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().

This commit is contained in:
Pietro Gagliardi 2014-05-30 17:59:29 -04:00
parent c543f5639b
commit 4a66f1467b
5 changed files with 63 additions and 8 deletions

View File

@ -31,8 +31,53 @@ func defWindowProc(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRE
return _LRESULT(r1) 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 { 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 { switch uMsg {
case _WM_COMMAND: case _WM_COMMAND:
id := _HMENU(wParam.LOWORD()) id := _HMENU(wParam.LOWORD())

View File

@ -30,6 +30,7 @@ type classData struct {
xstyle uint32 xstyle uint32
mkid bool mkid bool
altStyle uint32 altStyle uint32
storeSysData bool
doNotLoadFont bool doNotLoadFont bool
appendMsg uintptr appendMsg uintptr
insertBeforeMsg uintptr insertBeforeMsg uintptr
@ -48,6 +49,7 @@ var classTypes = [nctypes]*classData{
register: registerStdWndClass, register: registerStdWndClass,
style: _WS_OVERLAPPEDWINDOW, style: _WS_OVERLAPPEDWINDOW,
xstyle: 0, xstyle: 0,
storeSysData: true,
doNotLoadFont: true, doNotLoadFont: true,
}, },
c_button: &classData{ c_button: &classData{
@ -157,6 +159,10 @@ func (s *sysData) make(window *sysData) (err error) {
if s.alternate { if s.alternate {
style = uintptr(ct.altStyle) style = uintptr(ct.altStyle)
} }
lpParam := uintptr(_NULL)
if ct.storeSysData {
lpParam = uintptr(unsafe.Pointer(s))
}
uitask <- &uimsg{ uitask <- &uimsg{
call: _createWindowEx, call: _createWindowEx,
p: []uintptr{ p: []uintptr{
@ -171,7 +177,7 @@ func (s *sysData) make(window *sysData) (err error) {
pwin, pwin,
uintptr(cid), uintptr(cid),
uintptr(hInstance), uintptr(hInstance),
uintptr(_NULL), lpParam,
}, },
ret: ret, ret: ret,
} }

View File

@ -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 // 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 // we'll just simulate that here
var gwlpNames = map[string]string{ var gwlpNames = map[string]string{
"386": "etWindowLong", "386": "etWindowLongW",
"amd64": "etWindowLongPtr", "amd64": "etWindowLongPtrW",
} }
func printConst(f *os.File, goconst string, winconst string) { func printConst(f *os.File, goconst string, winconst string) {

View File

@ -28,6 +28,7 @@ const _ERROR = 0
const _ES_AUTOHSCROLL = 128 const _ES_AUTOHSCROLL = 128
const _ES_PASSWORD = 32 const _ES_PASSWORD = 32
const _FALSE = 0 const _FALSE = 0
const _GWLP_USERDATA = -21
const _GWL_STYLE = -16 const _GWL_STYLE = -16
const _ICC_PROGRESS_CLASS = 32 const _ICC_PROGRESS_CLASS = 32
const _LBS_EXTENDEDSEL = 2048 const _LBS_EXTENDEDSEL = 2048
@ -140,6 +141,7 @@ const _WM_MBUTTONDOWN = 519
const _WM_MBUTTONUP = 520 const _WM_MBUTTONUP = 520
const _WM_MOUSEACTIVATE = 33 const _WM_MOUSEACTIVATE = 33
const _WM_MOUSEMOVE = 512 const _WM_MOUSEMOVE = 512
const _WM_NCCREATE = 129
const _WM_PAINT = 15 const _WM_PAINT = 15
const _WM_RBUTTONDOWN = 516 const _WM_RBUTTONDOWN = 516
const _WM_RBUTTONUP = 517 const _WM_RBUTTONUP = 517
@ -162,5 +164,5 @@ const _IDC_ARROW = 32512
const _IDI_APPLICATION = 32512 const _IDI_APPLICATION = 32512
const _INVALID_HANDLE_VALUE = 4294967295 const _INVALID_HANDLE_VALUE = 4294967295
const _NULL = 0 const _NULL = 0
var _getWindowLongPtr = user32.NewProc("GetWindowLong") var _getWindowLongPtr = user32.NewProc("GetWindowLongW")
var _setWindowLongPtr = user32.NewProc("SetWindowLong") var _setWindowLongPtr = user32.NewProc("SetWindowLongW")

View File

@ -28,6 +28,7 @@ const _ERROR = 0
const _ES_AUTOHSCROLL = 128 const _ES_AUTOHSCROLL = 128
const _ES_PASSWORD = 32 const _ES_PASSWORD = 32
const _FALSE = 0 const _FALSE = 0
const _GWLP_USERDATA = -21
const _GWL_STYLE = -16 const _GWL_STYLE = -16
const _ICC_PROGRESS_CLASS = 32 const _ICC_PROGRESS_CLASS = 32
const _LBS_EXTENDEDSEL = 2048 const _LBS_EXTENDEDSEL = 2048
@ -140,6 +141,7 @@ const _WM_MBUTTONDOWN = 519
const _WM_MBUTTONUP = 520 const _WM_MBUTTONUP = 520
const _WM_MOUSEACTIVATE = 33 const _WM_MOUSEACTIVATE = 33
const _WM_MOUSEMOVE = 512 const _WM_MOUSEMOVE = 512
const _WM_NCCREATE = 129
const _WM_PAINT = 15 const _WM_PAINT = 15
const _WM_RBUTTONDOWN = 516 const _WM_RBUTTONDOWN = 516
const _WM_RBUTTONUP = 517 const _WM_RBUTTONUP = 517
@ -162,5 +164,5 @@ const _IDC_ARROW = 32512
const _IDI_APPLICATION = 32512 const _IDI_APPLICATION = 32512
const _INVALID_HANDLE_VALUE = 18446744073709551615 const _INVALID_HANDLE_VALUE = 18446744073709551615
const _NULL = 0 const _NULL = 0
var _getWindowLongPtr = user32.NewProc("GetWindowLongPtr") var _getWindowLongPtr = user32.NewProc("GetWindowLongPtrW")
var _setWindowLongPtr = user32.NewProc("SetWindowLongPtr") var _setWindowLongPtr = user32.NewProc("SetWindowLongPtrW")