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 void uiEntrySetText(uiEntry *e, const char *text);
_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 void uiEntrySetReadOnly(uiEntry *e, int readonly);
_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?
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.
@ -206,25 +189,7 @@ static int areaKeyEvent(uiArea *a, int up, WPARAM wParam, LPARAM lParam)
goto keyFound;
}
// okay, those above cases didn't match anything
// 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))
if (fillKeyEvent(ke, wParam, lParam))
goto keyFound;
// not a supported key, assume unhandled

View File

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

View File

@ -74,3 +74,48 @@ static const struct {
{ VK_RWIN, uiModifierSuper },
{ 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;
}