David Hedberg : explorerframe: Handle keyboard events.
Alexandre Julliard
julliard at winehq.org
Tue Aug 17 11:31:17 CDT 2010
Module: wine
Branch: master
Commit: b349072687f2694d12871867e9854a16af35298b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b349072687f2694d12871867e9854a16af35298b
Author: David Hedberg <david.hedberg at gmail.com>
Date: Mon Aug 16 09:17:34 2010 +0200
explorerframe: Handle keyboard events.
---
dlls/explorerframe/nstc.c | 85 +++++++++++++++++++++++++++++++++++++++
dlls/explorerframe/tests/nstc.c | 28 +++++++++++++
2 files changed, 113 insertions(+), 0 deletions(-)
diff --git a/dlls/explorerframe/nstc.c b/dlls/explorerframe/nstc.c
index a9e667f..1852921 100644
--- a/dlls/explorerframe/nstc.c
+++ b/dlls/explorerframe/nstc.c
@@ -54,6 +54,8 @@ typedef struct {
HWND hwnd_main;
HWND hwnd_tv;
+ WNDPROC tv_oldwndproc;
+
NSTCSTYLE style;
NSTCSTYLE2 style2;
struct list roots;
@@ -69,6 +71,9 @@ static const DWORD unsupported_styles2 =
NSTCS2_INTERRUPTNOTIFICATIONS | NSTCS2_SHOWNULLSPACEMENU | NSTCS2_DISPLAYPADDING |
NSTCS2_DISPLAYPINNEDONLY | NTSCS2_NOSINGLETONAUTOEXPAND | NTSCS2_NEVERINSERTNONENUMERATED;
+/* Forward declarations */
+static LRESULT CALLBACK tv_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
+
/*************************************************************************
* NamespaceTree event wrappers
*/
@@ -145,6 +150,13 @@ static HRESULT events_OnSelectionChanged(NSTC2Impl *This, IShellItemArray *psia)
return INameSpaceTreeControlEvents_OnSelectionChanged(This->pnstce, psia);
}
+static HRESULT events_OnKeyboardInput(NSTC2Impl *This, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if(!This->pnstce) return S_OK;
+
+ return INameSpaceTreeControlEvents_OnKeyboardInput(This->pnstce, uMsg, wParam, lParam);
+}
+
/*************************************************************************
* NamespaceTree helper functions
*/
@@ -325,6 +337,16 @@ static UINT fill_sublevel(NSTC2Impl *This, HTREEITEM hitem)
return added;
}
+static HTREEITEM get_selected_treeitem(NSTC2Impl *This)
+{
+ return (HTREEITEM)SendMessageW(This->hwnd_tv, TVM_GETNEXTITEM, TVGN_CARET, 0);
+}
+
+static IShellItem *get_selected_shellitem(NSTC2Impl *This)
+{
+ return shellitem_from_treeitem(This, get_selected_treeitem(This));
+}
+
/*************************************************************************
* NamespaceTree window functions
*/
@@ -378,6 +400,12 @@ static LRESULT create_namespacetree(HWND hWnd, CREATESTRUCTW *crs)
INameSpaceTreeControl_AddRef((INameSpaceTreeControl*)This);
+ /* Subclass the treeview to get the keybord events. */
+ This->tv_oldwndproc = (WNDPROC)SetWindowLongPtrW(This->hwnd_tv, GWLP_WNDPROC,
+ (ULONG_PTR)tv_wndproc);
+ if(This->tv_oldwndproc)
+ SetPropA(This->hwnd_tv, "PROP_THIS", This);
+
return TRUE;
}
@@ -396,6 +424,13 @@ static LRESULT destroy_namespacetree(NSTC2Impl *This)
{
TRACE("%p\n", This);
+ /* Undo the subclassing */
+ if(This->tv_oldwndproc)
+ {
+ SetWindowLongPtrW(This->hwnd_tv, GWLP_WNDPROC, (ULONG_PTR)This->tv_oldwndproc);
+ RemovePropA(This->hwnd_tv, "PROP_THIS");
+ }
+
INameSpaceTreeControl_RemoveAllRoots((INameSpaceTreeControl*)This);
/* This reference was added in create_namespacetree */
@@ -535,6 +570,56 @@ static LRESULT on_tvn_selchangedw(NSTC2Impl *This, LPARAM lParam)
return TRUE;
}
+static LRESULT on_kbd_event(NSTC2Impl *This, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ IShellItem *psi;
+ HTREEITEM hitem;
+ TRACE("%p : %d, %lx, %lx\n", This, uMsg, wParam, lParam);
+
+ /* Handled by the client? */
+ if(FAILED(events_OnKeyboardInput(This, uMsg, wParam, lParam)))
+ return TRUE;
+
+ if(uMsg == WM_KEYDOWN)
+ {
+ switch(wParam)
+ {
+ case VK_DELETE:
+ psi = get_selected_shellitem(This);
+ FIXME("Deletion of file requested (shellitem: %p).\n", psi);
+ return TRUE;
+
+ case VK_F2:
+ hitem = get_selected_treeitem(This);
+ SendMessageW(This->hwnd_tv, TVM_EDITLABELW, 0, (LPARAM)hitem);
+ return TRUE;
+ }
+ }
+
+ /* Let the TreeView handle the key */
+ return FALSE;
+}
+
+static LRESULT CALLBACK tv_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
+{
+ NSTC2Impl *This = (NSTC2Impl*)GetPropA(hWnd, "PROP_THIS");
+
+ switch(uMessage) {
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ case WM_CHAR:
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ case WM_SYSCHAR:
+ if(on_kbd_event(This, uMessage, wParam, lParam))
+ return TRUE;
+ break;
+ }
+
+ /* Pass the message on to the treeview */
+ return CallWindowProcW(This->tv_oldwndproc, hWnd, uMessage, wParam, lParam);
+}
+
static LRESULT CALLBACK NSTC2_WndProc(HWND hWnd, UINT uMessage,
WPARAM wParam, LPARAM lParam)
{
diff --git a/dlls/explorerframe/tests/nstc.c b/dlls/explorerframe/tests/nstc.c
index 77d9254..170f189 100644
--- a/dlls/explorerframe/tests/nstc.c
+++ b/dlls/explorerframe/tests/nstc.c
@@ -160,6 +160,8 @@ static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput(
LPARAM lParam)
{
NSTCE_IMPL(iface)->count[OnKeyboardInput]++;
+ ok(wParam == 0x1234, "Got unexpected wParam %lx\n", wParam);
+ ok(lParam == 0x1234, "Got unexpected lParam %lx\n", lParam);
return E_NOTIMPL;
}
@@ -1252,6 +1254,12 @@ static void test_events(void)
if(hwnd_tv)
{
HTREEITEM hroot, hitem;
+ UINT i;
+ static const UINT kbd_msgs_event[] = {
+ WM_KEYDOWN, WM_KEYUP, WM_CHAR, WM_SYSKEYDOWN, WM_SYSKEYUP,
+ WM_SYSCHAR, 0 };
+ static const UINT kbd_msgs_noevent[] ={
+ WM_DEADCHAR, WM_SYSDEADCHAR, WM_UNICHAR, 0 };
/* Test On*Expand */
hroot = (HTREEITEM)SendMessageW(hwnd_tv, TVM_GETNEXTITEM, TVGN_ROOT, 0);
@@ -1275,6 +1283,26 @@ static void test_events(void)
process_msgs();
ok_event_count(pnstceimpl, OnSelectionChanged, 1);
ok_no_events(pnstceimpl);
+
+ /* Test OnKeyboardInput */
+ for(i = 0; kbd_msgs_event[i] != 0; i++)
+ {
+ SendMessageW(hwnd_tv, kbd_msgs_event[i], 0x1234, 0x1234);
+ ok(pnstceimpl->count[OnKeyboardInput] == 1,
+ "%d (%x): Got count %d\n",
+ kbd_msgs_event[i], kbd_msgs_event[i], pnstceimpl->count[OnKeyboardInput]);
+ pnstceimpl->count[OnKeyboardInput] = 0;
+ }
+
+ for(i = 0; kbd_msgs_noevent[i] != 0; i++)
+ {
+ SendMessageW(hwnd_tv, kbd_msgs_noevent[i], 0x1234, 0x1234);
+ ok(pnstceimpl->count[OnKeyboardInput] == 0,
+ "%d (%x): Got count %d\n",
+ kbd_msgs_noevent[i], kbd_msgs_noevent[i], pnstceimpl->count[OnKeyboardInput]);
+ pnstceimpl->count[OnKeyboardInput] = 0;
+ }
+ ok_no_events(pnstceimpl);
}
else
skip("Skipping some tests.\n");
More information about the wine-cvs
mailing list