Implemented code to save and restore control focus on Windows properly when switching away from/back to our program. It's disabled for now though because it doesn't seem to work...

This commit is contained in:
Pietro Gagliardi 2014-06-05 23:27:17 -04:00
parent bb44712fad
commit 00ec85dee6
4 changed files with 43 additions and 0 deletions

View File

@ -68,6 +68,43 @@ func storeSysData(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRES
return defWindowProc(hwnd, uMsg, wParam, lParam) return defWindowProc(hwnd, uMsg, wParam, lParam)
} }
var (
_getFocus = user32.NewProc("GetFocus")
_isChild = user32.NewProc("IsChild")
// _setFocus in area_windows.go
)
// this is needed to ensure focus is preserved when switching away from and back to our program
// from http://blogs.msdn.com/b/oldnewthing/archive/2014/05/21/10527168.aspx
func (s *sysData) handleFocus(wParam _WPARAM) {
// parameter splitting from Microsoft's windowsx.h
state := uint32(wParam.LOWORD()) // originally UINT
minimized := wParam.HIWORD() != 0
if minimized { // don't do anything on minimize
return
}
if state == _WA_INACTIVE { // focusing out
old, _, _ := _getFocus.Call()
if _HWND(old) != _HWND(_NULL) { // if there is one
r1, _, _ := _isChild.Call(
uintptr(s.hwnd),
old)
if r1 != 0 {
s.lastfocus = _HWND(old)
println("s",s.lastfocus)
}
}
} else { // focusing in
if s.lastfocus != _HWND(_NULL) { // if we have one
r1, _, err := _setFocus.Call(uintptr(s.lastfocus))
if _HWND(r1) == _HWND(_NULL) {
panic(fmt.Errorf("error setting focus to previously focused window on reactivating Window: %v", err))
}
}
}
}
func stdWndProc(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT { func stdWndProc(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT {
s := getSysData(hwnd) s := getSysData(hwnd)
if s == nil { // not yet saved if s == nil { // not yet saved
@ -105,6 +142,9 @@ func stdWndProc(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESUL
} }
} }
return 0 return 0
// case _WM_ACTIVATE:
// s.handleFocus(wParam)
// return 0
case _WM_GETMINMAXINFO: case _WM_GETMINMAXINFO:
mm := lParam.MINMAXINFO() mm := lParam.MINMAXINFO()
// ... minimum size // ... minimum size

View File

@ -21,6 +21,7 @@ type sysData struct {
areawidth int areawidth int
areaheight int areaheight int
clickCounter clickCounter clickCounter clickCounter
lastfocus _HWND
} }
type classData struct { type classData struct {

View File

@ -129,6 +129,7 @@ const _VK_RWIN = 92
const _VK_SHIFT = 16 const _VK_SHIFT = 16
const _VK_SUBTRACT = 109 const _VK_SUBTRACT = 109
const _VK_UP = 38 const _VK_UP = 38
const _WA_INACTIVE = 0
const _WM_ACTIVATE = 6 const _WM_ACTIVATE = 6
const _WM_APP = 32768 const _WM_APP = 32768
const _WM_CLOSE = 16 const _WM_CLOSE = 16

View File

@ -129,6 +129,7 @@ const _VK_RWIN = 92
const _VK_SHIFT = 16 const _VK_SHIFT = 16
const _VK_SUBTRACT = 109 const _VK_SUBTRACT = 109
const _VK_UP = 38 const _VK_UP = 38
const _WA_INACTIVE = 0
const _WM_ACTIVATE = 6 const _WM_ACTIVATE = 6
const _WM_APP = 32768 const _WM_APP = 32768
const _WM_CLOSE = 16 const _WM_CLOSE = 16