Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/util/windows/win32/Win32Window.cpp
1693 views
1
//
2
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
7
// Win32Window.cpp: Implementation of OSWindow for Win32 (Windows)
8
9
#include "util/windows/win32/Win32Window.h"
10
11
#include <crtdbg.h>
12
#include <sstream>
13
14
#include "common/debug.h"
15
16
Key VirtualKeyCodeToKey(WPARAM key, LPARAM flags)
17
{
18
switch (key)
19
{
20
// Check the scancode to distinguish between left and right shift
21
case VK_SHIFT:
22
{
23
static unsigned int lShift = MapVirtualKey(VK_LSHIFT, MAPVK_VK_TO_VSC);
24
unsigned int scancode = static_cast<unsigned int>((flags & (0xFF << 16)) >> 16);
25
return scancode == lShift ? KEY_LSHIFT : KEY_RSHIFT;
26
}
27
28
// Check the "extended" flag to distinguish between left and right alt
29
case VK_MENU:
30
return (HIWORD(flags) & KF_EXTENDED) ? KEY_RALT : KEY_LALT;
31
32
// Check the "extended" flag to distinguish between left and right control
33
case VK_CONTROL:
34
return (HIWORD(flags) & KF_EXTENDED) ? KEY_RCONTROL : KEY_LCONTROL;
35
36
// Other keys are reported properly
37
case VK_LWIN:
38
return KEY_LSYSTEM;
39
case VK_RWIN:
40
return KEY_RSYSTEM;
41
case VK_APPS:
42
return KEY_MENU;
43
case VK_OEM_1:
44
return KEY_SEMICOLON;
45
case VK_OEM_2:
46
return KEY_SLASH;
47
case VK_OEM_PLUS:
48
return KEY_EQUAL;
49
case VK_OEM_MINUS:
50
return KEY_DASH;
51
case VK_OEM_4:
52
return KEY_LBRACKET;
53
case VK_OEM_6:
54
return KEY_RBRACKET;
55
case VK_OEM_COMMA:
56
return KEY_COMMA;
57
case VK_OEM_PERIOD:
58
return KEY_PERIOD;
59
case VK_OEM_7:
60
return KEY_QUOTE;
61
case VK_OEM_5:
62
return KEY_BACKSLASH;
63
case VK_OEM_3:
64
return KEY_TILDE;
65
case VK_ESCAPE:
66
return KEY_ESCAPE;
67
case VK_SPACE:
68
return KEY_SPACE;
69
case VK_RETURN:
70
return KEY_RETURN;
71
case VK_BACK:
72
return KEY_BACK;
73
case VK_TAB:
74
return KEY_TAB;
75
case VK_PRIOR:
76
return KEY_PAGEUP;
77
case VK_NEXT:
78
return KEY_PAGEDOWN;
79
case VK_END:
80
return KEY_END;
81
case VK_HOME:
82
return KEY_HOME;
83
case VK_INSERT:
84
return KEY_INSERT;
85
case VK_DELETE:
86
return KEY_DELETE;
87
case VK_ADD:
88
return KEY_ADD;
89
case VK_SUBTRACT:
90
return KEY_SUBTRACT;
91
case VK_MULTIPLY:
92
return KEY_MULTIPLY;
93
case VK_DIVIDE:
94
return KEY_DIVIDE;
95
case VK_PAUSE:
96
return KEY_PAUSE;
97
case VK_F1:
98
return KEY_F1;
99
case VK_F2:
100
return KEY_F2;
101
case VK_F3:
102
return KEY_F3;
103
case VK_F4:
104
return KEY_F4;
105
case VK_F5:
106
return KEY_F5;
107
case VK_F6:
108
return KEY_F6;
109
case VK_F7:
110
return KEY_F7;
111
case VK_F8:
112
return KEY_F8;
113
case VK_F9:
114
return KEY_F9;
115
case VK_F10:
116
return KEY_F10;
117
case VK_F11:
118
return KEY_F11;
119
case VK_F12:
120
return KEY_F12;
121
case VK_F13:
122
return KEY_F13;
123
case VK_F14:
124
return KEY_F14;
125
case VK_F15:
126
return KEY_F15;
127
case VK_LEFT:
128
return KEY_LEFT;
129
case VK_RIGHT:
130
return KEY_RIGHT;
131
case VK_UP:
132
return KEY_UP;
133
case VK_DOWN:
134
return KEY_DOWN;
135
case VK_NUMPAD0:
136
return KEY_NUMPAD0;
137
case VK_NUMPAD1:
138
return KEY_NUMPAD1;
139
case VK_NUMPAD2:
140
return KEY_NUMPAD2;
141
case VK_NUMPAD3:
142
return KEY_NUMPAD3;
143
case VK_NUMPAD4:
144
return KEY_NUMPAD4;
145
case VK_NUMPAD5:
146
return KEY_NUMPAD5;
147
case VK_NUMPAD6:
148
return KEY_NUMPAD6;
149
case VK_NUMPAD7:
150
return KEY_NUMPAD7;
151
case VK_NUMPAD8:
152
return KEY_NUMPAD8;
153
case VK_NUMPAD9:
154
return KEY_NUMPAD9;
155
case 'A':
156
return KEY_A;
157
case 'Z':
158
return KEY_Z;
159
case 'E':
160
return KEY_E;
161
case 'R':
162
return KEY_R;
163
case 'T':
164
return KEY_T;
165
case 'Y':
166
return KEY_Y;
167
case 'U':
168
return KEY_U;
169
case 'I':
170
return KEY_I;
171
case 'O':
172
return KEY_O;
173
case 'P':
174
return KEY_P;
175
case 'Q':
176
return KEY_Q;
177
case 'S':
178
return KEY_S;
179
case 'D':
180
return KEY_D;
181
case 'F':
182
return KEY_F;
183
case 'G':
184
return KEY_G;
185
case 'H':
186
return KEY_H;
187
case 'J':
188
return KEY_J;
189
case 'K':
190
return KEY_K;
191
case 'L':
192
return KEY_L;
193
case 'M':
194
return KEY_M;
195
case 'W':
196
return KEY_W;
197
case 'X':
198
return KEY_X;
199
case 'C':
200
return KEY_C;
201
case 'V':
202
return KEY_V;
203
case 'B':
204
return KEY_B;
205
case 'N':
206
return KEY_N;
207
case '0':
208
return KEY_NUM0;
209
case '1':
210
return KEY_NUM1;
211
case '2':
212
return KEY_NUM2;
213
case '3':
214
return KEY_NUM3;
215
case '4':
216
return KEY_NUM4;
217
case '5':
218
return KEY_NUM5;
219
case '6':
220
return KEY_NUM6;
221
case '7':
222
return KEY_NUM7;
223
case '8':
224
return KEY_NUM8;
225
case '9':
226
return KEY_NUM9;
227
}
228
229
return Key(0);
230
}
231
232
LRESULT CALLBACK Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
233
{
234
switch (message)
235
{
236
case WM_NCCREATE:
237
{
238
LPCREATESTRUCT pCreateStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
239
SetWindowLongPtr(hWnd, GWLP_USERDATA,
240
reinterpret_cast<LONG_PTR>(pCreateStruct->lpCreateParams));
241
return DefWindowProcA(hWnd, message, wParam, lParam);
242
}
243
}
244
245
Win32Window *window = reinterpret_cast<Win32Window *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
246
if (window)
247
{
248
switch (message)
249
{
250
case WM_DESTROY:
251
case WM_CLOSE:
252
{
253
Event event;
254
event.Type = Event::EVENT_CLOSED;
255
window->pushEvent(event);
256
break;
257
}
258
259
case WM_MOVE:
260
{
261
RECT winRect;
262
GetClientRect(hWnd, &winRect);
263
264
POINT topLeft;
265
topLeft.x = winRect.left;
266
topLeft.y = winRect.top;
267
ClientToScreen(hWnd, &topLeft);
268
269
Event event;
270
event.Type = Event::EVENT_MOVED;
271
event.Move.X = topLeft.x;
272
event.Move.Y = topLeft.y;
273
window->pushEvent(event);
274
275
break;
276
}
277
278
case WM_SIZE:
279
{
280
if (window->mIgnoreSizeEvents)
281
break;
282
283
RECT winRect;
284
GetClientRect(hWnd, &winRect);
285
286
POINT topLeft;
287
topLeft.x = winRect.left;
288
topLeft.y = winRect.top;
289
ClientToScreen(hWnd, &topLeft);
290
291
POINT botRight;
292
botRight.x = winRect.right;
293
botRight.y = winRect.bottom;
294
ClientToScreen(hWnd, &botRight);
295
296
Event event;
297
event.Type = Event::EVENT_RESIZED;
298
event.Size.Width = botRight.x - topLeft.x;
299
event.Size.Height = botRight.y - topLeft.y;
300
window->pushEvent(event);
301
302
break;
303
}
304
305
case WM_SETFOCUS:
306
{
307
Event event;
308
event.Type = Event::EVENT_GAINED_FOCUS;
309
window->pushEvent(event);
310
break;
311
}
312
313
case WM_KILLFOCUS:
314
{
315
Event event;
316
event.Type = Event::EVENT_LOST_FOCUS;
317
window->pushEvent(event);
318
break;
319
}
320
321
case WM_KEYDOWN:
322
case WM_SYSKEYDOWN:
323
case WM_KEYUP:
324
case WM_SYSKEYUP:
325
{
326
bool down = (message == WM_KEYDOWN || message == WM_SYSKEYDOWN);
327
328
Event event;
329
event.Type = down ? Event::EVENT_KEY_PRESSED : Event::EVENT_KEY_RELEASED;
330
event.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
331
event.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
332
event.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
333
event.Key.System =
334
HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN));
335
event.Key.Code = VirtualKeyCodeToKey(wParam, lParam);
336
window->pushEvent(event);
337
338
break;
339
}
340
341
case WM_MOUSEWHEEL:
342
{
343
Event event;
344
event.Type = Event::EVENT_MOUSE_WHEEL_MOVED;
345
event.MouseWheel.Delta = static_cast<short>(HIWORD(wParam)) / 120;
346
window->pushEvent(event);
347
break;
348
}
349
350
case WM_LBUTTONDOWN:
351
case WM_LBUTTONDBLCLK:
352
{
353
Event event;
354
event.Type = Event::EVENT_MOUSE_BUTTON_PRESSED;
355
event.MouseButton.Button = MOUSEBUTTON_LEFT;
356
event.MouseButton.X = static_cast<short>(LOWORD(lParam));
357
event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
358
window->pushEvent(event);
359
break;
360
}
361
362
case WM_LBUTTONUP:
363
{
364
Event event;
365
event.Type = Event::EVENT_MOUSE_BUTTON_RELEASED;
366
event.MouseButton.Button = MOUSEBUTTON_LEFT;
367
event.MouseButton.X = static_cast<short>(LOWORD(lParam));
368
event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
369
window->pushEvent(event);
370
break;
371
}
372
373
case WM_RBUTTONDOWN:
374
case WM_RBUTTONDBLCLK:
375
{
376
Event event;
377
event.Type = Event::EVENT_MOUSE_BUTTON_PRESSED;
378
event.MouseButton.Button = MOUSEBUTTON_RIGHT;
379
event.MouseButton.X = static_cast<short>(LOWORD(lParam));
380
event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
381
window->pushEvent(event);
382
break;
383
}
384
385
// Mouse right button up event
386
case WM_RBUTTONUP:
387
{
388
Event event;
389
event.Type = Event::EVENT_MOUSE_BUTTON_RELEASED;
390
event.MouseButton.Button = MOUSEBUTTON_RIGHT;
391
event.MouseButton.X = static_cast<short>(LOWORD(lParam));
392
event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
393
window->pushEvent(event);
394
break;
395
}
396
397
// Mouse wheel button down event
398
case WM_MBUTTONDOWN:
399
case WM_MBUTTONDBLCLK:
400
{
401
Event event;
402
event.Type = Event::EVENT_MOUSE_BUTTON_PRESSED;
403
event.MouseButton.Button = MOUSEBUTTON_MIDDLE;
404
event.MouseButton.X = static_cast<short>(LOWORD(lParam));
405
event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
406
window->pushEvent(event);
407
break;
408
}
409
410
// Mouse wheel button up event
411
case WM_MBUTTONUP:
412
{
413
Event event;
414
event.Type = Event::EVENT_MOUSE_BUTTON_RELEASED;
415
event.MouseButton.Button = MOUSEBUTTON_MIDDLE;
416
event.MouseButton.X = static_cast<short>(LOWORD(lParam));
417
event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
418
window->pushEvent(event);
419
break;
420
}
421
422
// Mouse X button down event
423
case WM_XBUTTONDOWN:
424
case WM_XBUTTONDBLCLK:
425
{
426
Event event;
427
event.Type = Event::EVENT_MOUSE_BUTTON_PRESSED;
428
event.MouseButton.Button =
429
(HIWORD(wParam) == XBUTTON1) ? MOUSEBUTTON_BUTTON4 : MOUSEBUTTON_BUTTON5;
430
event.MouseButton.X = static_cast<short>(LOWORD(lParam));
431
event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
432
window->pushEvent(event);
433
break;
434
}
435
436
// Mouse X button up event
437
case WM_XBUTTONUP:
438
{
439
Event event;
440
event.Type = Event::EVENT_MOUSE_BUTTON_RELEASED;
441
event.MouseButton.Button =
442
(HIWORD(wParam) == XBUTTON1) ? MOUSEBUTTON_BUTTON4 : MOUSEBUTTON_BUTTON5;
443
event.MouseButton.X = static_cast<short>(LOWORD(lParam));
444
event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
445
window->pushEvent(event);
446
break;
447
}
448
449
case WM_MOUSEMOVE:
450
{
451
if (!window->mIsMouseInWindow)
452
{
453
window->mIsMouseInWindow = true;
454
Event event;
455
event.Type = Event::EVENT_MOUSE_ENTERED;
456
window->pushEvent(event);
457
}
458
459
int mouseX = static_cast<short>(LOWORD(lParam));
460
int mouseY = static_cast<short>(HIWORD(lParam));
461
462
Event event;
463
event.Type = Event::EVENT_MOUSE_MOVED;
464
event.MouseMove.X = mouseX;
465
event.MouseMove.Y = mouseY;
466
window->pushEvent(event);
467
break;
468
}
469
470
case WM_MOUSELEAVE:
471
{
472
Event event;
473
event.Type = Event::EVENT_MOUSE_LEFT;
474
window->pushEvent(event);
475
window->mIsMouseInWindow = false;
476
break;
477
}
478
479
case WM_USER:
480
{
481
Event testEvent;
482
testEvent.Type = Event::EVENT_TEST;
483
window->pushEvent(testEvent);
484
break;
485
}
486
}
487
}
488
return DefWindowProcA(hWnd, message, wParam, lParam);
489
}
490
491
Win32Window::Win32Window()
492
: mIsVisible(false),
493
mIsMouseInWindow(false),
494
mNativeWindow(0),
495
mParentWindow(0),
496
mNativeDisplay(0)
497
{}
498
499
Win32Window::~Win32Window()
500
{
501
destroy();
502
}
503
504
bool Win32Window::initializeImpl(const std::string &name, int width, int height)
505
{
506
destroy();
507
508
// Use a new window class name for ever window to ensure that a new window can be created
509
// even if the last one was not properly destroyed
510
static size_t windowIdx = 0;
511
std::ostringstream nameStream;
512
nameStream << name << "_" << windowIdx++;
513
514
mParentClassName = nameStream.str();
515
mChildClassName = mParentClassName + "_Child";
516
517
// Work around compile error from not defining "UNICODE" while Chromium does
518
const LPSTR idcArrow = MAKEINTRESOURCEA(32512);
519
520
WNDCLASSEXA parentWindowClass = {};
521
parentWindowClass.cbSize = sizeof(WNDCLASSEXA);
522
parentWindowClass.style = 0;
523
parentWindowClass.lpfnWndProc = WndProc;
524
parentWindowClass.cbClsExtra = 0;
525
parentWindowClass.cbWndExtra = 0;
526
parentWindowClass.hInstance = GetModuleHandle(nullptr);
527
parentWindowClass.hIcon = nullptr;
528
parentWindowClass.hCursor = LoadCursorA(nullptr, idcArrow);
529
parentWindowClass.hbrBackground = 0;
530
parentWindowClass.lpszMenuName = nullptr;
531
parentWindowClass.lpszClassName = mParentClassName.c_str();
532
if (!RegisterClassExA(&parentWindowClass))
533
{
534
return false;
535
}
536
537
WNDCLASSEXA childWindowClass = {};
538
childWindowClass.cbSize = sizeof(WNDCLASSEXA);
539
childWindowClass.style = CS_OWNDC;
540
childWindowClass.lpfnWndProc = WndProc;
541
childWindowClass.cbClsExtra = 0;
542
childWindowClass.cbWndExtra = 0;
543
childWindowClass.hInstance = GetModuleHandle(nullptr);
544
childWindowClass.hIcon = nullptr;
545
childWindowClass.hCursor = LoadCursorA(nullptr, idcArrow);
546
childWindowClass.hbrBackground = 0;
547
childWindowClass.lpszMenuName = nullptr;
548
childWindowClass.lpszClassName = mChildClassName.c_str();
549
if (!RegisterClassExA(&childWindowClass))
550
{
551
return false;
552
}
553
554
DWORD parentStyle = WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;
555
DWORD parentExtendedStyle = WS_EX_APPWINDOW | WS_EX_TOOLWINDOW;
556
557
RECT sizeRect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
558
AdjustWindowRectEx(&sizeRect, parentStyle, FALSE, parentExtendedStyle);
559
560
mParentWindow = CreateWindowExA(parentExtendedStyle, mParentClassName.c_str(), name.c_str(),
561
parentStyle, CW_USEDEFAULT, CW_USEDEFAULT,
562
sizeRect.right - sizeRect.left, sizeRect.bottom - sizeRect.top,
563
nullptr, nullptr, GetModuleHandle(nullptr), this);
564
565
mNativeWindow = CreateWindowExA(0, mChildClassName.c_str(), name.c_str(), WS_CHILD, 0, 0,
566
static_cast<int>(width), static_cast<int>(height),
567
mParentWindow, nullptr, GetModuleHandle(nullptr), this);
568
569
mNativeDisplay = GetDC(mNativeWindow);
570
if (!mNativeDisplay)
571
{
572
destroy();
573
return false;
574
}
575
576
return true;
577
}
578
579
void Win32Window::disableErrorMessageDialog()
580
{
581
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
582
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
583
}
584
585
void Win32Window::destroy()
586
{
587
if (mNativeDisplay)
588
{
589
ReleaseDC(mNativeWindow, mNativeDisplay);
590
mNativeDisplay = 0;
591
}
592
593
if (mNativeWindow)
594
{
595
DestroyWindow(mNativeWindow);
596
mNativeWindow = 0;
597
}
598
599
if (mParentWindow)
600
{
601
DestroyWindow(mParentWindow);
602
mParentWindow = 0;
603
}
604
605
UnregisterClassA(mParentClassName.c_str(), nullptr);
606
UnregisterClassA(mChildClassName.c_str(), nullptr);
607
}
608
609
bool Win32Window::takeScreenshot(uint8_t *pixelData)
610
{
611
if (mIsVisible)
612
{
613
return false;
614
}
615
616
bool error = false;
617
618
// Hack for DWM: There is no way to wait for DWM animations to finish, so we just have to wait
619
// for a while before issuing screenshot if window was just made visible.
620
{
621
static const double WAIT_WINDOW_VISIBLE_MS = 0.5; // Half a second for the animation
622
double timeSinceVisible = mSetVisibleTimer.getElapsedTime();
623
624
if (timeSinceVisible < WAIT_WINDOW_VISIBLE_MS)
625
{
626
Sleep(static_cast<DWORD>((WAIT_WINDOW_VISIBLE_MS - timeSinceVisible) * 1000));
627
}
628
}
629
630
HDC screenDC = nullptr;
631
HDC windowDC = nullptr;
632
HDC tmpDC = nullptr;
633
HBITMAP tmpBitmap = nullptr;
634
635
if (!error)
636
{
637
screenDC = GetDC(HWND_DESKTOP);
638
error = screenDC == nullptr;
639
}
640
641
if (!error)
642
{
643
windowDC = GetDC(mNativeWindow);
644
error = windowDC == nullptr;
645
}
646
647
if (!error)
648
{
649
tmpDC = CreateCompatibleDC(screenDC);
650
error = tmpDC == nullptr;
651
}
652
653
if (!error)
654
{
655
tmpBitmap = CreateCompatibleBitmap(screenDC, mWidth, mHeight);
656
error = tmpBitmap == nullptr;
657
}
658
659
POINT topLeft = {0, 0};
660
if (!error)
661
{
662
error = (MapWindowPoints(mNativeWindow, HWND_DESKTOP, &topLeft, 1) == 0);
663
}
664
665
if (!error)
666
{
667
error = SelectObject(tmpDC, tmpBitmap) == nullptr;
668
}
669
670
if (!error)
671
{
672
error = BitBlt(tmpDC, 0, 0, mWidth, mHeight, screenDC, topLeft.x, topLeft.y, SRCCOPY) == 0;
673
}
674
675
if (!error)
676
{
677
BITMAPINFOHEADER bitmapInfo;
678
bitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
679
bitmapInfo.biWidth = mWidth;
680
bitmapInfo.biHeight = -mHeight;
681
bitmapInfo.biPlanes = 1;
682
bitmapInfo.biBitCount = 32;
683
bitmapInfo.biCompression = BI_RGB;
684
bitmapInfo.biSizeImage = 0;
685
bitmapInfo.biXPelsPerMeter = 0;
686
bitmapInfo.biYPelsPerMeter = 0;
687
bitmapInfo.biClrUsed = 0;
688
bitmapInfo.biClrImportant = 0;
689
int getBitsResult = GetDIBits(screenDC, tmpBitmap, 0, mHeight, pixelData,
690
reinterpret_cast<BITMAPINFO *>(&bitmapInfo), DIB_RGB_COLORS);
691
error = (getBitsResult == 0);
692
}
693
694
if (tmpBitmap != nullptr)
695
{
696
DeleteObject(tmpBitmap);
697
}
698
if (tmpDC != nullptr)
699
{
700
DeleteDC(tmpDC);
701
}
702
if (screenDC != nullptr)
703
{
704
ReleaseDC(nullptr, screenDC);
705
}
706
if (windowDC != nullptr)
707
{
708
ReleaseDC(mNativeWindow, windowDC);
709
}
710
711
return !error;
712
}
713
714
void Win32Window::resetNativeWindow() {}
715
716
EGLNativeWindowType Win32Window::getNativeWindow() const
717
{
718
return mNativeWindow;
719
}
720
721
EGLNativeDisplayType Win32Window::getNativeDisplay() const
722
{
723
return mNativeDisplay;
724
}
725
726
void Win32Window::messageLoop()
727
{
728
MSG msg;
729
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
730
{
731
TranslateMessage(&msg);
732
DispatchMessage(&msg);
733
}
734
}
735
736
void Win32Window::setMousePosition(int x, int y)
737
{
738
RECT winRect;
739
GetClientRect(mNativeWindow, &winRect);
740
741
POINT topLeft;
742
topLeft.x = winRect.left;
743
topLeft.y = winRect.top;
744
ClientToScreen(mNativeWindow, &topLeft);
745
746
SetCursorPos(topLeft.x + x, topLeft.y + y);
747
}
748
749
bool Win32Window::setOrientation(int width, int height)
750
{
751
UNIMPLEMENTED();
752
return false;
753
}
754
755
bool Win32Window::setPosition(int x, int y)
756
{
757
if (mX == x && mY == y)
758
{
759
return true;
760
}
761
762
RECT windowRect;
763
if (!GetWindowRect(mParentWindow, &windowRect))
764
{
765
return false;
766
}
767
768
if (!MoveWindow(mParentWindow, x, y, windowRect.right - windowRect.left,
769
windowRect.bottom - windowRect.top, TRUE))
770
{
771
return false;
772
}
773
774
return true;
775
}
776
777
bool Win32Window::resize(int width, int height)
778
{
779
if (width == mWidth && height == mHeight)
780
{
781
return true;
782
}
783
784
RECT windowRect;
785
if (!GetWindowRect(mParentWindow, &windowRect))
786
{
787
return false;
788
}
789
790
RECT clientRect;
791
if (!GetClientRect(mParentWindow, &clientRect))
792
{
793
return false;
794
}
795
796
LONG diffX = (windowRect.right - windowRect.left) - clientRect.right;
797
LONG diffY = (windowRect.bottom - windowRect.top) - clientRect.bottom;
798
if (!MoveWindow(mParentWindow, windowRect.left, windowRect.top, width + diffX, height + diffY,
799
TRUE))
800
{
801
return false;
802
}
803
804
if (!MoveWindow(mNativeWindow, 0, 0, width, height, FALSE))
805
{
806
return false;
807
}
808
809
return true;
810
}
811
812
void Win32Window::setVisible(bool isVisible)
813
{
814
int flag = (isVisible ? SW_SHOW : SW_HIDE);
815
816
ShowWindow(mParentWindow, flag);
817
ShowWindow(mNativeWindow, flag);
818
819
if (isVisible)
820
{
821
mSetVisibleTimer.stop();
822
mSetVisibleTimer.start();
823
}
824
}
825
826
void Win32Window::pushEvent(Event event)
827
{
828
OSWindow::pushEvent(event);
829
830
switch (event.Type)
831
{
832
case Event::EVENT_RESIZED:
833
MoveWindow(mNativeWindow, 0, 0, mWidth, mHeight, FALSE);
834
break;
835
default:
836
break;
837
}
838
}
839
840
void Win32Window::signalTestEvent()
841
{
842
PostMessage(mNativeWindow, WM_USER, 0, 0);
843
}
844
845
// static
846
OSWindow *OSWindow::New()
847
{
848
return new Win32Window();
849
}
850
851