Made Areas on Windows tab stops and implemented AreaHandler.Defocuses() on Windows.

This commit is contained in:
Pietro Gagliardi 2014-08-13 10:41:27 -04:00
parent 59f2eeca22
commit b01c653942
5 changed files with 38 additions and 6 deletions

View File

@ -5,8 +5,6 @@
#include "winapi_windows.h" #include "winapi_windows.h"
#include "_cgo_export.h" #include "_cgo_export.h"
#define areaWindowClass L"gouiarea"
static void getScrollPos(HWND hwnd, int *xpos, int *ypos) static void getScrollPos(HWND hwnd, int *xpos, int *ypos)
{ {
SCROLLINFO si; SCROLLINFO si;
@ -412,6 +410,8 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
case msgAreaRepaintAll: case msgAreaRepaintAll:
repaintArea(hwnd); repaintArea(hwnd);
return 0; return 0;
case msgAreaDefocuses:
return (LRESULT) areaDefocuses(data);
default: default:
return DefWindowProcW(hwnd, uMsg, wParam, lParam); return DefWindowProcW(hwnd, uMsg, wParam, lParam);
} }
@ -445,7 +445,7 @@ HWND newArea(void *data)
hwnd = CreateWindowExW( hwnd = CreateWindowExW(
0, 0,
areaWindowClass, L"", areaWindowClass, L"",
WS_HSCROLL | WS_VSCROLL | WS_CHILD | WS_VISIBLE, WS_HSCROLL | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
100, 100, 100, 100,
msgwin, NULL, hInstance, data); msgwin, NULL, hInstance, data);

View File

@ -280,6 +280,15 @@ func areaResetClickCounter(data unsafe.Pointer) {
a.clickCounter.reset() a.clickCounter.reset()
} }
//export areaDefocuses
func areaDefocuses(data unsafe.Pointer) C.BOOL {
a := (*area)(data)
if a.handler.Defocuses() {
return C.TRUE
}
return C.FALSE
}
func (a *area) hwnd() C.HWND { func (a *area) hwnd() C.HWND {
return a._hwnd return a._hwnd
} }

View File

@ -3,11 +3,16 @@
#include "winapi_windows.h" #include "winapi_windows.h"
#include "_cgo_export.h" #include "_cgo_export.h"
/* note that this includes the terminating '\0' */
#define NAREACLASS (sizeof areaWindowClass / sizeof areaWindowClass[0])
void uimsgloop(void) void uimsgloop(void)
{ {
MSG msg; MSG msg;
int res; int res;
HWND active; HWND active;
WCHAR classchk[NAREACLASS];
BOOL dodlgmessage;
for (;;) { for (;;) {
SetLastError(0); SetLastError(0);
@ -17,9 +22,24 @@ void uimsgloop(void)
if (res == 0) /* WM_QUIT */ if (res == 0) /* WM_QUIT */
break; break;
active = GetActiveWindow(); active = GetActiveWindow();
// TODO this interferes with Area if (active != NULL) {
if (active != NULL && IsDialogMessageW(active, &msg) != 0) HWND focus;
continue;
dodlgmessage = TRUE;
focus = GetFocus();
if (focus != NULL) {
// theoretically we could use the class atom to avoid a wcscmp()
// however, raymond chen advises against this - TODO_get_URL
// while I have no idea what could deregister *my* window class from under *me*, better safe than sorry
// we could also theoretically just send msgAreaDefocuses directly, but what DefWindowProc() does to a WM_APP message is undocumented
if (GetClassNameW(focus, classchk, NAREACLASS) == 0)
xpanic("error getting name of focused window class for Area check", GetLastError());
if (wcscmp(classchk, areaWindowClass) == 0)
dodlgmessage = (BOOL) SendMessageW(focus, msgAreaDefocuses, 0, 0);
}
if (dodlgmessage && IsDialogMessageW(active, &msg) != 0)
continue;
}
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessageW(&msg); DispatchMessageW(&msg);
} }

View File

@ -29,6 +29,7 @@ enum {
msgNOTIFY, /* WM_NOTIFY proxy */ msgNOTIFY, /* WM_NOTIFY proxy */
msgAreaSizeChanged, msgAreaSizeChanged,
msgAreaRepaintAll, msgAreaRepaintAll,
msgAreaDefocuses,
}; };
/* uitask_windows.c */ /* uitask_windows.c */
@ -104,6 +105,7 @@ extern HWND newContainer(void *);
extern void calculateBaseUnits(HWND, int *, int *, LONG *); extern void calculateBaseUnits(HWND, int *, int *, LONG *);
/* area_window.c */ /* area_window.c */
#define areaWindowClass L"gouiarea"
extern void repaintArea(HWND); extern void repaintArea(HWND);
extern DWORD makeAreaWindowClass(char **); extern DWORD makeAreaWindowClass(char **);
extern HWND newArea(void *); extern HWND newArea(void *);

View File

@ -137,6 +137,7 @@ func (tw *testwin) make(done chan struct{}) {
tw.t.Append("Password Field", tw.e2) tw.t.Append("Password Field", tw.e2)
tw.w.Show() tw.w.Show()
if *smallWindow { if *smallWindow {
// TODO windows - tab order wrong in wine?
tw.wsmall = NewWindow("Small", 80, 80, tw.wsmall = NewWindow("Small", 80, 80,
NewVerticalStack( NewVerticalStack(
NewButton("Small"), NewButton("Small"),