summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-05-30 17:59:29 -0400
committerPietro Gagliardi <[email protected]>2014-05-30 17:59:29 -0400
commit4a66f1467bf0ee9a69c0758a53ab6f1425da166d (patch)
treef11a897c449cc7634c229e00db0d41a37ba8808d
parentc543f5639b121bcdae11f681466c030394902f65 (diff)
Moved the standard window class (for Window) on Windows to get the sysData pointer from CreateWindowEx() and store it in the window memory instead of being given it via a closure. This will lead to having only one window class for all Windows, which will come next. Also fixed an error in windowsconstgen's output related to GetWindowLongPtr()/SetWindowLongPtr().
-rw-r--r--stdwndclass_windows.go47
-rw-r--r--sysdata_windows.go8
-rw-r--r--tools/windowsconstgen.go4
-rw-r--r--zconstants_windows_386.go6
-rw-r--r--zconstants_windows_amd64.go6
5 files changed, 63 insertions, 8 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())
diff --git a/sysdata_windows.go b/sysdata_windows.go
index b9df277..f813de3 100644
--- a/sysdata_windows.go
+++ b/sysdata_windows.go
@@ -30,6 +30,7 @@ type classData struct {
xstyle uint32
mkid bool
altStyle uint32
+ storeSysData bool
doNotLoadFont bool
appendMsg uintptr
insertBeforeMsg uintptr
@@ -48,6 +49,7 @@ var classTypes = [nctypes]*classData{
register: registerStdWndClass,
style: _WS_OVERLAPPEDWINDOW,
xstyle: 0,
+ storeSysData: true,
doNotLoadFont: true,
},
c_button: &classData{
@@ -157,6 +159,10 @@ func (s *sysData) make(window *sysData) (err error) {
if s.alternate {
style = uintptr(ct.altStyle)
}
+ lpParam := uintptr(_NULL)
+ if ct.storeSysData {
+ lpParam = uintptr(unsafe.Pointer(s))
+ }
uitask <- &uimsg{
call: _createWindowEx,
p: []uintptr{
@@ -171,7 +177,7 @@ func (s *sysData) make(window *sysData) (err error) {
pwin,
uintptr(cid),
uintptr(hInstance),
- uintptr(_NULL),
+ lpParam,
},
ret: ret,
}
diff --git a/tools/windowsconstgen.go b/tools/windowsconstgen.go
index 6be1b59..777324d 100644
--- a/tools/windowsconstgen.go
+++ b/tools/windowsconstgen.go
@@ -110,8 +110,8 @@ func preamble(pkg string) string {
// for backwards compatibiilty reasons, Windows defines GetWindowLongPtr()/SetWindowLongPtr() as a macro which expands to GetWindowLong()/SetWindowLong() on 32-bit systems
// we'll just simulate that here
var gwlpNames = map[string]string{
- "386": "etWindowLong",
- "amd64": "etWindowLongPtr",
+ "386": "etWindowLongW",
+ "amd64": "etWindowLongPtrW",
}
func printConst(f *os.File, goconst string, winconst string) {
diff --git a/zconstants_windows_386.go b/zconstants_windows_386.go
index c1d88c2..fa0ab76 100644
--- a/zconstants_windows_386.go
+++ b/zconstants_windows_386.go
@@ -28,6 +28,7 @@ const _ERROR = 0
const _ES_AUTOHSCROLL = 128
const _ES_PASSWORD = 32
const _FALSE = 0
+const _GWLP_USERDATA = -21
const _GWL_STYLE = -16
const _ICC_PROGRESS_CLASS = 32
const _LBS_EXTENDEDSEL = 2048
@@ -140,6 +141,7 @@ const _WM_MBUTTONDOWN = 519
const _WM_MBUTTONUP = 520
const _WM_MOUSEACTIVATE = 33
const _WM_MOUSEMOVE = 512
+const _WM_NCCREATE = 129
const _WM_PAINT = 15
const _WM_RBUTTONDOWN = 516
const _WM_RBUTTONUP = 517
@@ -162,5 +164,5 @@ const _IDC_ARROW = 32512
const _IDI_APPLICATION = 32512
const _INVALID_HANDLE_VALUE = 4294967295
const _NULL = 0
-var _getWindowLongPtr = user32.NewProc("GetWindowLong")
-var _setWindowLongPtr = user32.NewProc("SetWindowLong")
+var _getWindowLongPtr = user32.NewProc("GetWindowLongW")
+var _setWindowLongPtr = user32.NewProc("SetWindowLongW")
diff --git a/zconstants_windows_amd64.go b/zconstants_windows_amd64.go
index 4d3c1c3..54bbae8 100644
--- a/zconstants_windows_amd64.go
+++ b/zconstants_windows_amd64.go
@@ -28,6 +28,7 @@ const _ERROR = 0
const _ES_AUTOHSCROLL = 128
const _ES_PASSWORD = 32
const _FALSE = 0
+const _GWLP_USERDATA = -21
const _GWL_STYLE = -16
const _ICC_PROGRESS_CLASS = 32
const _LBS_EXTENDEDSEL = 2048
@@ -140,6 +141,7 @@ const _WM_MBUTTONDOWN = 519
const _WM_MBUTTONUP = 520
const _WM_MOUSEACTIVATE = 33
const _WM_MOUSEMOVE = 512
+const _WM_NCCREATE = 129
const _WM_PAINT = 15
const _WM_RBUTTONDOWN = 516
const _WM_RBUTTONUP = 517
@@ -162,5 +164,5 @@ const _IDC_ARROW = 32512
const _IDI_APPLICATION = 32512
const _INVALID_HANDLE_VALUE = 18446744073709551615
const _NULL = 0
-var _getWindowLongPtr = user32.NewProc("GetWindowLongPtr")
-var _setWindowLongPtr = user32.NewProc("SetWindowLongPtr")
+var _getWindowLongPtr = user32.NewProc("GetWindowLongPtrW")
+var _setWindowLongPtr = user32.NewProc("SetWindowLongPtrW")