entry: add onKeyEvent handler taking uiAreaKeyEvent
This commit is contained in:
parent
49cc39c291
commit
599f483914
1
ui.h
1
ui.h
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue