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:
parent
c543f5639b
commit
4a66f1467b
|
@ -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())
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue