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 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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue