entry: add onKeyEvent handler taking uiAreaKeyEvent

This commit is contained in:
Rustam Gamidov 2020-02-26 18:45:03 +02:00
parent 49cc39c291
commit 599f483914
4 changed files with 87 additions and 38 deletions

1
ui.h
View File

@ -168,6 +168,7 @@ typedef struct uiEntry uiEntry;
_UI_EXTERN char *uiEntryText(uiEntry *e); _UI_EXTERN char *uiEntryText(uiEntry *e);
_UI_EXTERN void uiEntrySetText(uiEntry *e, const char *text); _UI_EXTERN void uiEntrySetText(uiEntry *e, const char *text);
_UI_EXTERN void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *e, void *data), void *data); _UI_EXTERN void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *e, void *data), void *data);
_UI_EXTERN void uiEntryOnKeyEvent(uiEntry *e, int (*f)(uiEntry *e, uiAreaKeyEvent *event));
_UI_EXTERN int uiEntryReadOnly(uiEntry *e); _UI_EXTERN int uiEntryReadOnly(uiEntry *e);
_UI_EXTERN void uiEntrySetReadOnly(uiEntry *e, int readonly); _UI_EXTERN void uiEntrySetReadOnly(uiEntry *e, int readonly);
_UI_EXTERN uiEntry *uiNewEntry(void); _UI_EXTERN uiEntry *uiNewEntry(void);

View File

@ -5,23 +5,6 @@
// TODO https://github.com/Microsoft/Windows-classic-samples/blob/master/Samples/Win7Samples/multimedia/DirectWrite/PadWrite/TextEditor.cpp notes on explicit RTL handling under MirrorXCoordinate(); also in areadraw.cpp too? // TODO https://github.com/Microsoft/Windows-classic-samples/blob/master/Samples/Win7Samples/multimedia/DirectWrite/PadWrite/TextEditor.cpp notes on explicit RTL handling under MirrorXCoordinate(); also in areadraw.cpp too?
static uiModifiers getModifiers(void)
{
uiModifiers m = 0;
if ((GetKeyState(VK_CONTROL) & 0x80) != 0)
m |= uiModifierCtrl;
if ((GetKeyState(VK_MENU) & 0x80) != 0)
m |= uiModifierAlt;
if ((GetKeyState(VK_SHIFT) & 0x80) != 0)
m |= uiModifierShift;
if ((GetKeyState(VK_LWIN) & 0x80) != 0)
m |= uiModifierSuper;
if ((GetKeyState(VK_RWIN) & 0x80) != 0)
m |= uiModifierSuper;
return m;
}
/* /*
Windows doesn't natively support mouse crossing events. Windows doesn't natively support mouse crossing events.
@ -206,25 +189,7 @@ static int areaKeyEvent(uiArea *a, int up, WPARAM wParam, LPARAM lParam)
goto keyFound; goto keyFound;
} }
// okay, those above cases didn't match anything if (fillKeyEvent(ke, wParam, lParam))
// first try the extended keys
for (i = 0; extKeys[i].vk != VK_SNAPSHOT; i++)
if (extKeys[i].vk == wParam) {
ke.ExtKey = extKeys[i].extkey;
goto keyFound;
}
// then try modifier keys
for (i = 0; modKeys[i].vk != VK_SNAPSHOT; i++)
if (modKeys[i].vk == wParam) {
ke.Modifier = modKeys[i].mod;
// and don't include the key in Modifiers
ke.Modifiers &= ~ke.Modifier;
goto keyFound;
}
// and finally everything else
if (uiprivFromScancode((lParam >> 16) & 0xFF, &ke))
goto keyFound; goto keyFound;
// not a supported key, assume unhandled // not a supported key, assume unhandled

View File

@ -1,5 +1,6 @@
// 8 april 2015 // 8 april 2015
#include "uipriv_windows.hpp" #include "uipriv_windows.hpp"
#include "keyboard.hpp"
struct uiEntry { struct uiEntry {
uiWindowsControl c; uiWindowsControl c;
@ -7,26 +8,46 @@ struct uiEntry {
void (*onChanged)(uiEntry *, void *); void (*onChanged)(uiEntry *, void *);
void *onChangedData; void *onChangedData;
BOOL inhibitChanged; BOOL inhibitChanged;
int (*onKeyEvent)(uiEntry *, uiAreaKeyEvent *);
void *self;
WNDPROC native_wndproc; WNDPROC native_wndproc;
}; };
static LRESULT CALLBACK entryWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) static LRESULT CALLBACK entryWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
BOOL righthand = FALSE;
uiAreaKeyEvent ke;
ke.Key = 0;
ke.ExtKey = 0;
ke.Modifier = 0;
ke.Modifiers = getModifiers();
ke.Up = 0;
int (*onKeyEvent)(uiEntry *, uiAreaKeyEvent *) = (int (*)(uiEntry *, uiAreaKeyEvent *))GetProp(hwnd, L"ON_KEY_EVENT");
uiEntry *self = (uiEntry *)GetProp(hwnd, L"SELF");
switch (uMsg) switch (uMsg)
{ {
case WM_GETDLGCODE: case WM_GETDLGCODE:
return DLGC_HASSETSEL | DLGC_WANTALLKEYS; return DLGC_HASSETSEL | DLGC_WANTALLKEYS;
break; break;
case WM_KEYUP: case WM_KEYUP:
ke.Up = 1;
case WM_KEYDOWN: case WM_KEYDOWN:
if (onKeyEvent) {
fillKeyEvent(ke, wParam, lParam);
if ((*onKeyEvent)(self, &ke)) {
return TRUE;
}
}
break; break;
} }
WNDPROC native_wndproc = (WNDPROC)GetProp(hwnd, L"NATIVE_WNDPROC"); WNDPROC native_wndproc = (WNDPROC)GetProp(hwnd, L"NATIVE_WNDPROC");
return CallWindowProcW(native_wndproc, hwnd, uMsg, wParam, lParam); return CallWindowProcW(native_wndproc, hwnd, uMsg, wParam, lParam);
} }
static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
{ {
uiEntry *e = uiEntry(c); uiEntry *e = uiEntry(c);
@ -46,6 +67,8 @@ static void uiEntryDestroy(uiControl *c)
(WNDPROC)SetWindowLongPtrW(e->hwnd, GWLP_WNDPROC, (LONG_PTR)e->native_wndproc); (WNDPROC)SetWindowLongPtrW(e->hwnd, GWLP_WNDPROC, (LONG_PTR)e->native_wndproc);
RemoveProp(e->hwnd, L"NATIVE_WNDPROC"); RemoveProp(e->hwnd, L"NATIVE_WNDPROC");
RemoveProp(e->hwnd, L"ON_KEY_EVENT");
RemoveProp(e->hwnd, L"SELF");
uiWindowsUnregisterWM_COMMANDHandler(e->hwnd); uiWindowsUnregisterWM_COMMANDHandler(e->hwnd);
uiWindowsEnsureDestroyWindow(e->hwnd); uiWindowsEnsureDestroyWindow(e->hwnd);
@ -77,6 +100,13 @@ static void defaultOnChanged(uiEntry *e, void *data)
// do nothing // do nothing
} }
static int defaultOnKeyEvent(uiEntry *e, uiAreaKeyEvent *event)
{
// do nothing
return FALSE;
}
char *uiEntryText(uiEntry *e) char *uiEntryText(uiEntry *e)
{ {
return uiWindowsWindowText(e->hwnd); return uiWindowsWindowText(e->hwnd);
@ -97,6 +127,12 @@ void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *, void *), void *data)
e->onChangedData = data; e->onChangedData = data;
} }
void uiEntryOnKeyEvent(uiEntry *e, int (*f)(uiEntry *, uiAreaKeyEvent *))
{
e->onKeyEvent = f;
SetProp(e->hwnd, L"ON_KEY_EVENT", (HGLOBAL)(f));
}
int uiEntryReadOnly(uiEntry *e) int uiEntryReadOnly(uiEntry *e)
{ {
return (getStyle(e->hwnd) & ES_READONLY) != 0; return (getStyle(e->hwnd) & ES_READONLY) != 0;
@ -128,9 +164,11 @@ static uiEntry *finishNewEntry(DWORD style)
uiWindowsRegisterWM_COMMANDHandler(e->hwnd, onWM_COMMAND, uiControl(e)); uiWindowsRegisterWM_COMMANDHandler(e->hwnd, onWM_COMMAND, uiControl(e));
e->native_wndproc = (WNDPROC)SetWindowLongPtrW(e->hwnd, GWLP_WNDPROC, (LONG_PTR)entryWndProc); e->native_wndproc = (WNDPROC)SetWindowLongPtrW(e->hwnd, GWLP_WNDPROC, (LONG_PTR)entryWndProc);
SetProp(e->hwnd, L"NATIVE_WNDPROC", (HANDLE)e->native_wndproc); SetProp(e->hwnd, L"NATIVE_WNDPROC", (HGLOBAL)e->native_wndproc);
SetProp(e->hwnd, L"SELF", (HGLOBAL)e);
uiEntryOnChanged(e, defaultOnChanged, NULL); uiEntryOnChanged(e, defaultOnChanged, NULL);
uiEntryOnKeyEvent(e, defaultOnKeyEvent);
return e; return e;
} }

View File

@ -74,3 +74,48 @@ static const struct {
{ VK_RWIN, uiModifierSuper }, { VK_RWIN, uiModifierSuper },
{ VK_SNAPSHOT, 0 }, { VK_SNAPSHOT, 0 },
}; };
static uiModifiers getModifiers(void)
{
uiModifiers m = 0;
if ((GetKeyState(VK_CONTROL) & 0x80) != 0)
m |= uiModifierCtrl;
if ((GetKeyState(VK_MENU) & 0x80) != 0)
m |= uiModifierAlt;
if ((GetKeyState(VK_SHIFT) & 0x80) != 0)
m |= uiModifierShift;
if ((GetKeyState(VK_LWIN) & 0x80) != 0)
m |= uiModifierSuper;
if ((GetKeyState(VK_RWIN) & 0x80) != 0)
m |= uiModifierSuper;
return m;
}
static BOOL fillKeyEvent(uiAreaKeyEvent &ke, WPARAM wParam, LPARAM lParam)
{
int i = 0;
for (i = 0; extKeys[i].vk != VK_SNAPSHOT; i++) {
if (extKeys[i].vk == wParam) {
ke.ExtKey = extKeys[i].extkey;
return TRUE;
}
}
for (i = 0; modKeys[i].vk != VK_SNAPSHOT; i++) {
if (modKeys[i].vk == wParam) {
ke.Modifier = modKeys[i].mod;
ke.Modifiers &= ~ke.Modifier;
return TRUE;
}
}
// TODO the original code only did this if ke.Modifiers == 0 - why?
if (uiprivFromScancode((lParam >> 16) & 0xFF, &ke)) {
return TRUE;
}
return FALSE;
}