From af1c5304426a1f22eeffe4d7f36e9b7a0136a2b3 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 18 Jul 2022 18:22:46 +1000 Subject: [PATCH] Remove usage of unsafe.Pointer in winc (#1556) * Remove usage of unsafe.Pointer * [windows] Remove MakeIntResource and add overloads for Load functions * Fix `EnumProc` race condition. * Refactor `EnumDisplayMonitors` to use `unsafe.Pointer` instead of `uintptr` Co-authored-by: stffabi --- .../frontend/desktop/windows/screen.go | 6 ++---- .../frontend/desktop/windows/winc/icon.go | 2 +- .../desktop/windows/winc/imageviewbox.go | 2 +- .../frontend/desktop/windows/winc/resizer.go | 12 +++++------ .../frontend/desktop/windows/winc/utils.go | 4 ++-- .../desktop/windows/winc/w32/user32.go | 21 ++++++++++++++++--- .../desktop/windows/winc/w32/utils.go | 4 ---- 7 files changed, 30 insertions(+), 21 deletions(-) diff --git a/v2/internal/frontend/desktop/windows/screen.go b/v2/internal/frontend/desktop/windows/screen.go index 473519e40..e9e9cd603 100644 --- a/v2/internal/frontend/desktop/windows/screen.go +++ b/v2/internal/frontend/desktop/windows/screen.go @@ -39,7 +39,7 @@ func GetMonitorInfo(hMonitor w32.HMONITOR) (*w32.MONITORINFO, error) { return &info, nil } -func EnumProc(hMonitor w32.HMONITOR, hdcMonitor w32.HDC, lprcMonitor *w32.RECT, dwData w32.LPARAM) uintptr { +func EnumProc(hMonitor w32.HMONITOR, hdcMonitor w32.HDC, lprcMonitor *w32.RECT, screenContainer *ScreenContainer) uintptr { // adapted from https://stackoverflow.com/a/23492886/4188138 // see docs for the following pages to better understand this function @@ -49,8 +49,6 @@ func EnumProc(hMonitor w32.HMONITOR, hdcMonitor w32.HDC, lprcMonitor *w32.RECT, // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-monitorfromwindow ourMonitorData := Screen{} - screenContainer := (*ScreenContainer)(unsafe.Pointer(dwData)) - currentMonHndl := w32.MonitorFromWindow(screenContainer.mainWinHandle, w32.MONITOR_DEFAULTTONEAREST) currentMonInfo, currErr := GetMonitorInfo(currentMonHndl) @@ -99,7 +97,7 @@ func GetAllScreens(mainWinHandle w32.HWND) ([]Screen, error) { dc := w32.GetDC(0) defer w32.ReleaseDC(0, dc) - succeeded := w32.EnumDisplayMonitors(dc, nil, syscall.NewCallback(EnumProc), uintptr(unsafe.Pointer(&monitorContainer))) + succeeded := w32.EnumDisplayMonitors(dc, nil, syscall.NewCallback(EnumProc), unsafe.Pointer(&monitorContainer)) if !succeeded { return monitorContainer.monitors, errors.New("Windows call to EnumDisplayMonitors failed") } diff --git a/v2/internal/frontend/desktop/windows/winc/icon.go b/v2/internal/frontend/desktop/windows/winc/icon.go index 97bc79b2c..b19d59471 100644 --- a/v2/internal/frontend/desktop/windows/winc/icon.go +++ b/v2/internal/frontend/desktop/windows/winc/icon.go @@ -29,7 +29,7 @@ func NewIconFromFile(path string) (*Icon, error) { func NewIconFromResource(instance w32.HINSTANCE, resId uint16) (*Icon, error) { ico := new(Icon) var err error - if ico.handle = w32.LoadIcon(instance, w32.MakeIntResource(resId)); ico.handle == 0 { + if ico.handle = w32.LoadIconWithResourceID(instance, resId); ico.handle == 0 { err = errors.New(fmt.Sprintf("Cannot load icon from resource with id %v", resId)) } return ico, err diff --git a/v2/internal/frontend/desktop/windows/winc/imageviewbox.go b/v2/internal/frontend/desktop/windows/winc/imageviewbox.go index be97a4435..978a5098f 100644 --- a/v2/internal/frontend/desktop/windows/winc/imageviewbox.go +++ b/v2/internal/frontend/desktop/windows/winc/imageviewbox.go @@ -292,7 +292,7 @@ func (iv *ImageViewBox) WndProc(msg uint32, wparam, lparam uintptr) uintptr { } else { if !iv.add { - w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(iv.getCursor(x, y)))) + w32.SetCursor(w32.LoadCursorWithResourceID(0, iv.getCursor(x, y))) } // do not call repaint if underMouse item did not change. if iv.updateHighlight(x, y) { diff --git a/v2/internal/frontend/desktop/windows/winc/resizer.go b/v2/internal/frontend/desktop/windows/winc/resizer.go index 9c0ac1f78..61789a8bd 100644 --- a/v2/internal/frontend/desktop/windows/winc/resizer.go +++ b/v2/internal/frontend/desktop/windows/winc/resizer.go @@ -50,7 +50,7 @@ func (sp *VResizer) SetControl(control1, control2 Dockable, dir Direction, minSi if sp.drag { x := e.Data.(*MouseEventData).X sp.update(x) - w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_SIZEWE))) + w32.SetCursor(w32.LoadCursorWithResourceID(0, w32.IDC_SIZEWE)) } fmt.Println("control1.OnMouseMove") @@ -60,7 +60,7 @@ func (sp *VResizer) SetControl(control1, control2 Dockable, dir Direction, minSi if sp.drag { x := e.Data.(*MouseEventData).X sp.update(x) - w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_SIZEWE))) + w32.SetCursor(w32.LoadCursorWithResourceID(0, w32.IDC_SIZEWE)) } fmt.Println("control2.OnMouseMove") @@ -95,7 +95,7 @@ func (sp *VResizer) update(x int) { fm := sp.parent.(*Form) fm.UpdateLayout() - w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_ARROW))) + w32.SetCursor(w32.LoadCursorWithResourceID(0, w32.IDC_ARROW)) } func (sp *VResizer) WndProc(msg uint32, wparam, lparam uintptr) uintptr { @@ -108,7 +108,7 @@ func (sp *VResizer) WndProc(msg uint32, wparam, lparam uintptr) uintptr { x, _ := genPoint(lparam) sp.update(x) } else { - w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_SIZEWE))) + w32.SetCursor(w32.LoadCursorWithResourceID(0, w32.IDC_SIZEWE)) } if sp.mouseLeft { @@ -179,7 +179,7 @@ func (sp *HResizer) update(y int) { fm := sp.parent.(*Form) fm.UpdateLayout() - w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_ARROW))) + w32.SetCursor(w32.LoadCursorWithResourceID(0, w32.IDC_ARROW)) } func (sp *HResizer) WndProc(msg uint32, wparam, lparam uintptr) uintptr { @@ -192,7 +192,7 @@ func (sp *HResizer) WndProc(msg uint32, wparam, lparam uintptr) uintptr { _, y := genPoint(lparam) sp.update(y) } else { - w32.SetCursor(w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_SIZENS))) + w32.SetCursor(w32.LoadCursorWithResourceID(0, w32.IDC_SIZENS)) } if sp.mouseLeft { diff --git a/v2/internal/frontend/desktop/windows/winc/utils.go b/v2/internal/frontend/desktop/windows/winc/utils.go index aa4304a1c..527e85903 100644 --- a/v2/internal/frontend/desktop/windows/winc/utils.go +++ b/v2/internal/frontend/desktop/windows/winc/utils.go @@ -78,7 +78,7 @@ func CreateWindow(className string, parent Controller, exStyle, style uint) w32. func RegisterClass(className string, wndproc uintptr) { instance := GetAppInstance() - icon := w32.LoadIcon(instance, w32.MakeIntResource(w32.IDI_APPLICATION)) + icon := w32.LoadIconWithResourceID(instance, w32.IDI_APPLICATION) var wc w32.WNDCLASSEX wc.Size = uint32(unsafe.Sizeof(wc)) @@ -87,7 +87,7 @@ func RegisterClass(className string, wndproc uintptr) { wc.Instance = instance wc.Background = w32.COLOR_BTNFACE + 1 wc.Icon = icon - wc.Cursor = w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_ARROW)) + wc.Cursor = w32.LoadCursorWithResourceID(0, w32.IDC_ARROW) wc.ClassName = syscall.StringToUTF16Ptr(className) wc.MenuName = nil wc.IconSm = icon diff --git a/v2/internal/frontend/desktop/windows/winc/w32/user32.go b/v2/internal/frontend/desktop/windows/winc/w32/user32.go index a6a744d19..c68b7cde7 100644 --- a/v2/internal/frontend/desktop/windows/winc/w32/user32.go +++ b/v2/internal/frontend/desktop/windows/winc/w32/user32.go @@ -179,13 +179,28 @@ func LoadIcon(instance HINSTANCE, iconName *uint16) HICON { return HICON(ret) } +func LoadIconWithResourceID(instance HINSTANCE, res uint16) HICON { + ret, _, _ := procLoadIcon.Call( + uintptr(instance), + uintptr(res)) + + return HICON(ret) +} + func LoadCursor(instance HINSTANCE, cursorName *uint16) HCURSOR { ret, _, _ := procLoadCursor.Call( uintptr(instance), uintptr(unsafe.Pointer(cursorName))) return HCURSOR(ret) +} +func LoadCursorWithResourceID(instance HINSTANCE, res uint16) HCURSOR { + ret, _, _ := procLoadCursor.Call( + uintptr(instance), + uintptr(res)) + + return HCURSOR(ret) } func ShowWindow(hwnd HWND, cmdshow int) bool { @@ -1115,12 +1130,12 @@ func GetMonitorInfo(hMonitor HMONITOR, lmpi *MONITORINFO) bool { return ret != 0 } -func EnumDisplayMonitors(hdc HDC, clip *RECT, fnEnum, dwData uintptr) bool { +func EnumDisplayMonitors(hdc HDC, clip *RECT, fnEnum uintptr, dwData unsafe.Pointer) bool { ret, _, _ := procEnumDisplayMonitors.Call( - uintptr(hdc), + hdc, uintptr(unsafe.Pointer(clip)), fnEnum, - dwData, + uintptr(dwData), ) return ret != 0 } diff --git a/v2/internal/frontend/desktop/windows/winc/w32/utils.go b/v2/internal/frontend/desktop/windows/winc/w32/utils.go index cb8d354d0..718d88cbb 100644 --- a/v2/internal/frontend/desktop/windows/winc/w32/utils.go +++ b/v2/internal/frontend/desktop/windows/winc/w32/utils.go @@ -37,10 +37,6 @@ func FAILED(hr HRESULT) bool { return hr < 0 } -func MakeIntResource(id uint16) *uint16 { - return (*uint16)(unsafe.Pointer(uintptr(id))) -} - func LOWORD(dw uint32) uint16 { return uint16(dw) }