Module: wine Branch: master Commit: b349072687f2694d12871867e9854a16af35298b URL: http://source.winehq.org/git/wine.git/?a=commit;h=b349072687f2694d12871867e9...
Author: David Hedberg david.hedberg@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");