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