b311480e |
1 | // Copyright (c) 1998-1999 Matra Datavision |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
d5f74e42 |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
b311480e |
14 | |
cf4bee7c |
15 | #if defined(_WIN32) |
16 | // include windows.h first to have all definitions available |
17 | #include <windows.h> |
18 | #endif |
7fd59977 |
19 | |
1ce0716b |
20 | #include <WNT_Window.hxx> |
21 | |
22 | #if defined(_WIN32) && !defined(OCCT_UWP) |
7fd59977 |
23 | |
7fd59977 |
24 | #include <Aspect_Convert.hxx> |
42cf5bc1 |
25 | #include <Aspect_WindowDefinitionError.hxx> |
26 | #include <Aspect_WindowError.hxx> |
d6fbb2ab |
27 | #include <Message.hxx> |
42cf5bc1 |
28 | #include <Standard_Type.hxx> |
ad03c234 |
29 | #include <TCollection_ExtendedString.hxx> |
42cf5bc1 |
30 | #include <WNT_WClass.hxx> |
7fd59977 |
31 | |
ad03c234 |
32 | IMPLEMENT_STANDARD_RTTIEXT(WNT_Window, Aspect_Window) |
f5f4ebd0 |
33 | |
eaf5c5e0 |
34 | // ======================================================================= |
35 | // function : WNT_Window |
36 | // purpose : |
37 | // ======================================================================= |
dc3fe572 |
38 | WNT_Window::WNT_Window (const Standard_CString theTitle, |
7fd59977 |
39 | const Handle(WNT_WClass)& theClass, |
40 | const WNT_Dword& theStyle, |
41 | const Standard_Integer thePxLeft, |
42 | const Standard_Integer thePxTop, |
43 | const Standard_Integer thePxWidth, |
44 | const Standard_Integer thePxHeight, |
45 | const Quantity_NameOfColor theBackColor, |
46 | const Aspect_Handle theParent, |
47 | const Aspect_Handle theMenu, |
48 | const Standard_Address theClientStruct) |
dc3fe572 |
49 | : Aspect_Window(), |
7fd59977 |
50 | aXLeft (thePxLeft), |
51 | aYTop (thePxTop), |
52 | aXRight (thePxLeft + thePxWidth), |
53 | aYBottom (thePxTop + thePxHeight), |
eaf5c5e0 |
54 | myWClass (theClass), |
55 | myIsForeign (Standard_False) |
7fd59977 |
56 | { |
7fd59977 |
57 | if (thePxWidth <= 0 || thePxHeight <= 0) |
58 | { |
9775fa61 |
59 | throw Aspect_WindowDefinitionError("Coordinate(s) out of range"); |
7fd59977 |
60 | } |
61 | |
ad03c234 |
62 | DWORD aStyle = theStyle; |
7fd59977 |
63 | if (theParent && !(theStyle & WS_CHILD)) |
64 | { |
ad03c234 |
65 | aStyle |= WS_CHILD | WS_CLIPSIBLINGS; |
7fd59977 |
66 | } |
67 | else if (!theParent && !(theStyle & WS_CLIPCHILDREN)) |
68 | { |
ad03c234 |
69 | aStyle |= WS_CLIPCHILDREN; |
7fd59977 |
70 | } |
71 | |
ad03c234 |
72 | // include decorations in the window dimensions to reproduce same behavior of Xw_Window |
7fe83417 |
73 | RECT aRect; |
74 | aRect.top = aYTop; |
75 | aRect.bottom = aYBottom; |
76 | aRect.left = aXLeft; |
77 | aRect.right = aXRight; |
ad03c234 |
78 | AdjustWindowRect (&aRect, aStyle, theMenu != NULL ? TRUE : FALSE); |
7fe83417 |
79 | aXLeft = aRect.left; |
80 | aYTop = aRect.top; |
81 | aXRight = aRect.right; |
82 | aYBottom = aRect.bottom; |
7fd59977 |
83 | |
ad03c234 |
84 | const TCollection_ExtendedString aTitleW (theTitle); |
85 | const TCollection_ExtendedString aClassNameW (myWClass->Name()); |
86 | myHWindow = CreateWindowW (aClassNameW.ToWideString(), aTitleW.ToWideString(), |
87 | aStyle, |
88 | aXLeft, aYTop, |
89 | (aXRight - aXLeft), (aYBottom - aYTop), |
90 | (HWND )theParent, |
91 | (HMENU )theMenu, |
92 | (HINSTANCE )myWClass->Instance(), |
93 | theClientStruct); |
7fd59977 |
94 | if (!myHWindow) |
95 | { |
9775fa61 |
96 | throw Aspect_WindowDefinitionError("Unable to create window"); |
7fd59977 |
97 | } |
98 | |
7fd59977 |
99 | myHParentWindow = theParent; |
7fd59977 |
100 | SetBackground (theBackColor); |
eaf5c5e0 |
101 | } |
dc3fe572 |
102 | |
eaf5c5e0 |
103 | // ======================================================================= |
104 | // function : WNT_Window |
105 | // purpose : |
106 | // ======================================================================= |
107 | WNT_Window::WNT_Window (const Aspect_Handle theHandle, |
108 | const Quantity_NameOfColor theBackColor) |
109 | : myIsForeign (Standard_True) |
110 | { |
111 | myHWindow = theHandle; |
112 | myHParentWindow = GetParent ((HWND )theHandle); |
7fd59977 |
113 | |
eaf5c5e0 |
114 | SetBackground (theBackColor); |
7fd59977 |
115 | |
eaf5c5e0 |
116 | WINDOWPLACEMENT aPlace; |
117 | aPlace.length = sizeof (WINDOWPLACEMENT); |
118 | ::GetWindowPlacement ((HWND )myHWindow, &aPlace); |
119 | |
120 | aXLeft = aPlace.rcNormalPosition.left; |
121 | aYTop = aPlace.rcNormalPosition.top; |
122 | aXRight = aPlace.rcNormalPosition.right; |
123 | aYBottom = aPlace.rcNormalPosition.bottom; |
7fd59977 |
124 | } |
125 | |
eaf5c5e0 |
126 | // ======================================================================= |
e6f550da |
127 | // function : ~WNT_Window |
eaf5c5e0 |
128 | // purpose : |
129 | // ======================================================================= |
e6f550da |
130 | WNT_Window::~WNT_Window() |
dc3fe572 |
131 | { |
eaf5c5e0 |
132 | if (myHWindow == NULL |
133 | || myIsForeign) |
134 | { |
135 | return; |
136 | } |
7fd59977 |
137 | |
eaf5c5e0 |
138 | DestroyWindow ((HWND )myHWindow); |
139 | myIsForeign = Standard_False; |
140 | } |
7fd59977 |
141 | |
eaf5c5e0 |
142 | // ======================================================================= |
143 | // function : SetCursor |
144 | // purpose : |
145 | // ======================================================================= |
146 | void WNT_Window::SetCursor (const Aspect_Handle theCursor) const |
147 | { |
ad03c234 |
148 | ::SetClassLongPtrW ((HWND )myHWindow, GCLP_HCURSOR, (LONG_PTR )theCursor); |
eaf5c5e0 |
149 | } |
7fd59977 |
150 | |
eaf5c5e0 |
151 | // ======================================================================= |
152 | // function : IsMapped |
153 | // purpose : |
154 | // ======================================================================= |
155 | Standard_Boolean WNT_Window::IsMapped() const |
dc3fe572 |
156 | { |
eaf5c5e0 |
157 | if (IsVirtual()) |
7fd59977 |
158 | { |
587630c5 |
159 | return Standard_True; |
7fd59977 |
160 | } |
161 | |
eaf5c5e0 |
162 | WINDOWPLACEMENT aPlace; |
163 | aPlace.length = sizeof (WINDOWPLACEMENT); |
164 | ::GetWindowPlacement ((HWND )myHWindow, &aPlace); |
165 | return !(aPlace.showCmd == SW_HIDE |
166 | || aPlace.showCmd == SW_MINIMIZE); |
167 | } |
dc3fe572 |
168 | |
eaf5c5e0 |
169 | // ======================================================================= |
170 | // function : Map |
171 | // purpose : |
172 | // ======================================================================= |
173 | void WNT_Window::Map() const |
174 | { |
175 | if (!IsVirtual()) |
176 | { |
177 | Map (SW_SHOW); |
7fd59977 |
178 | } |
eaf5c5e0 |
179 | } |
180 | |
181 | // ======================================================================= |
182 | // function : Map |
183 | // purpose : |
184 | // ======================================================================= |
185 | void WNT_Window::Map (const Standard_Integer theMapMode) const |
186 | { |
187 | if (IsVirtual()) |
188 | { |
7fd59977 |
189 | return; |
190 | } |
7fd59977 |
191 | |
eaf5c5e0 |
192 | ::ShowWindow ((HWND )myHWindow, theMapMode); |
193 | ::UpdateWindow ((HWND )myHWindow); |
194 | } |
7fd59977 |
195 | |
eaf5c5e0 |
196 | // ======================================================================= |
197 | // function : Unmap |
198 | // purpose : |
199 | // ======================================================================= |
200 | void WNT_Window::Unmap() const |
201 | { |
202 | Map (SW_HIDE); |
203 | } |
dc3fe572 |
204 | |
eaf5c5e0 |
205 | // ======================================================================= |
206 | // function : DoResize |
207 | // purpose : |
208 | // ======================================================================= |
1a5007a9 |
209 | Aspect_TypeOfResize WNT_Window::DoResize() |
dc3fe572 |
210 | { |
62e1beed |
211 | if (IsVirtual()) |
212 | { |
213 | return Aspect_TOR_UNKNOWN; |
214 | } |
215 | |
dc3fe572 |
216 | int mask = 0; |
217 | Aspect_TypeOfResize mode = Aspect_TOR_UNKNOWN; |
218 | WINDOWPLACEMENT wp; |
7fd59977 |
219 | |
dc3fe572 |
220 | wp.length = sizeof ( WINDOWPLACEMENT ); |
221 | GetWindowPlacement ( ( HWND )myHWindow, &wp ); |
7fd59977 |
222 | |
dc3fe572 |
223 | if (wp.showCmd != SW_SHOWMINIMIZED) |
224 | { |
7c65581d |
225 | if (Abs ((int )wp.rcNormalPosition.left - aXLeft ) > 2) mask |= 1; |
226 | if (Abs ((int )wp.rcNormalPosition.right - aXRight ) > 2) mask |= 2; |
227 | if (Abs ((int )wp.rcNormalPosition.top - aYTop ) > 2) mask |= 4; |
228 | if (Abs ((int )wp.rcNormalPosition.bottom - aYBottom) > 2) mask |= 8; |
dc3fe572 |
229 | |
230 | switch (mask) |
231 | { |
232 | case 0: |
233 | mode = Aspect_TOR_NO_BORDER; |
234 | break; |
235 | case 1: |
236 | mode = Aspect_TOR_LEFT_BORDER; |
237 | break; |
238 | case 2: |
239 | mode = Aspect_TOR_RIGHT_BORDER; |
240 | break; |
241 | case 4: |
242 | mode = Aspect_TOR_TOP_BORDER; |
243 | break; |
244 | case 5: |
245 | mode = Aspect_TOR_LEFT_AND_TOP_BORDER; |
246 | break; |
247 | case 6: |
248 | mode = Aspect_TOR_TOP_AND_RIGHT_BORDER; |
249 | break; |
250 | case 8: |
251 | mode = Aspect_TOR_BOTTOM_BORDER; |
252 | break; |
253 | case 9: |
254 | mode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; |
255 | break; |
256 | case 10: |
257 | mode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; |
258 | break; |
259 | default: |
260 | break; |
261 | } // end switch |
262 | |
1a5007a9 |
263 | aXLeft = wp.rcNormalPosition.left; |
264 | aXRight = wp.rcNormalPosition.right; |
265 | aYTop = wp.rcNormalPosition.top; |
266 | aYBottom = wp.rcNormalPosition.bottom; |
dc3fe572 |
267 | } |
7fd59977 |
268 | |
dc3fe572 |
269 | return mode; |
7fd59977 |
270 | } |
271 | |
eaf5c5e0 |
272 | // ======================================================================= |
273 | // function : Ratio |
274 | // purpose : |
275 | // ======================================================================= |
ee2be2a8 |
276 | Standard_Real WNT_Window::Ratio() const |
dc3fe572 |
277 | { |
62e1beed |
278 | if (IsVirtual()) |
279 | { |
ee2be2a8 |
280 | return Standard_Real(aXRight - aXLeft)/ Standard_Real(aYBottom - aYTop); |
62e1beed |
281 | } |
282 | |
283 | RECT aRect; |
284 | GetClientRect ((HWND )myHWindow, &aRect); |
ee2be2a8 |
285 | return Standard_Real(aRect.right - aRect.left) / Standard_Real(aRect.bottom - aRect.top); |
eaf5c5e0 |
286 | } |
7fd59977 |
287 | |
eaf5c5e0 |
288 | // ======================================================================= |
289 | // function : Position |
290 | // purpose : |
291 | // ======================================================================= |
292 | void WNT_Window::Position (Standard_Integer& theX1, Standard_Integer& theY1, |
293 | Standard_Integer& theX2, Standard_Integer& theY2) const |
294 | { |
62e1beed |
295 | if (IsVirtual()) |
296 | { |
297 | theX1 = aXLeft; |
298 | theX2 = aXRight; |
299 | theY1 = aYTop; |
300 | theY2 = aYBottom; |
301 | return; |
302 | } |
303 | |
eaf5c5e0 |
304 | RECT aRect; |
305 | ::GetClientRect ((HWND )myHWindow, &aRect); |
7fd59977 |
306 | |
eaf5c5e0 |
307 | POINT aPntLeft, aPntRight; |
308 | aPntLeft.x = aPntLeft.y = 0; |
309 | ::ClientToScreen ((HWND )myHWindow, &aPntLeft); |
310 | aPntRight.x = aRect.right; |
311 | aPntRight.y = aRect.bottom; |
312 | ::ClientToScreen ((HWND )myHWindow, &aPntRight); |
7fd59977 |
313 | |
eaf5c5e0 |
314 | if (myHParentWindow != NULL) |
7fd59977 |
315 | { |
eaf5c5e0 |
316 | ::ScreenToClient ((HWND )myHParentWindow, &aPntLeft); |
317 | ::ScreenToClient ((HWND )myHParentWindow, &aPntRight); |
7fd59977 |
318 | } |
319 | |
eaf5c5e0 |
320 | theX1 = aPntLeft.x; |
321 | theX2 = aPntRight.x; |
322 | theY1 = aPntLeft.y; |
323 | theY2 = aPntRight.y; |
324 | } |
7fd59977 |
325 | |
eaf5c5e0 |
326 | // ======================================================================= |
327 | // function : Size |
328 | // purpose : |
329 | // ======================================================================= |
330 | void WNT_Window::Size (Standard_Integer& theWidth, |
331 | Standard_Integer& theHeight) const |
332 | { |
62e1beed |
333 | if (IsVirtual()) |
334 | { |
335 | theWidth = aXRight - aXLeft; |
336 | theHeight = aYBottom - aYTop; |
337 | return; |
338 | } |
339 | |
eaf5c5e0 |
340 | RECT aRect; |
341 | ::GetClientRect ((HWND )myHWindow, &aRect); |
342 | theWidth = aRect.right; |
343 | theHeight = aRect.bottom; |
344 | } |
7fd59977 |
345 | |
eaf5c5e0 |
346 | // ======================================================================= |
347 | // function : SetPos |
348 | // purpose : |
349 | // ======================================================================= |
350 | void WNT_Window::SetPos (const Standard_Integer theX, const Standard_Integer theY, |
351 | const Standard_Integer theX1, const Standard_Integer theY1) |
352 | { |
353 | aXLeft = theX; |
354 | aYTop = theY; |
355 | aXRight = theX1; |
356 | aYBottom = theY1; |
357 | } |
1ce0716b |
358 | |
49582f9d |
359 | // ======================================================================= |
360 | // function : SetTitle |
361 | // purpose : |
362 | // ======================================================================= |
363 | void WNT_Window::SetTitle (const TCollection_AsciiString& theTitle) |
364 | { |
365 | const TCollection_ExtendedString aTitleW (theTitle); |
366 | SetWindowTextW ((HWND )myHWindow, aTitleW.ToWideString()); |
367 | } |
368 | |
8693dfd0 |
369 | // ======================================================================= |
370 | // function : InvalidateContent |
371 | // purpose : |
372 | // ======================================================================= |
373 | void WNT_Window::InvalidateContent (const Handle(Aspect_DisplayConnection)& ) |
374 | { |
375 | if (myHWindow != NULL) |
376 | { |
377 | ::InvalidateRect ((HWND )myHWindow, NULL, TRUE); |
378 | } |
379 | } |
380 | |
49582f9d |
381 | // ======================================================================= |
382 | // function : VirtualKeyFromNative |
383 | // purpose : |
384 | // ======================================================================= |
385 | Aspect_VKey WNT_Window::VirtualKeyFromNative (Standard_Integer theKey) |
386 | { |
387 | if (theKey >= Standard_Integer('0') |
388 | && theKey <= Standard_Integer('9')) |
389 | { |
390 | return Aspect_VKey((theKey - Standard_Integer('0')) + Aspect_VKey_0); |
391 | } |
392 | if (theKey >= Standard_Integer('A') |
393 | && theKey <= Standard_Integer('Z')) |
394 | { |
395 | // main latin alphabet keys |
396 | return Aspect_VKey((theKey - Standard_Integer('A')) + Aspect_VKey_A); |
397 | } |
398 | if (theKey >= VK_F1 |
399 | && theKey <= VK_F24) |
400 | { |
401 | // special keys |
402 | if (theKey <= VK_F12) |
403 | { |
404 | return Aspect_VKey((theKey - VK_F1) + Aspect_VKey_F1); |
405 | } |
406 | return Aspect_VKey_UNKNOWN; |
407 | } |
408 | if (theKey >= VK_NUMPAD0 |
409 | && theKey <= VK_NUMPAD9) |
410 | { |
411 | // numpad keys |
412 | return Aspect_VKey((theKey - VK_NUMPAD0) + Aspect_VKey_Numpad0); |
413 | } |
414 | |
415 | switch (theKey) |
416 | { |
417 | case VK_LBUTTON: |
418 | case VK_RBUTTON: |
419 | case VK_CANCEL: |
420 | case VK_MBUTTON: |
421 | case VK_XBUTTON1: |
422 | case VK_XBUTTON2: |
423 | return Aspect_VKey_UNKNOWN; |
424 | case VK_BACK: |
425 | return Aspect_VKey_Backspace; |
426 | case VK_TAB: |
427 | return Aspect_VKey_Tab; |
428 | case VK_CLEAR: |
429 | return Aspect_VKey_UNKNOWN; |
430 | case VK_RETURN: |
431 | return Aspect_VKey_Enter; |
432 | case VK_SHIFT: |
433 | return Aspect_VKey_Shift; |
434 | case VK_CONTROL: |
435 | return Aspect_VKey_Control; |
436 | case VK_MENU: |
437 | return Aspect_VKey_Alt; //Aspect_VKey_Menu; |
438 | case VK_PAUSE: |
439 | case VK_CAPITAL: |
440 | return Aspect_VKey_UNKNOWN; |
441 | case VK_ESCAPE: |
442 | return Aspect_VKey_Escape; |
443 | case VK_CONVERT: |
444 | case VK_NONCONVERT: |
445 | case VK_ACCEPT: |
446 | case VK_MODECHANGE: |
447 | return Aspect_VKey_UNKNOWN; |
448 | case VK_SPACE: |
449 | return Aspect_VKey_Space; |
450 | case VK_PRIOR: |
451 | return Aspect_VKey_PageUp; |
452 | case VK_NEXT: |
453 | return Aspect_VKey_PageDown; |
454 | case VK_END: |
455 | return Aspect_VKey_End; |
456 | case VK_HOME: |
457 | return Aspect_VKey_Home; |
458 | case VK_LEFT: |
459 | return Aspect_VKey_Left; |
460 | case VK_UP: |
461 | return Aspect_VKey_Up; |
462 | case VK_DOWN: |
463 | return Aspect_VKey_Down; |
464 | case VK_RIGHT: |
465 | return Aspect_VKey_Right; |
466 | case VK_SELECT: |
467 | case VK_PRINT: |
468 | case VK_EXECUTE: |
469 | case VK_SNAPSHOT: |
470 | return Aspect_VKey_UNKNOWN; |
471 | case VK_INSERT: |
472 | return Aspect_VKey_UNKNOWN; // Aspect_VKey_Insert |
473 | case VK_DELETE: |
474 | return Aspect_VKey_Delete; |
475 | case VK_HELP: |
476 | case VK_LWIN: |
477 | case VK_RWIN: |
478 | case VK_APPS: |
479 | case VK_SLEEP: |
480 | return Aspect_VKey_UNKNOWN; |
481 | case VK_MULTIPLY: |
482 | return Aspect_VKey_NumpadMultiply; |
483 | case VK_ADD: |
484 | return Aspect_VKey_NumpadAdd; |
485 | case VK_SEPARATOR: |
486 | case VK_DECIMAL: |
487 | return Aspect_VKey_UNKNOWN; |
488 | case VK_SUBTRACT: |
489 | return Aspect_VKey_NumpadSubtract; |
490 | case VK_DIVIDE: |
491 | return Aspect_VKey_NumpadDivide; |
492 | case VK_NUMLOCK: |
493 | return Aspect_VKey_Numlock; |
494 | case VK_SCROLL: |
495 | return Aspect_VKey_Scroll; |
496 | case VK_LSHIFT: |
497 | case VK_RSHIFT: |
498 | case VK_LCONTROL: |
499 | case VK_RCONTROL: |
500 | case VK_LMENU: |
501 | case VK_RMENU: |
502 | return Aspect_VKey_UNKNOWN; |
503 | case VK_BROWSER_BACK: |
504 | return Aspect_VKey_BrowserBack; |
505 | case VK_BROWSER_FORWARD: |
506 | return Aspect_VKey_BrowserForward; |
507 | case VK_BROWSER_REFRESH: |
508 | return Aspect_VKey_BrowserRefresh; |
509 | case VK_BROWSER_STOP: |
510 | return Aspect_VKey_BrowserStop; |
511 | case VK_BROWSER_SEARCH: |
512 | return Aspect_VKey_BrowserSearch; |
513 | case VK_BROWSER_FAVORITES: |
514 | return Aspect_VKey_BrowserFavorites; |
515 | case VK_BROWSER_HOME: |
516 | return Aspect_VKey_BrowserHome; |
517 | case VK_VOLUME_MUTE: |
518 | return Aspect_VKey_VolumeMute; |
519 | case VK_VOLUME_DOWN: |
520 | return Aspect_VKey_VolumeDown; |
521 | case VK_VOLUME_UP: |
522 | return Aspect_VKey_VolumeUp; |
523 | case VK_MEDIA_NEXT_TRACK: |
524 | return Aspect_VKey_MediaNextTrack; |
525 | case VK_MEDIA_PREV_TRACK: |
526 | return Aspect_VKey_MediaPreviousTrack; |
527 | case VK_MEDIA_STOP: |
528 | return Aspect_VKey_MediaStop; |
529 | case VK_MEDIA_PLAY_PAUSE: |
530 | return Aspect_VKey_MediaPlayPause; |
531 | case VK_OEM_1: |
532 | return Aspect_VKey_Semicolon; |
533 | case VK_OEM_PLUS: |
534 | return Aspect_VKey_Plus; |
535 | case VK_OEM_COMMA: |
536 | return Aspect_VKey_Comma; |
537 | case VK_OEM_MINUS: |
538 | return Aspect_VKey_Minus; |
539 | case VK_OEM_PERIOD: |
540 | return Aspect_VKey_Period; |
541 | case VK_OEM_2: |
542 | return Aspect_VKey_Slash; |
543 | case VK_OEM_3: |
544 | return Aspect_VKey_Tilde; |
545 | case VK_OEM_4: |
546 | return Aspect_VKey_BracketLeft; |
547 | case VK_OEM_5: |
548 | return Aspect_VKey_Backslash; |
549 | case VK_OEM_6: |
550 | return Aspect_VKey_BracketRight; |
551 | case VK_OEM_7: |
552 | return Aspect_VKey_Apostrophe; |
553 | } |
554 | return Aspect_VKey_UNKNOWN; |
555 | } |
556 | |
557 | // ======================================================================= |
558 | // function : MouseKeyFlagsFromEvent |
559 | // purpose : |
560 | // ======================================================================= |
561 | Aspect_VKeyFlags WNT_Window::MouseKeyFlagsFromEvent (WPARAM theKeys) |
562 | { |
563 | Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE; |
564 | if ((theKeys & MK_CONTROL) != 0) |
565 | { |
566 | aFlags |= Aspect_VKeyFlags_CTRL; |
567 | } |
568 | if ((theKeys & MK_SHIFT) != 0) |
569 | { |
570 | aFlags |= Aspect_VKeyFlags_SHIFT; |
571 | } |
572 | if (GetKeyState (VK_MENU) < 0) |
573 | { |
574 | aFlags |= Aspect_VKeyFlags_ALT; |
575 | } |
576 | return aFlags; |
577 | } |
578 | |
579 | // ======================================================================= |
580 | // function : MouseKeyFlagsAsync |
581 | // purpose : |
582 | // ======================================================================= |
583 | Aspect_VKeyFlags WNT_Window::MouseKeyFlagsAsync() |
584 | { |
585 | Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE; |
586 | if ((GetAsyncKeyState (VK_CONTROL) & 0x8000) != 0) |
587 | { |
588 | aFlags |= Aspect_VKeyFlags_CTRL; |
589 | } |
590 | if ((GetAsyncKeyState (VK_SHIFT) & 0x8000) != 0) |
591 | { |
592 | aFlags |= Aspect_VKeyFlags_SHIFT; |
593 | } |
594 | if ((GetAsyncKeyState (VK_MENU) & 0x8000) != 0) |
595 | { |
596 | aFlags |= Aspect_VKeyFlags_ALT; |
597 | } |
598 | return aFlags; |
599 | } |
600 | |
601 | // ======================================================================= |
602 | // function : MouseButtonsFromEvent |
603 | // purpose : |
604 | // ======================================================================= |
605 | Aspect_VKeyMouse WNT_Window::MouseButtonsFromEvent (WPARAM theKeys) |
606 | { |
607 | Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE; |
608 | if ((theKeys & MK_LBUTTON) != 0) |
609 | { |
610 | aButtons |= Aspect_VKeyMouse_LeftButton; |
611 | } |
612 | if ((theKeys & MK_MBUTTON) != 0) |
613 | { |
614 | aButtons |= Aspect_VKeyMouse_MiddleButton; |
615 | } |
616 | if ((theKeys & MK_RBUTTON) != 0) |
617 | { |
618 | aButtons |= Aspect_VKeyMouse_RightButton; |
619 | } |
620 | return aButtons; |
621 | } |
622 | |
623 | // ======================================================================= |
624 | // function : MouseButtonsAsync |
625 | // purpose : |
626 | // ======================================================================= |
627 | Aspect_VKeyMouse WNT_Window::MouseButtonsAsync() |
628 | { |
629 | Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE; |
630 | const bool isSwapped = GetSystemMetrics (SM_SWAPBUTTON) != 0; |
631 | |
632 | if ((GetAsyncKeyState (!isSwapped ? VK_LBUTTON : VK_RBUTTON) & 0x8000) != 0) |
633 | { |
634 | aButtons |= Aspect_VKeyMouse_LeftButton; |
635 | } |
636 | if ((GetAsyncKeyState (VK_MBUTTON) & 0x8000) != 0) |
637 | { |
638 | aButtons |= Aspect_VKeyMouse_MiddleButton; |
639 | } |
640 | if ((GetAsyncKeyState (!isSwapped ? VK_RBUTTON : VK_LBUTTON) & 0x8000) != 0) |
641 | { |
642 | aButtons |= Aspect_VKeyMouse_RightButton; |
643 | } |
644 | return aButtons; |
645 | } |
646 | |
d6fbb2ab |
647 | // ======================================================================= |
648 | // function : RegisterRawInputDevices |
649 | // purpose : |
650 | // ======================================================================= |
651 | int WNT_Window::RegisterRawInputDevices (unsigned int theRawDeviceMask) |
652 | { |
653 | if (IsVirtual() |
654 | || myHWindow == NULL) |
655 | { |
656 | return 0; |
657 | } |
658 | |
659 | // hidusage.h |
660 | enum HidUsagePage { THE_HID_USAGE_PAGE_GENERIC = 0x01 }; // HID_USAGE_PAGE_GENERIC |
661 | enum HidUsage |
662 | { |
663 | THE_HID_USAGE_GENERIC_MOUSE = 0x02, // HID_USAGE_GENERIC_MOUSE |
664 | THE_HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER = 0x08, // HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER |
665 | }; |
666 | |
667 | int aNbDevices = 0; |
668 | RAWINPUTDEVICE aRawInDevList[2]; |
669 | if ((theRawDeviceMask & RawInputMask_Mouse) != 0) |
670 | { |
671 | // mouse |
672 | RAWINPUTDEVICE& aRawMouse = aRawInDevList[aNbDevices++]; |
673 | aRawMouse.usUsagePage = THE_HID_USAGE_PAGE_GENERIC; |
674 | aRawMouse.usUsage = THE_HID_USAGE_GENERIC_MOUSE; |
675 | aRawMouse.dwFlags = RIDEV_INPUTSINK; |
676 | aRawMouse.hwndTarget = (HWND )myHWindow; |
677 | } |
678 | if ((theRawDeviceMask & RawInputMask_SpaceMouse) != 0) |
679 | { |
680 | // space mouse |
681 | RAWINPUTDEVICE& aRawSpace = aRawInDevList[aNbDevices++]; |
682 | aRawSpace.usUsagePage = THE_HID_USAGE_PAGE_GENERIC; |
683 | aRawSpace.usUsage = THE_HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER; |
684 | aRawSpace.dwFlags = 0; // RIDEV_DEVNOTIFY |
685 | aRawSpace.hwndTarget = (HWND )myHWindow; |
686 | } |
687 | |
688 | for (int aTryIter = aNbDevices; aTryIter > 0; --aTryIter) |
689 | { |
690 | if (::RegisterRawInputDevices (aRawInDevList, aTryIter, sizeof(aRawInDevList[0]))) |
691 | { |
692 | return aTryIter; |
693 | } |
694 | |
695 | Message::SendTrace (aRawInDevList[aTryIter - 1].usUsage == THE_HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER |
696 | ? "Warning: RegisterRawInputDevices() failed to register RAW multi-axis controller input" |
697 | : "Warning: RegisterRawInputDevices() failed to register RAW mouse input"); |
698 | } |
699 | return 0; |
700 | } |
701 | |
1ce0716b |
702 | #endif // _WIN32 |