Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in tip

fogcreek shellext: added basic infrastructure for keyboard hook

Changeset 11daa31b29f1

Parent ca343468d05b

by David Golub

Changes to 9 files · Browse files at 11daa31b29f1 Showing diff from parent ca343468d05b Diff from another changeset...

 
23
24
25
 
26
27
28
 
33
34
35
 
36
37
38
 
23
24
25
26
27
28
29
 
34
35
36
37
38
39
40
@@ -23,6 +23,7 @@
 #include "TortoiseHgCmenu.h"  #include "TortoiseHgDropHandler.h"  #include "TortoiseHgOverlay.h" +#include "TortoiseHgKeyboard.h"    CComModule _Module;   @@ -33,6 +34,7 @@
  OBJECT_ENTRY(CLSID_TortoiseHgAdded, CTortoiseHgAdded)   OBJECT_ENTRY(CLSID_TortoiseHgModified, CTortoiseHgModified)   OBJECT_ENTRY(CLSID_TortoiseHgUnversioned, CTortoiseHgUnversioned) + OBJECT_ENTRY(CLSID_TortoiseHgKeyboard, CTortoiseHgKeyboard)  END_OBJECT_MAP()    BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
 
57
58
59
 
 
 
 
 
 
60
 
57
58
59
60
61
62
63
64
65
66
@@ -57,4 +57,10 @@
  {   [default] interface IUnknown;   } + + [uuid(36BFF16B-4EA0-4D91-9D2C-39941CF0BFE4)] + coclass TortoiseHgKeyboard + { + [default] interface IObjectWithSite; + }  }
 
29
30
31
 
32
33
34
 
29
30
31
32
33
34
35
@@ -29,6 +29,7 @@
 IDR_ADDED REGISTRY "TortoiseHgAdded.rgs"  IDR_MODIFIED REGISTRY "TortoiseHgModified.rgs"  IDR_UNVERSIONED REGISTRY "TortoiseHgUnversioned.rgs" +IDR_KEYBOARD REGISTRY "TortoiseHgKeyboard.rgs"    #ifdef APSTUDIO_INVOKED  /////////////////////////////////////////////////////////////////////////////
 
222
223
224
 
225
226
227
 
245
246
247
 
248
249
250
 
256
257
258
 
259
260
261
 
222
223
224
225
226
227
228
 
246
247
248
249
250
251
252
 
258
259
260
261
262
263
264
@@ -222,6 +222,7 @@
  <ClCompile Include="THgVersion.cpp" />   <ClCompile Include="TortoiseHgCmenu.cpp" />   <ClCompile Include="TortoiseHgDropHandler.cpp" /> + <ClCompile Include="TortoiseHgKeyboard.cpp" />   <ClCompile Include="TortoiseHgOverlay.cpp" />   <ClCompile Include="TortoiseIconBitmap.cpp" />   <ClCompile Include="TortoiseUtils.cpp" /> @@ -245,6 +246,7 @@
  <ClInclude Include="THgVersion.h" />   <ClInclude Include="TortoiseHgCmenu.h" />   <ClInclude Include="TortoiseHgDropHandler.h" /> + <ClInclude Include="TortoiseHgKeyboard.h" />   <ClInclude Include="TortoiseHgOverlay.h" />   <ClInclude Include="TortoiseIconBitmap.h" />   <ClInclude Include="TortoiseUtils.h" /> @@ -256,6 +258,7 @@
  <None Include="TortoiseHgAdded.rgs" />   <None Include="TortoiseHgCmenu.rgs" />   <None Include="TortoiseHgDropHandler.rgs" /> + <None Include="TortoiseHgKeyboard.rgs" />   <None Include="TortoiseHgModified.rgs" />   <None Include="TortoiseHgNormal.rgs" />   <None Include="TortoiseHgUnversioned.rgs" />
 
78
79
80
 
 
 
81
82
83
 
143
144
145
 
 
 
146
147
148
 
169
170
171
 
 
 
172
173
174
 
78
79
80
81
82
83
84
85
86
 
146
147
148
149
150
151
152
153
154
 
175
176
177
178
179
180
181
182
183
@@ -78,6 +78,9 @@
  <ClCompile Include="Kiln.cpp">   <Filter>Source Files</Filter>   </ClCompile> + <ClCompile Include="TortoiseHgKeyboard.cpp"> + <Filter>Source Files</Filter> + </ClCompile>   </ItemGroup>   <ItemGroup>   <ClInclude Include="Directory.h"> @@ -143,6 +146,9 @@
  <ClInclude Include="Kiln.h">   <Filter>Header Files</Filter>   </ClInclude> + <ClInclude Include="TortoiseHgKeyboard.h"> + <Filter>Header Files</Filter> + </ClInclude>   </ItemGroup>   <ItemGroup>   <None Include="THgShell.def"> @@ -169,6 +175,9 @@
  <None Include="THgShell.rc2">   <Filter>Resource Files</Filter>   </None> + <None Include="TortoiseHgKeyboard.rgs"> + <Filter>Resource Files</Filter> + </None>   </ItemGroup>   <ItemGroup>   <ResourceCompile Include="THgShell.rc">
