SO3Engine
SO3KeyboardHook.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
32#include "SO3Renderer/SO3Root.h"
36
37#ifdef _WIN32
38#include "Windowsx.h"
39#endif
40
41namespace SO3
42{
43#ifdef _WIN32
44 LRESULT CALLBACK GetMessageProcKeyBoardHook(UINT nCode, WPARAM wParam, LPARAM lParam);
45 LRESULT CALLBACK GetProcKeyBoardHook(UINT nCode, WPARAM wParam, LPARAM lParam);
46#endif
47
49
51 {
52 instance = this;
53
54#ifdef _WIN32
55 HINSTANCE hInstance = GetModuleHandle(0);
56 getMsgHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMessageProcKeyBoardHook, hInstance, GetCurrentThreadId());
57 getProcHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)GetProcKeyBoardHook, hInstance, GetCurrentThreadId());
58#endif
59 }
60
62 {
63#ifdef _WIN32
64 UnhookWindowsHookEx(getMsgHook);
65 UnhookWindowsHookEx(getProcHook);
66#endif
67 instance = 0;
68 }
69
70 LONG SKeyboardHook::handleHook(UINT msg, ScolWindowHandle hwnd, WPARAM wParam, LPARAM lParam)
71 {
72#ifdef _WIN32
73 LRESULT stopFurtherProcessing = FALSE;
75 if (window != 0)
76 {
77 //catch keyboard and system messages to send to widget
78 if (msg == WM_KEYDOWN || msg == WM_KEYUP || msg == WM_CHAR || msg == WM_CANCELMODE ||
79 msg == WM_DEADCHAR || msg == WM_SYSKEYDOWN ||
80 msg == WM_SYSKEYUP || msg == WM_SYSDEADCHAR || msg == WM_SYSCHAR ||
81 msg == WM_IME_CHAR || msg == WM_IME_COMPOSITION || msg == WM_IME_COMPOSITIONFULL ||
82 msg == WM_IME_CONTROL || msg == WM_IME_ENDCOMPOSITION || msg == WM_IME_KEYDOWN ||
83 msg == WM_IME_KEYUP || msg == WM_IME_NOTIFY || msg == WM_IME_REQUEST ||
84 msg == WM_IME_SELECT || msg == WM_IME_SETCONTEXT || msg == WM_IME_STARTCOMPOSITION ||
85 msg == WM_COPY || msg == WM_PASTE || msg == WM_CUT || msg == WM_HELP)
86 SWidgetManager::getSingleton().InjectKeyEvent(msg, hwnd, wParam, lParam);
87 else
88 switch (msg)
89 {
90 case WM_ACTIVATE:
91 {
92 // break input to bypss defProc and signal we processed the message when lost focus
93 bool active = (LOWORD(wParam) != WA_INACTIVE);
94 if (!active)
95 break;
96 }
97 case WM_DISPLAYCHANGE:
98 case WM_MOVE:
99 case WM_SIZE:
100 case WM_SIZING:
101 case WM_STYLECHANGED:
102 case WM_WINDOWPOSCHANGED:
103 case WM_SYSCOMMAND:
104 case WM_SHOWWINDOW:
105 case WM_EXITSIZEMOVE:
106 {
107 window->SetSizeDirty();
108 break;
109 }
110
111 /*case WM_LBUTTONDOWN:
112 {
113 int x = (int)GET_X_LPARAM(lParam);
114 int y = (int)GET_Y_LPARAM(lParam);
115
116 //for touch
117 SWidgetManager::getSingleton().InjectMouseMove(window, x, y, 0);
118
119 // Call raycasting function
120 //window->RayCast(x, y);
121
122 // Updating widgets.
123 SWidgetManager::getSingleton().InjectMouseDown(window, x, y, MOUSE_LEFT_BUTTON);
124 break;
125 }
126
127 case WM_LBUTTONUP:
128 {
129 int x = (int)GET_X_LPARAM(lParam);
130 int y = (int)GET_Y_LPARAM(lParam);
131
132 // Call raycasting function
133 //window->RayCast(x, y);
134
135 // Updating widgets.
136 SWidgetManager::getSingleton().InjectMouseUp(window, x, y, MOUSE_LEFT_BUTTON);
137
138 //for touch
139 SWidgetManager::getSingleton().InjectMouseMove(window, x, y, 0);
140
141 break;
142 }
143
144 case WM_LBUTTONDBLCLK:
145 {
146 int x = (int)GET_X_LPARAM(lParam);
147 int y = (int)GET_Y_LPARAM(lParam);
148
149 //for touch
150 SWidgetManager::getSingleton().InjectMouseMove(window, x, y, 0);
151
152 // Call raycasting function
153 //window->RayCast(x, y);
154
155 // Updating widgets.
156 SWidgetManager::getSingleton().InjectMouseDown(window, x, y, MOUSE_LEFT_BUTTON);
157 SWidgetManager::getSingleton().InjectMouseUp(window, x, y, MOUSE_LEFT_BUTTON);
158 break;
159 }
160
161 case WM_RBUTTONDOWN:
162 {
163 int x = (int)GET_X_LPARAM(lParam);
164 int y = (int)GET_Y_LPARAM(lParam);
165
166 //for touch
167 SWidgetManager::getSingleton().InjectMouseMove(window, x, y, 0);
168
169 // Call raycasting function
170 //window->RayCast(x, y);
171
172 // Updating widgets.
173 SWidgetManager::getSingleton().InjectMouseDown(window, x, y, MOUSE_RIGHT_BUTTON);
174 break;
175 }
176
177 case WM_RBUTTONUP:
178 {
179 int x = (int)GET_X_LPARAM(lParam);
180 int y = (int)GET_Y_LPARAM(lParam);
181
182 // Call raycasting function
183 //window->RayCast(x, y);
184
185 // Updating widgets.
186 SWidgetManager::getSingleton().InjectMouseUp(window, x, y, MOUSE_RIGHT_BUTTON);
187
188 //for touch
189 SWidgetManager::getSingleton().InjectMouseMove(window, x, y, 0);
190 break;
191 }
192
193 case WM_RBUTTONDBLCLK:
194 {
195 int x = (int)GET_X_LPARAM(lParam);
196 int y = (int)GET_Y_LPARAM(lParam);
197
198 //for touch
199 SWidgetManager::getSingleton().InjectMouseMove(window, x, y, 0);
200
201 // Call raycasting function
202 //window->RayCast(x, y);
203
204 // Updating widgets.
205 SWidgetManager::getSingleton().InjectMouseDown(window, x, y, MOUSE_RIGHT_BUTTON);
206 SWidgetManager::getSingleton().InjectMouseUp(window, x, y, MOUSE_RIGHT_BUTTON);
207 break;
208 }
209
210 case WM_MBUTTONDOWN:
211 {
212 int x = (int)GET_X_LPARAM(lParam);
213 int y = (int)GET_Y_LPARAM(lParam);
214
215 //for touch
216 SWidgetManager::getSingleton().InjectMouseMove(window, x, y, 0);
217
218 // Call raycasting function
219 //window->RayCast(x, y);
220
221 // Updating widgets.
222 SWidgetManager::getSingleton().InjectMouseDown(window, x, y, MOUSE_MIDDLE_BUTTON);
223 break;
224 }
225
226 case WM_MBUTTONUP:
227 {
228 int x = (int)GET_X_LPARAM(lParam);
229 int y = (int)GET_Y_LPARAM(lParam);
230
231 // Call raycasting function
232 //window->RayCast(x, y);
233
234 // Updating widgets.
235 SWidgetManager::getSingleton().InjectMouseUp(window, x, y, MOUSE_MIDDLE_BUTTON);
236
237 //for touch
238 SWidgetManager::getSingleton().InjectMouseMove(window, x, y, 0);
239 break;
240 }
241
242 case WM_MBUTTONDBLCLK:
243 {
244 int x = (int)GET_X_LPARAM(lParam);
245 int y = (int)GET_Y_LPARAM(lParam);
246
247 //for touch
248 SWidgetManager::getSingleton().InjectMouseMove(window, x, y, 0);
249
250 // Call raycasting function
251 //window->RayCast(x, y);
252
253 // Updating widgets.
254 SWidgetManager::getSingleton().InjectMouseDown(window, x, y, MOUSE_MIDDLE_BUTTON);
255 SWidgetManager::getSingleton().InjectMouseUp(window, x, y, MOUSE_MIDDLE_BUTTON);
256 break;
257 }
258
259 case WM_MOUSEMOVE:
260 {
261 int x = (int)GET_X_LPARAM(lParam);
262 int y = (int)GET_Y_LPARAM(lParam);
263
264 MouseButtonId btn = static_cast <MouseButtonId>(wParam&(MK_CONTROL | MK_LBUTTON | MK_MBUTTON | MK_RBUTTON | MK_SHIFT));
265
266 // Call raycasting function
267 //window->RayCast(x, y);
268
269 // Updating widgets.
270 SWidgetManager::getSingleton().InjectMouseMove(window, x, y, btn);
271 }*/
272
273 case WM_SETCURSOR:
274 {
276 if (focusedWidget != 0)
277 {
278 if (focusedWidget->GetMouseEnable())
279 {
280 HCURSOR newCursor = focusedWidget->GetCurrentMouseCursor();
281 if (newCursor != 0)
282 {
283 SetClassLongPtr(hwnd, GCLP_HCURSOR, static_cast<LONG>(reinterpret_cast<LONG_PTR>(newCursor)));
284 SetCursor(newCursor);
285
286 // We don't want that any other hook/windows proc modify the cursor
287 /*if(msg == WM_SETCURSOR)
288 stopFurtherProcessing = TRUE;*/
289 }
290 }
291 }
292 break;
293 }
294
295 /*case WM_MOUSEWHEEL:
296 {
297 int scroll = (int)GET_WHEEL_DELTA_WPARAM(wParam) / 120;
298 int x = (int)GET_X_LPARAM(lParam);
299 int y = (int)GET_Y_LPARAM(lParam);
300
301 SWidgetManager::getSingleton().InjectMouseWheel(window, x, y, scroll);
302 break;
303 }*/
304 }
305 }
306
307 // Does the handled message needs further processing?
308 return stopFurtherProcessing;
309#else
310 return 0;
311#endif
312 }
313
314#ifdef _WIN32
315 LRESULT CALLBACK GetMessageProcKeyBoardHook(UINT nCode, WPARAM wParam, LPARAM lParam)
316 {
317 if (nCode < 0)
318 return CallNextHookEx(0, nCode, wParam, lParam);
319
320 MSG* msg = (MSG*)lParam;
321 if (nCode == HC_ACTION)
322 {
323 if (wParam & PM_REMOVE)
324 SKeyboardHook::instance->handleHook(msg->message, msg->hwnd, msg->wParam, msg->lParam);
325 }
326
327 // Call next hooks even if we have disabled further processing (else some plugits based on those windows message will not work anymore).
328 // Return the next hook return value after cancelling the message.
329 return CallNextHookEx(0, nCode, wParam, lParam);
330 }
331
332 LRESULT CALLBACK GetProcKeyBoardHook(UINT nCode, WPARAM wParam, LPARAM lParam)
333 {
334 if (nCode < 0)
335 return CallNextHookEx(0, nCode, wParam, lParam);
336
337 CWPSTRUCT* msg = (CWPSTRUCT*)lParam;
338 if (nCode == HC_ACTION)
339 {
340 SKeyboardHook::instance->handleHook(msg->message, msg->hwnd, msg->wParam, msg->lParam);
341 }
342
343 return CallNextHookEx(0, nCode, wParam, lParam);
344 }
345#endif
346
347}
long LONG
Definition SO3Android.h:59
unsigned int UINT
Definition SO3Android.h:58
void * HCURSOR
Definition SO3Android.h:60
struct HINSTANCE__ * hInstance
static SKeyboardHook * instance
LONG handleHook(UINT msg, ScolWindowHandle hwnd, WPARAM wParam, LPARAM lParam)
SWindow * GetRenderWindow(const std::string &windowName)
Definition SO3Root.cpp:812
static SRoot & getSingleton()
Definition SO3Root.cpp:116
bool GetMouseEnable()
virtual HCURSOR GetCurrentMouseCursor()
void InjectKeyEvent(const UINT &msg, const ScolWindowHandle &hwnd, const WPARAM &wParam, const LPARAM &lParam)
static SWidgetManager & getSingleton()
void SetSizeDirty()
LRESULT CALLBACK GetProcKeyBoardHook(UINT nCode, WPARAM wParam, LPARAM lParam)
LRESULT CALLBACK GetMessageProcKeyBoardHook(UINT nCode, WPARAM wParam, LPARAM lParam)