[windows] Support AlwaysOnTop, EnableResize at runtime. Added Solid/Transparent/Translucent options.

This commit is contained in:
Lea Anthony
2023-05-30 16:31:47 +08:00
committed by Misite Bao
parent 4a60dfc373
commit 7c63cee9e8
41 changed files with 5679 additions and 8207 deletions
+22
View File
@@ -180,3 +180,25 @@ const MyEnum = {
- Why use `float64`? Can't we use `int`?
- Because JavaScript doesn't have a concept of `int`. Everything is a `number`, which translates to `float64` in Go. There are also restrictions on casting types in Go's reflection package, which means using `int` doesn't work.
### BackgroundColour
In v2, this was a pointer to an `RGBA` struct. In v3, this is an `RGBA` struct value.
### WindowIsTranslucent
This flag has been removed. Now there is a `BackgroundType` flag that can be used to set the type of background the window should have.
This flag can be set to any of the following values:
- `BackgroundTypeSolid` - The window will have a solid background
- `BackgroundTypeTransparent` - The window will have a transparent background
- `BackgroundTypeTranslucent` - The window will have a translucent background
On Windows, if the `BackgroundType` is set to `BackgroundTypeTranslucent`, the type of translucency can be set using the
`BackdropType` flag in the `WindowsWindow` options. This can be set to any of the following values:
- `Auto` - The window will use an effect determined by the system
- `None` - The window will have no background
- `Mica` - The window will use the Mica effect
- `Acrylic` - The window will use the acrylic effect
- `Tabbed` - The window will use the tabbed effect
+1 -2
View File
@@ -4,7 +4,6 @@ go 1.19
require (
github.com/go-task/task/v3 v3.20.0
github.com/gonutz/w32/v2 v2.7.0
github.com/google/go-cmp v0.5.9
github.com/jackmordaunt/icns/v2 v2.2.1
github.com/json-iterator/go v1.1.12
@@ -18,6 +17,7 @@ require (
github.com/samber/lo v1.37.0
github.com/tc-hib/winres v0.1.6
github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6
golang.org/x/sys v0.7.0
modernc.org/sqlite v1.21.0
)
@@ -54,7 +54,6 @@ require (
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/term v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/tools v0.1.12 // indirect
+2 -4
View File
@@ -27,8 +27,6 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8Wd
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-task/task/v3 v3.20.0 h1:pTavuhP+AiEpKLzh5I6Lja9Ux7ypYO5QMsEPTbhYEDc=
github.com/go-task/task/v3 v3.20.0/go.mod h1:y7rWakbLR5gFElGgo6rA2dyr6vU/zNIDVfn3S4Of6OI=
github.com/gonutz/w32/v2 v2.7.0 h1:O9lx/5tZ+WjZdxdvQFTh+/kP/7y95YCaL5MHqPrIHn4=
github.com/gonutz/w32/v2 v2.7.0/go.mod h1:MgtHx0AScDVNKyB+kjyPder4xIi3XAcHS6LDDU2DmdE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -184,8 +182,8 @@ golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-48
View File
@@ -1,48 +0,0 @@
The MIT License (MIT)
Copyright (c) 2021 gonutz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
This is the license from the original fork that this library is based on:
Copyright (c) 2010-2012 The w32 Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-20
View File
@@ -1,20 +0,0 @@
This is a fork of [gonutz/w32](https://github.com/gonutz/w32).
-----------------------
About w32
==========
w32 is a wrapper for a number of Windows APIs for the [Go Programming Language](https://golang.org/).
This library has no other dependencies and you need no C-compiler, it is written in pure Go. Some function signatures have been adapted to make them work in Go, e.g. functions that take a pointer to an array and a count of items in C will now simply accept a slice in Go.
If you miss any Windows API functions, just write an issue or create a pull request, the Win32 API is very large and has many rarely used functions in it so this wrapper is supposed to grow as needed by the Go community.
Installation
============
Get the latest version with:
go get github.com/gonutz/w32/v2
+143
View File
@@ -0,0 +1,143 @@
//go:build windows
/*
* Based on code originally from https://github.com/atotto/clipboard. Copyright (c) 2013 Ato Araki. All rights reserved.
*/
package w32
import (
"runtime"
"syscall"
"time"
"unsafe"
)
const (
cfUnicodetext = 13
gmemMoveable = 0x0002
)
// waitOpenClipboard opens the clipboard, waiting for up to a second to do so.
func waitOpenClipboard() error {
started := time.Now()
limit := started.Add(time.Second)
var r uintptr
var err error
for time.Now().Before(limit) {
r, _, err = procOpenClipboard.Call(0)
if r != 0 {
return nil
}
time.Sleep(time.Millisecond)
}
return err
}
func GetClipboardText() (string, error) {
// LockOSThread ensure that the whole method will keep executing on the same thread from begin to end (it actually locks the goroutine thread attribution).
// Otherwise if the goroutine switch thread during execution (which is a common practice), the OpenClipboard and CloseClipboard will happen on two different threads, and it will result in a clipboard deadlock.
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if formatAvailable, _, err := procIsClipboardFormatAvailable.Call(cfUnicodetext); formatAvailable == 0 {
return "", err
}
err := waitOpenClipboard()
if err != nil {
return "", err
}
h, _, err := procGetClipboardData.Call(cfUnicodetext)
if h == 0 {
_, _, _ = procCloseClipboard.Call()
return "", err
}
l, _, err := kernelGlobalLock.Call(h)
if l == 0 {
_, _, _ = procCloseClipboard.Call()
return "", err
}
text := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(l))[:])
r, _, err := kernelGlobalUnlock.Call(h)
if r == 0 {
_, _, _ = procCloseClipboard.Call()
return "", err
}
closed, _, err := procCloseClipboard.Call()
if closed == 0 {
return "", err
}
return text, nil
}
func SetClipboardText(text string) error {
// LockOSThread ensure that the whole method will keep executing on the same thread from begin to end (it actually locks the goroutine thread attribution).
// Otherwise if the goroutine switch thread during execution (which is a common practice), the OpenClipboard and CloseClipboard will happen on two different threads, and it will result in a clipboard deadlock.
runtime.LockOSThread()
defer runtime.UnlockOSThread()
err := waitOpenClipboard()
if err != nil {
return err
}
r, _, err := procEmptyClipboard.Call(0)
if r == 0 {
_, _, _ = procCloseClipboard.Call()
return err
}
data, err := syscall.UTF16FromString(text)
if err != nil {
return err
}
// "If the hMem parameter identifies a memory object, the object must have
// been allocated using the function with the GMEM_MOVEABLE flag."
h, _, err := kernelGlobalAlloc.Call(gmemMoveable, uintptr(len(data)*int(unsafe.Sizeof(data[0]))))
if h == 0 {
_, _, _ = procCloseClipboard.Call()
return err
}
defer func() {
if h != 0 {
kernelGlobalFree.Call(h)
}
}()
l, _, err := kernelGlobalLock.Call(h)
if l == 0 {
_, _, _ = procCloseClipboard.Call()
return err
}
r, _, err = kernelLstrcpy.Call(l, uintptr(unsafe.Pointer(&data[0])))
if r == 0 {
_, _, _ = procCloseClipboard.Call()
return err
}
r, _, err = kernelGlobalUnlock.Call(h)
if r == 0 {
if err.(syscall.Errno) != 0 {
_, _, _ = procCloseClipboard.Call()
return err
}
}
r, _, err = procSetClipboardData.Call(cfUnicodetext, h)
if r == 0 {
_, _, _ = procCloseClipboard.Call()
return err
}
h = 0 // suppress deferred cleanup
closed, _, err := procCloseClipboard.Call()
if closed == 0 {
return err
}
return nil
}
+112
View File
@@ -0,0 +1,112 @@
//go:build windows
/*
* Copyright (C) 2019 The Winc Authors. All Rights Reserved.
* Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved.
*/
package w32
import (
"syscall"
"unsafe"
)
var (
modcomctl32 = syscall.NewLazyDLL("comctl32.dll")
procInitCommonControlsEx = modcomctl32.NewProc("InitCommonControlsEx")
procImageList_Create = modcomctl32.NewProc("ImageList_Create")
procImageList_Destroy = modcomctl32.NewProc("ImageList_Destroy")
procImageList_GetImageCount = modcomctl32.NewProc("ImageList_GetImageCount")
procImageList_SetImageCount = modcomctl32.NewProc("ImageList_SetImageCount")
procImageList_Add = modcomctl32.NewProc("ImageList_Add")
procImageList_ReplaceIcon = modcomctl32.NewProc("ImageList_ReplaceIcon")
procImageList_Remove = modcomctl32.NewProc("ImageList_Remove")
procTrackMouseEvent = modcomctl32.NewProc("_TrackMouseEvent")
)
func InitCommonControlsEx(lpInitCtrls *INITCOMMONCONTROLSEX) bool {
ret, _, _ := procInitCommonControlsEx.Call(
uintptr(unsafe.Pointer(lpInitCtrls)))
return ret != 0
}
func ImageList_Create(cx, cy int, flags uint, cInitial, cGrow int) HIMAGELIST {
ret, _, _ := procImageList_Create.Call(
uintptr(cx),
uintptr(cy),
uintptr(flags),
uintptr(cInitial),
uintptr(cGrow))
if ret == 0 {
panic("Create image list failed")
}
return HIMAGELIST(ret)
}
func ImageList_Destroy(himl HIMAGELIST) bool {
ret, _, _ := procImageList_Destroy.Call(
uintptr(himl))
return ret != 0
}
func ImageList_GetImageCount(himl HIMAGELIST) int {
ret, _, _ := procImageList_GetImageCount.Call(
uintptr(himl))
return int(ret)
}
func ImageList_SetImageCount(himl HIMAGELIST, uNewCount uint) bool {
ret, _, _ := procImageList_SetImageCount.Call(
uintptr(himl),
uintptr(uNewCount))
return ret != 0
}
func ImageList_Add(himl HIMAGELIST, hbmImage, hbmMask HBITMAP) int {
ret, _, _ := procImageList_Add.Call(
uintptr(himl),
uintptr(hbmImage),
uintptr(hbmMask))
return int(ret)
}
func ImageList_ReplaceIcon(himl HIMAGELIST, i int, hicon HICON) int {
ret, _, _ := procImageList_ReplaceIcon.Call(
uintptr(himl),
uintptr(i),
uintptr(hicon))
return int(ret)
}
func ImageList_AddIcon(himl HIMAGELIST, hicon HICON) int {
return ImageList_ReplaceIcon(himl, -1, hicon)
}
func ImageList_Remove(himl HIMAGELIST, i int) bool {
ret, _, _ := procImageList_Remove.Call(
uintptr(himl),
uintptr(i))
return ret != 0
}
func ImageList_RemoveAll(himl HIMAGELIST) bool {
return ImageList_Remove(himl, -1)
}
func TrackMouseEvent(tme *TRACKMOUSEEVENT) bool {
ret, _, _ := procTrackMouseEvent.Call(
uintptr(unsafe.Pointer(tme)))
return ret != 0
}
+40
View File
@@ -0,0 +1,40 @@
//go:build windows
/*
* Copyright (C) 2019 The Winc Authors. All Rights Reserved.
* Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved.
*/
package w32
import (
"syscall"
"unsafe"
)
var (
modcomdlg32 = syscall.NewLazyDLL("comdlg32.dll")
procGetSaveFileName = modcomdlg32.NewProc("GetSaveFileNameW")
procGetOpenFileName = modcomdlg32.NewProc("GetOpenFileNameW")
procCommDlgExtendedError = modcomdlg32.NewProc("CommDlgExtendedError")
)
func GetOpenFileName(ofn *OPENFILENAME) bool {
ret, _, _ := procGetOpenFileName.Call(
uintptr(unsafe.Pointer(ofn)))
return ret != 0
}
func GetSaveFileName(ofn *OPENFILENAME) bool {
ret, _, _ := procGetSaveFileName.Call(
uintptr(unsafe.Pointer(ofn)))
return ret != 0
}
func CommDlgExtendedError() uint {
ret, _, _ := procCommDlgExtendedError.Call()
return uint(ret)
}
+1118 -2453
View File
File diff suppressed because it is too large Load Diff
+83
View File
@@ -0,0 +1,83 @@
//go:build windows
package w32
import (
"golang.org/x/sys/windows/registry"
"strconv"
"syscall"
)
var (
modwingdi = syscall.NewLazyDLL("gdi32.dll")
procCreateSolidBrush = modwingdi.NewProc("CreateSolidBrush")
)
var (
kernel32 = syscall.NewLazyDLL("kernel32")
kernelGlobalAlloc = kernel32.NewProc("GlobalAlloc")
kernelGlobalFree = kernel32.NewProc("GlobalFree")
kernelGlobalLock = kernel32.NewProc("GlobalLock")
kernelGlobalUnlock = kernel32.NewProc("GlobalUnlock")
kernelLstrcpy = kernel32.NewProc("lstrcpyW")
)
var windowsVersion, _ = getWindowsVersionInfo()
func IsWindowsVersionAtLeast(major, minor, buildNumber int) bool {
return windowsVersion.Major >= major &&
windowsVersion.Minor >= minor &&
windowsVersion.Build >= buildNumber
}
type WindowsVersionInfo struct {
Major int
Minor int
Build int
DisplayVersion string
}
func (w *WindowsVersionInfo) IsWindowsVersionAtLeast(major, minor, buildNumber int) bool {
return w.Major >= major && w.Minor >= minor && w.Build >= buildNumber
}
func getWindowsVersionInfo() (*WindowsVersionInfo, error) {
key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
if err != nil {
return nil, err
}
return &WindowsVersionInfo{
Major: regDWORDKeyAsInt(key, "CurrentMajorVersionNumber"),
Minor: regDWORDKeyAsInt(key, "CurrentMinorVersionNumber"),
Build: regStringKeyAsInt(key, "CurrentBuildNumber"),
DisplayVersion: regKeyAsString(key, "DisplayVersion"),
}, nil
}
func regDWORDKeyAsInt(key registry.Key, name string) int {
result, _, err := key.GetIntegerValue(name)
if err != nil {
return -1
}
return int(result)
}
func regStringKeyAsInt(key registry.Key, name string) int {
resultStr, _, err := key.GetStringValue(name)
if err != nil {
return -1
}
result, err := strconv.Atoi(resultStr)
if err != nil {
return -1
}
return result
}
func regKeyAsString(key registry.Key, name string) string {
resultStr, _, err := key.GetStringValue(name)
if err != nil {
return ""
}
return resultStr
}
+36
View File
@@ -0,0 +1,36 @@
//go:build windows
package w32
import (
"syscall"
"unsafe"
)
var (
moddwmapi = syscall.NewLazyDLL("dwmapi.dll")
procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute")
procDwmExtendFrameIntoClientArea = moddwmapi.NewProc("DwmExtendFrameIntoClientArea")
)
func DwmSetWindowAttribute(hwnd HWND, dwAttribute DWMWINDOWATTRIBUTE, pvAttribute LPCVOID, cbAttribute uint32) HRESULT {
ret, _, _ := procDwmSetWindowAttribute.Call(
hwnd,
uintptr(dwAttribute),
uintptr(pvAttribute),
uintptr(cbAttribute))
return HRESULT(ret)
}
func dwmExtendFrameIntoClientArea(hwnd uintptr, margins *MARGINS) error {
ret, _, _ := procDwmExtendFrameIntoClientArea.Call(
hwnd,
uintptr(unsafe.Pointer(margins)))
if ret != 0 {
return syscall.GetLastError()
}
return nil
}
File diff suppressed because it is too large Load Diff
-29
View File
@@ -1,29 +0,0 @@
package w32
// MenuItemFromPoint determines which menu item, if any, is at the specified
// location.
func MenuItemFromPoint(w HWND, m HMENU, screen POINT) int {
ret, _, _ := menuItemFromPoint.Call(
uintptr(w),
uintptr(m),
uintptr(screen.X),
uintptr(screen.Y),
)
return int(ret)
}
func GetClassLongPtr(w HWND, index int) uintptr {
return uintptr(GetClassLong(w, index))
}
func SetClassLongPtr(w HWND, index int, value uintptr) uintptr {
return uintptr(SetClassLong(w, index, int32(value)))
}
func GetWindowLongPtr(hwnd HWND, index int) uintptr {
return uintptr(GetWindowLong(hwnd, index))
}
func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr {
return uintptr(SetWindowLong(hwnd, index, int32(value)))
}
-43
View File
@@ -1,43 +0,0 @@
package w32
// MenuItemFromPoint determines which menu item, if any, is at the specified
// location.
func MenuItemFromPoint(w HWND, m HMENU, screen POINT) int {
ret, _, _ := menuItemFromPoint.Call(
uintptr(w),
uintptr(m),
uintptr(uint64(screen.X)<<32|uint64(screen.Y)),
)
return int(ret)
}
func GetClassLongPtr(w HWND, index int) uintptr {
ret, _, _ := getClassLongPtr.Call(uintptr(w), uintptr(index))
return ret
}
func SetClassLongPtr(w HWND, index int, value uintptr) uintptr {
ret, _, _ := setClassLongPtr.Call(
uintptr(w),
uintptr(index),
value,
)
return ret
}
func GetWindowLongPtr(hwnd HWND, index int) uintptr {
ret, _, _ := getWindowLongPtr.Call(
uintptr(hwnd),
uintptr(index),
)
return ret
}
func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr {
ret, _, _ := setWindowLongPtr.Call(
uintptr(hwnd),
uintptr(index),
value,
)
return ret
}
-43
View File
@@ -1,43 +0,0 @@
package w32
// MenuItemFromPoint determines which menu item, if any, is at the specified
// location.
func MenuItemFromPoint(w HWND, m HMENU, screen POINT) int {
ret, _, _ := menuItemFromPoint.Call(
uintptr(w),
uintptr(m),
uintptr(uint64(screen.X)<<32|uint64(screen.Y)),
)
return int(ret)
}
func GetClassLongPtr(w HWND, index int) uintptr {
ret, _, _ := getClassLongPtr.Call(uintptr(w), uintptr(index))
return ret
}
func SetClassLongPtr(w HWND, index int, value uintptr) uintptr {
ret, _, _ := setClassLongPtr.Call(
uintptr(w),
uintptr(index),
value,
)
return ret
}
func GetWindowLongPtr(hwnd HWND, index int) uintptr {
ret, _, _ := getWindowLongPtr.Call(
uintptr(hwnd),
uintptr(index),
)
return ret
}
func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr {
ret, _, _ := setWindowLongPtr.Call(
uintptr(hwnd),
uintptr(index),
value,
)
return ret
}
File diff suppressed because it is too large Load Diff
+177
View File
@@ -0,0 +1,177 @@
//go:build windows
/*
* Copyright (C) 2019 The Winc Authors. All Rights Reserved.
* Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved.
*/
package w32
import (
"errors"
"fmt"
"syscall"
"unsafe"
)
const (
Ok = 0
GenericError = 1
InvalidParameter = 2
OutOfMemory = 3
ObjectBusy = 4
InsufficientBuffer = 5
NotImplemented = 6
Win32Error = 7
WrongState = 8
Aborted = 9
FileNotFound = 10
ValueOverflow = 11
AccessDenied = 12
UnknownImageFormat = 13
FontFamilyNotFound = 14
FontStyleNotFound = 15
NotTrueTypeFont = 16
UnsupportedGdiplusVersion = 17
GdiplusNotInitialized = 18
PropertyNotFound = 19
PropertyNotSupported = 20
ProfileNotFound = 21
)
func GetGpStatus(s int32) string {
switch s {
case Ok:
return "Ok"
case GenericError:
return "GenericError"
case InvalidParameter:
return "InvalidParameter"
case OutOfMemory:
return "OutOfMemory"
case ObjectBusy:
return "ObjectBusy"
case InsufficientBuffer:
return "InsufficientBuffer"
case NotImplemented:
return "NotImplemented"
case Win32Error:
return "Win32Error"
case WrongState:
return "WrongState"
case Aborted:
return "Aborted"
case FileNotFound:
return "FileNotFound"
case ValueOverflow:
return "ValueOverflow"
case AccessDenied:
return "AccessDenied"
case UnknownImageFormat:
return "UnknownImageFormat"
case FontFamilyNotFound:
return "FontFamilyNotFound"
case FontStyleNotFound:
return "FontStyleNotFound"
case NotTrueTypeFont:
return "NotTrueTypeFont"
case UnsupportedGdiplusVersion:
return "UnsupportedGdiplusVersion"
case GdiplusNotInitialized:
return "GdiplusNotInitialized"
case PropertyNotFound:
return "PropertyNotFound"
case PropertyNotSupported:
return "PropertyNotSupported"
case ProfileNotFound:
return "ProfileNotFound"
}
return "Unknown Status Value"
}
var (
token uintptr
modgdiplus = syscall.NewLazyDLL("gdiplus.dll")
procGdipCreateBitmapFromFile = modgdiplus.NewProc("GdipCreateBitmapFromFile")
procGdipCreateBitmapFromHBITMAP = modgdiplus.NewProc("GdipCreateBitmapFromHBITMAP")
procGdipCreateHBITMAPFromBitmap = modgdiplus.NewProc("GdipCreateHBITMAPFromBitmap")
procGdipCreateBitmapFromResource = modgdiplus.NewProc("GdipCreateBitmapFromResource")
procGdipCreateBitmapFromStream = modgdiplus.NewProc("GdipCreateBitmapFromStream")
procGdipDisposeImage = modgdiplus.NewProc("GdipDisposeImage")
procGdiplusShutdown = modgdiplus.NewProc("GdiplusShutdown")
procGdiplusStartup = modgdiplus.NewProc("GdiplusStartup")
)
func GdipCreateBitmapFromFile(filename string) (*uintptr, error) {
var bitmap *uintptr
ret, _, _ := procGdipCreateBitmapFromFile.Call(
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))),
uintptr(unsafe.Pointer(&bitmap)))
if ret != Ok {
return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromFile failed with status '%s' for file '%s'", GetGpStatus(int32(ret)), filename))
}
return bitmap, nil
}
func GdipCreateBitmapFromResource(instance HINSTANCE, resId *uint16) (*uintptr, error) {
var bitmap *uintptr
ret, _, _ := procGdipCreateBitmapFromResource.Call(
uintptr(instance),
uintptr(unsafe.Pointer(resId)),
uintptr(unsafe.Pointer(&bitmap)))
if ret != Ok {
return nil, errors.New(fmt.Sprintf("GdiCreateBitmapFromResource failed with status '%s'", GetGpStatus(int32(ret))))
}
return bitmap, nil
}
func GdipCreateBitmapFromStream(stream *IStream) (*uintptr, error) {
var bitmap *uintptr
ret, _, _ := procGdipCreateBitmapFromStream.Call(
uintptr(unsafe.Pointer(stream)),
uintptr(unsafe.Pointer(&bitmap)))
if ret != Ok {
return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromStream failed with status '%s'", GetGpStatus(int32(ret))))
}
return bitmap, nil
}
func GdipCreateHBITMAPFromBitmap(bitmap *uintptr, background uint32) (HBITMAP, error) {
var hbitmap HBITMAP
ret, _, _ := procGdipCreateHBITMAPFromBitmap.Call(
uintptr(unsafe.Pointer(bitmap)),
uintptr(unsafe.Pointer(&hbitmap)),
uintptr(background))
if ret != Ok {
return 0, errors.New(fmt.Sprintf("GdipCreateHBITMAPFromBitmap failed with status '%s'", GetGpStatus(int32(ret))))
}
return hbitmap, nil
}
func GdipDisposeImage(image *uintptr) {
procGdipDisposeImage.Call(uintptr(unsafe.Pointer(image)))
}
func GdiplusShutdown() {
procGdiplusShutdown.Call(token)
}
func GdiplusStartup(input *GdiplusStartupInput, output *GdiplusStartupOutput) {
ret, _, _ := procGdiplusStartup.Call(
uintptr(unsafe.Pointer(&token)),
uintptr(unsafe.Pointer(input)),
uintptr(unsafe.Pointer(output)))
if ret != Ok {
panic("GdiplusStartup failed with status " + GetGpStatus(int32(ret)))
}
}
+45
View File
@@ -0,0 +1,45 @@
//go:build windows
/*
* Copyright (C) 2019 The Winc Authors. All Rights Reserved.
* Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved.
*/
package w32
import (
"unsafe"
)
type pIDispatchVtbl struct {
pQueryInterface uintptr
pAddRef uintptr
pRelease uintptr
pGetTypeInfoCount uintptr
pGetTypeInfo uintptr
pGetIDsOfNames uintptr
pInvoke uintptr
}
type IDispatch struct {
lpVtbl *pIDispatchVtbl
}
func (this *IDispatch) QueryInterface(id *GUID) *IDispatch {
return ComQueryInterface((*IUnknown)(unsafe.Pointer(this)), id)
}
func (this *IDispatch) AddRef() int32 {
return ComAddRef((*IUnknown)(unsafe.Pointer(this)))
}
func (this *IDispatch) Release() int32 {
return ComRelease((*IUnknown)(unsafe.Pointer(this)))
}
func (this *IDispatch) GetIDsOfName(names []string) []int32 {
return ComGetIDsOfName(this, names)
}
func (this *IDispatch) Invoke(dispid int32, dispatch int16, params ...interface{}) *VARIANT {
return ComInvoke(this, dispid, dispatch, params...)
}
+33
View File
@@ -0,0 +1,33 @@
//go:build windows
/*
* Copyright (C) 2019 Tad Vizbaras. All Rights Reserved.
* Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved.
*/
package w32
import (
"unsafe"
)
type pIStreamVtbl struct {
pQueryInterface uintptr
pAddRef uintptr
pRelease uintptr
}
type IStream struct {
lpVtbl *pIStreamVtbl
}
func (this *IStream) QueryInterface(id *GUID) *IDispatch {
return ComQueryInterface((*IUnknown)(unsafe.Pointer(this)), id)
}
func (this *IStream) AddRef() int32 {
return ComAddRef((*IUnknown)(unsafe.Pointer(this)))
}
func (this *IStream) Release() int32 {
return ComRelease((*IUnknown)(unsafe.Pointer(this)))
}
+29
View File
@@ -0,0 +1,29 @@
//go:build windows
/*
* Copyright (C) 2019 Tad Vizbaras. All Rights Reserved.
* Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved.
*/
package w32
type pIUnknownVtbl struct {
pQueryInterface uintptr
pAddRef uintptr
pRelease uintptr
}
type IUnknown struct {
lpVtbl *pIUnknownVtbl
}
func (this *IUnknown) QueryInterface(id *GUID) *IDispatch {
return ComQueryInterface(this, id)
}
func (this *IUnknown) AddRef() int32 {
return ComAddRef(this)
}
func (this *IUnknown) Release() int32 {
return ComRelease(this)
}

Some files were not shown because too many files have changed in this diff Show More