Change 1 of 1 Show Entire File win32/​shellext/​TortoiseHgKeyboard.cpp Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
@@ -0,0 +1,102 @@
+// Copyright (C) 2011 Fog Creek Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "stdafx.h" +#include "THgShell_h.h" + +#include "TortoiseHgKeyboard.h" + +// Each Windows Explorer window is launched in a separate thread. Therefore, use thread +// local storage so that each thread can have its own hook. +__declspec(thread) CTortoiseHgKeyboard* CTortoiseHgKeyboard::g_pObject = NULL; + +// Keyboard shortcut flags +#define KSF_ALT 0x0001 +#define KSF_CONTROL 0x0002 +#define KSF_SHIFT 0x0004 + +struct CKeyShortcut +{ + CString strName; + WORD wKey; + WORD wFlags; +}; + +static const CKeyShortcut KeyShortcutList[] = +{ + { "add", VK_INSERT, KSF_ALT }, + { "remove", VK_DELETE, KSF_ALT }, +}; + +STDMETHODIMP CTortoiseHgKeyboard::SetSite(IUnknown* pUnkSite) +{ + if (g_pObject == NULL) + { + ATLASSERT(m_hHook == NULL); + g_pObject = this; + m_hHook = ::SetWindowsHookEx(WH_KEYBOARD, HookProc, NULL, + ::GetCurrentThreadId()); + } + + return IObjectWithSiteImpl<CTortoiseHgKeyboard>::SetSite(pUnkSite); +} + +LRESULT CALLBACK CTortoiseHgKeyboard::HookProc(int code, WPARAM wParam, LPARAM lParam) +{ + ATLASSERT(g_pObject != NULL); + ATLASSERT(g_pObject->m_hHook != NULL); + + // Ignore repeated key messages when the user holds a key down, as well as calls when + // a key is released. + if (!(lParam & 0x80000000L) && !(lParam & 0x40000000L)) + { + // Get the state of the Alt, Control, and Shift keys. + WORD wFlags = 0; + if (::GetKeyState(VK_MENU) & 0x8000) wFlags |= KSF_ALT; + if (::GetKeyState(VK_CONTROL) & 0x8000) wFlags |= KSF_CONTROL; + if (::GetKeyState(VK_SHIFT) & 0x8000) wFlags |= KSF_SHIFT; + + // Look for a matching keyboard shortcut. + for (int i = 0; i < sizeof(KeyShortcutList) / sizeof(CKeyShortcut); i++) + { + if (KeyShortcutList[i].wKey == wParam && KeyShortcutList[i].wFlags == wFlags) + { + } + } + } + + return ::CallNextHookEx(g_pObject->m_hHook, code, wParam, lParam); +} + +HRESULT CTortoiseHgKeyboard::GetActiveShellView(IShellView** ppSV) +{ + CComQIPtr<IWebBrowser2> spWB = m_spUnkSite; + if (spWB == NULL) return E_FAIL; + CComPtr<IDispatch> spApp; + if (FAILED(spWB->get_Application(&spApp))) return E_FAIL; + CComQIPtr<IServiceProvider> spSP = spApp; + if (spSP == NULL) return E_FAIL; + CComPtr<IShellBrowser> spSB; + if (FAILED(spSP->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&spSB))) + { + return E_FAIL; + } + return spSB->QueryActiveShellView(ppSV); +} + +CTortoiseHgKeyboard::CTortoiseHgKeyboard() : + m_hHook(NULL) +{ +}
Change 1 of 1 Show Entire File win32/​shellext/​TortoiseHgKeyboard.h Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@@ -0,0 +1,43 @@
+// Copyright (C) 2011 Fog Creek Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#pragma once + +class CTortoiseHgKeyboard : + public CComObjectRootEx<CComMultiThreadModel>, + public CComCoClass<CTortoiseHgKeyboard, &CLSID_TortoiseHgKeyboard>, + public IObjectWithSiteImpl<CTortoiseHgKeyboard> +{ +private: + static __declspec(thread) CTortoiseHgKeyboard* g_pObject; + HHOOK m_hHook; + +public: + CTortoiseHgKeyboard(); + + BEGIN_COM_MAP(CTortoiseHgKeyboard) + COM_INTERFACE_ENTRY(IObjectWithSite) + END_COM_MAP() + + DECLARE_REGISTRY_RESOURCEID(IDR_KEYBOARD) + + // IObjectWithSite + STDMETHOD(SetSite)(IUnknown* pUnkSite); + +private: + HRESULT GetActiveShellView(IShellView** ppSV); + + static LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam); +};
Change 1 of 1 Show Entire File win32/​shellext/​TortoiseHgKeyboard.rgs Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@@ -0,0 +1,35 @@
+HKCR +{ + NoRemove 'CLSID' + { + ForceRemove '{36BFF16B-4EA0-4D91-9D2C-39941CF0BFE4}' = s 'TortoiseHg' + { + 'InprocServer32' = s '%MODULE%' + { + val 'ThreadingModel' = s 'Apartment' + } + } + } +} +HKLM +{ + NoRemove 'Software' + { + NoRemove 'Microsoft' + { + NoRemove 'Windows' + { + NoRemove 'CurrentVersion' + { + NoRemove 'Explorer' + { + NoRemove 'Browser Helper Objects' + { + ForceRemove '{36BFF16B-4EA0-4D91-9D2C-39941CF0BFE4}' = s 'TortoiseHg' + } + } + } + } + } + } +}
 
8
9
10
 
11
12
13
14
15
16
 
17
18
19
 
8
9
10
11
12
13
14
15
16
 
17
18
19
20
@@ -8,12 +8,13 @@
 #define IDR_ADDED 104  #define IDR_MODIFIED 105  #define IDR_UNVERSIONED 106 +#define IDR_KEYBOARD 107    // Next default values for new objects  //  #ifdef APSTUDIO_INVOKED  #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 107 +#define _APS_NEXT_RESOURCE_VALUE 108  #define _APS_NEXT_COMMAND_VALUE 40001  #define _APS_NEXT_CONTROL_VALUE 1000  #define _APS_NEXT_SYMED_VALUE 101