summaryrefslogtreecommitdiff
path: root/stdwndclass_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'stdwndclass_windows.go')
-rw-r--r--stdwndclass_windows.go47
1 files changed, 46 insertions, 1 deletions
diff --git a/stdwndclass_windows.go b/stdwndclass_windows.go
index d57cc20..44af126 100644
--- a/stdwndclass_windows.go
+++ b/stdwndclass_windows.go
@@ -31,8 +31,53 @@ func defWindowProc(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRE
return _LRESULT(r1)
}
-func stdWndProc(s *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT {
+// don't worry about error returns from GetWindowLongPtr()/SetWindowLongPtr()
+// see comments of http://blogs.msdn.com/b/oldnewthing/archive/2014/02/03/10496248.aspx
+
+func getWindowLongPtr(hwnd _HWND, what uintptr) uintptr {
+ r1, _, _ := _getWindowLongPtr.Call(
+ uintptr(hwnd),
+ what)
+ return r1
+}
+
+func setWindowLongPtr(hwnd _HWND, what uintptr, value uintptr) {
+ _setWindowLongPtr.Call(
+ uintptr(hwnd),
+ what,
+ value)
+}
+
+// we can store a pointer in extra space provided by Windows
+// we'll store sysData there
+// see http://blogs.msdn.com/b/oldnewthing/archive/2005/03/03/384285.aspx
+func getSysData(hwnd _HWND) *sysData {
+ return (*sysData)(unsafe.Pointer(getWindowLongPtr(hwnd, negConst(_GWLP_USERDATA))))
+}
+
+func storeSysData(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT {
+ // we can get the lpParam from CreateWindowEx() in WM_NCCREATE and WM_CREATE
+ // we can freely skip any messages that come prior
+ // see http://blogs.msdn.com/b/oldnewthing/archive/2005/04/22/410773.aspx and http://blogs.msdn.com/b/oldnewthing/archive/2014/02/03/10496248.aspx (note the date on the latter one!)
+ if uMsg == _WM_NCCREATE {
+ // the lpParam to CreateWindowEx() is the first uintptr of the CREATESTRUCT
+ // so rather than create that whole structure, we'll just grab the uintptr at the address pointed to by lParam
+ cs := (*uintptr)(unsafe.Pointer(lParam))
+ saddr := *cs
+ setWindowLongPtr(hwnd, negConst(_GWLP_USERDATA), saddr)
+ // don't set s; we return here
+ }
+ // TODO is this correct for WM_NCCREATE? I think the above link does it but I'm not entirely sure...
+ return defWindowProc(hwnd, uMsg, wParam, lParam)
+}
+
+func stdWndProc(unused *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT {
return func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT {
+ s := getSysData(hwnd)
+ if s == nil { // not yet saved
+ return storeSysData(hwnd, uMsg, wParam, lParam)
+ }
+
switch uMsg {
case _WM_COMMAND:
id := _HMENU(wParam.LOWORD())