29#define WM_DPICHANGED 0x02E0
33#define WM_TOUCH 0x0240
37#define WM_MOUSEHWHEEL 0x020E
42#define TOUCH_COORD_TO_PIXEL(l) ((l) / 100)
47DECLARE_HANDLE(HTOUCHINPUT);
51TypeHandle WinGraphicsWindow::WinWindowHandle::_type_handle;
53WinGraphicsWindow::WindowHandles WinGraphicsWindow::_window_handles;
57bool WinGraphicsWindow::_cursor_hidden =
false;
59RECT WinGraphicsWindow::_mouse_unconfined_cliprect;
64bool WinGraphicsWindow::_got_saved_params =
false;
65int WinGraphicsWindow::_saved_mouse_trails;
66BOOL WinGraphicsWindow::_saved_cursor_shadow;
67BOOL WinGraphicsWindow::_saved_mouse_vanish;
73int WinGraphicsWindow::_window_class_index = 0;
75static const char *
const errorbox_title =
"Panda3D Error";
79typedef BOOL (WINAPI *PFN_REGISTERTOUCHWINDOW)(IN HWND hWnd, IN ULONG ulFlags);
80typedef BOOL (WINAPI *PFN_GETTOUCHINPUTINFO)(IN HTOUCHINPUT hTouchInput, IN UINT cInputs, OUT PTOUCHINPUT pInputs, IN
int cbSize);
81typedef BOOL (WINAPI *PFN_CLOSETOUCHINPUTHANDLE)(IN HTOUCHINPUT hTouchInput);
83static PFN_REGISTERTOUCHWINDOW pRegisterTouchWindow = 0;
84static PFN_GETTOUCHINPUTINFO pGetTouchInputInfo = 0;
85static PFN_CLOSETOUCHINPUTHANDLE pCloseTouchInputHandle = 0;
92 const std::string &name,
98 GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
100 initialize_input_devices();
104 _tracking_mouse_leaving =
false;
106 _lost_keypresses =
false;
107 _lshift_down =
false;
108 _rshift_down =
false;
109 _lcontrol_down =
false;
110 _rcontrol_down =
false;
121~WinGraphicsWindow() {
122 if (_window_handle !=
nullptr) {
123 DCAST(WinWindowHandle, _window_handle)->clear_window();
135 nassertr(device >= 0 && device < (
int)_input_devices.size(),
MouseData());
141 if (device == 0 && result._in_window && GetCursorPos(&cpos) && ScreenToClient(_hWnd, &cpos)) {
143 result._xpos = cpos.x;
144 result._ypos = cpos.y;
170 if (!_properties.get_foreground() )
181 SetCursorPos(view_rect.left + x, view_rect.top + y);
186 if ((device < 1)||(device >= (
int)_input_devices.size())) {
204 HIMC hIMC = ImmGetContext(_hWnd);
206 if (!ImmSetOpenStatus(hIMC,
false)) {
207 windisplay_cat.debug() <<
"ImmSetOpenStatus failed\n";
209 ImmReleaseContext(_hWnd, hIMC);
213 windisplay_cat.debug() <<
"success: closed ime window\n";
261 if (!disable_message_loop) {
264 while (PeekMessage(&msg,
nullptr, 0, 0, PM_NOREMOVE)) {
288 if (do_windowed_switch()) {
289 _properties.set_fullscreen(
false);
292 windisplay_cat.warning()
293 <<
"Switching to windowed mode failed!\n";
316 if (_parent_window_handle ==
nullptr) {
317 LPoint2i top_left = _properties.get_origin();
318 LPoint2i bottom_right = top_left + _properties.get_size();
320 DWORD window_style = make_style(_properties);
321 SetWindowLong(_hWnd, GWL_STYLE, window_style);
325 SetRect(&view_rect, top_left[0], top_left[1],
326 bottom_right[0], bottom_right[1]);
328 GetWindowInfo(_hWnd, &wi);
329 AdjustWindowRectEx(&view_rect, wi.dwStyle, FALSE, wi.dwExStyle);
332 SetWindowPos(_hWnd, HWND_NOTOPMOST, view_rect.left, view_rect.top,
333 view_rect.right - view_rect.left,
334 view_rect.bottom - view_rect.top,
335 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED |
336 SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
341 std::string title = properties.
get_title();
342 _properties.set_title(title);
345 SetWindowTextW(_hWnd, title_w.c_str());
352 ::SendMessage(_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)icon);
353 ::SendMessage(_hWnd, WM_SETICON, ICON_BIG, (LPARAM)icon);
362 _properties.set_cursor_hidden(hide_cursor);
363 if (_cursor_window ==
this) {
364 hide_or_show_cursor(hide_cursor);
372 _properties.set_cursor_filename(filename);
374 _cursor = get_cursor(filename);
376 _cursor = LoadCursor(
nullptr, IDC_ARROW);
379 if (_cursor_window ==
this) {
387 WindowProperties::ZOrder last_z_order = _properties.get_z_order();
389 adjust_z_order(last_z_order, properties.
get_z_order());
395 if (!SetActiveWindow(_hWnd)) {
396 windisplay_cat.warning()
397 <<
"SetForegroundWindow() failed!\n";
399 _properties.set_foreground(
true);
406 if (_properties.get_minimized() != properties.
get_minimized()) {
408 ShowWindow(_hWnd, SW_MINIMIZE);
410 ShowWindow(_hWnd, SW_RESTORE);
420 if (do_fullscreen_switch()){
421 _properties.set_fullscreen(
true);
424 windisplay_cat.warning()
425 <<
"Switching to fullscreen mode failed!\n";
430 if (properties.has_mouse_mode()) {
431 if (properties.
get_mouse_mode() != _properties.get_mouse_mode()) {
433 case WindowProperties::M_absolute:
434 case WindowProperties::M_relative:
436 if (_properties.get_mouse_mode() == WindowProperties::M_confined) {
438 windisplay_cat.info() <<
"Unconfining cursor from window\n";
440 _properties.set_mouse_mode(WindowProperties::M_absolute);
443 case WindowProperties::M_confined:
446 if (GetForegroundWindow() != _hWnd || confine_cursor()) {
447 _properties.set_mouse_mode(WindowProperties::M_confined);
461void WinGraphicsWindow::
463 GraphicsWindow::trigger_flip();
469 InvalidateRect(_hWnd,
nullptr, FALSE);
470 _got_expose_event =
false;
472 if (windisplay_cat.is_spam()) {
473 windisplay_cat.spam()
474 <<
"InvalidateRect: " <<
this <<
"\n";
482void WinGraphicsWindow::
484 set_cursor_out_of_window();
485 DestroyWindow(_hWnd);
487 if (_properties.has_mouse_mode() &&
488 _properties.get_mouse_mode() == WindowProperties::M_confined) {
494 do_fullscreen_disable();
498 _window_handles.erase(_hWnd);
501 GraphicsWindow::close_window();
508bool WinGraphicsWindow::
510 if (_properties.has_cursor_filename()) {
511 _cursor = get_cursor(_properties.get_cursor_filename());
514 _cursor = LoadCursor(
nullptr, IDC_ARROW);
516 bool want_foreground = (!_properties.has_foreground() || _properties.get_foreground());
517 bool want_minimized = (_properties.has_minimized() && _properties.get_minimized()) && !want_foreground;
519 HWND old_foreground_window = GetForegroundWindow();
524 _creating_window =
this;
525 bool opened = open_graphic_window();
526 _creating_window =
nullptr;
534 _window_handles.insert(WindowHandles::value_type(_hWnd,
this));
537 SetWindowPos(_hWnd, HWND_TOP, 0,0,0,0,
538 SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE);
541 if (want_minimized) {
542 ShowWindow(_hWnd, SW_MINIMIZE);
543 ShowWindow(_hWnd, SW_MINIMIZE);
545 ShowWindow(_hWnd, SW_SHOWNORMAL);
546 ShowWindow(_hWnd, SW_SHOWNORMAL);
549 HWND new_foreground_window = _hWnd;
550 if (!want_foreground) {
553 new_foreground_window = old_foreground_window;
556 if (!SetActiveWindow(new_foreground_window)) {
557 windisplay_cat.warning()
558 <<
"SetActiveWindow() failed!\n";
564 if (!SetForegroundWindow(new_foreground_window)) {
565 windisplay_cat.warning()
566 <<
"SetForegroundWindow() failed!\n";
572 HIMC hIMC = ImmGetContext(_hWnd);
574 _ime_open = (ImmGetOpenStatus(hIMC) != 0);
575 ImmReleaseContext(_hWnd, hIMC);
579 if (_input_devices.size() > 1) {
581 Rid.usUsagePage = 0x01;
584 Rid.hwndTarget = _hWnd;
585 RegisterRawInputDevices(&Rid, 1,
sizeof (Rid));
589 _window_handle = NativeWindowHandle::make_win(_hWnd);
592 _window_handle =
new WinWindowHandle(
this, *_window_handle);
595 if (_parent_window_handle !=
nullptr) {
596 _parent_window_handle->attach_child(_window_handle);
603 static bool initialized =
false;
606 HMODULE user32 = GetModuleHandleA(
"user32.dll");
609 pRegisterTouchWindow = (PFN_REGISTERTOUCHWINDOW)GetProcAddress(user32,
"RegisterTouchWindow");
610 pGetTouchInputInfo = (PFN_GETTOUCHINPUTINFO)GetProcAddress(user32,
"GetTouchInputInfo");
611 pCloseTouchInputHandle = (PFN_CLOSETOUCHINPUTHANDLE)GetProcAddress(user32,
"CloseTouchInputHandle");
616 if (pRegisterTouchWindow !=
nullptr) {
617 pRegisterTouchWindow(_hWnd, 0);
629void WinGraphicsWindow::
630initialize_input_devices() {
632 PRAWINPUTDEVICELIST pRawInputDeviceList;
634 nassertv(_input_devices.size() == 0);
637 memset(_input_device_handle, 0,
sizeof(_input_device_handle));
639 GraphicsWindowInputDevice::pointer_and_keyboard(
this,
"keyboard_mouse");
640 add_input_device(device);
644 if (GetRawInputDeviceList(
nullptr, &nInputDevices,
sizeof(RAWINPUTDEVICELIST)) != 0) {
649 pRawInputDeviceList = (PRAWINPUTDEVICELIST)alloca(
sizeof(RAWINPUTDEVICELIST) * nInputDevices);
650 if (pRawInputDeviceList==0) {
655 if (GetRawInputDeviceList(pRawInputDeviceList, &nInputDevices,
sizeof(RAWINPUTDEVICELIST)) == -1) {
660 for (
int i = 0; i < (int)nInputDevices; i++) {
661 if (pRawInputDeviceList[i].dwType == RIM_TYPEMOUSE) {
664 if (GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)0, &nSize) != 0) {
667 char *psName = (
char*)alloca(
sizeof(TCHAR) * nSize);
668 if (psName == 0)
return;
669 if (GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)psName, &nSize) < 0) {
674 if (strncmp(psName,
"\\??\\Root#RDP_MOU#0000#",22)!=0) {
675 if (_input_devices.size() < 32) {
676 if (strncmp(psName,
"\\??\\",4)==0) psName += 4;
677 char *pound1 = strchr(psName,
'#');
678 char *pound2 = pound1 ? strchr(pound1+1,
'#') : 0;
679 char *pound3 = pound2 ? strchr(pound2+1,
'#') : 0;
680 if (pound3) *pound3 = 0;
681 for (
char *p = psName; *p; p++) {
686 if (pound2) *pound2 =
'.';
687 _input_device_handle[_input_devices.size()] = pRawInputDeviceList[i].hDevice;
690 device->set_pointer_in_window(0, 0);
691 add_input_device(device);
704void WinGraphicsWindow::
714void WinGraphicsWindow::
724bool WinGraphicsWindow::
725do_reshape_request(
int x_origin,
int y_origin,
bool has_origin,
726 int x_size,
int y_size) {
727 if (windisplay_cat.is_debug()) {
728 windisplay_cat.debug()
729 <<
"Got reshape request (" << x_origin <<
", " << y_origin
730 <<
", " << has_origin <<
", " << x_size <<
", " << y_size <<
")\n";
735 if (x_origin == -2) {
736 x_origin = 0.5 * (_pipe->get_display_width() - x_size);
738 if (y_origin == -2) {
739 y_origin = 0.5 * (_pipe->get_display_height() - y_size);
741 _properties.set_origin(x_origin, y_origin);
743 if (x_origin == -1 && y_origin == -1) {
753 SetRect(&view_rect, x_origin, y_origin,
754 x_origin + x_size, y_origin + y_size);
756 GetWindowInfo(_hWnd, &wi);
757 AdjustWindowRectEx(&view_rect, wi.dwStyle, FALSE, wi.dwExStyle);
759 UINT flags = SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOACTIVATE;
762 x_origin = view_rect.left;
763 y_origin = view_rect.top;
765 x_origin = CW_USEDEFAULT;
766 y_origin = CW_USEDEFAULT;
770 SetWindowPos(_hWnd,
nullptr, x_origin, y_origin,
771 view_rect.right - view_rect.left,
772 view_rect.bottom - view_rect.top,
780 return do_fullscreen_resize(x_size, y_size);
787void WinGraphicsWindow::
790 if (!GetClientRect(_hWnd, &view_rect)) {
793 if (windisplay_cat.is_debug()) {
794 windisplay_cat.debug()
795 <<
"GetClientRect() failed in handle_reshape. Ignoring.\n";
802 if (view_rect.left == 0 && view_rect.right == 0 &&
803 view_rect.bottom == 0 && view_rect.top == 0) {
804 if (windisplay_cat.is_debug()) {
805 windisplay_cat.debug()
806 <<
"GetClientRect() returned all zeroes in handle_reshape. Ignoring.\n";
811 bool result = (FALSE != ClientToScreen(_hWnd, (POINT*)&view_rect.left));
813 result = (FALSE != ClientToScreen(_hWnd, (POINT*)&view_rect.right));
817 if (windisplay_cat.is_debug()) {
818 windisplay_cat.debug()
819 <<
"ClientToScreen() failed in handle_reshape. Ignoring.\n";
829 if (_properties.has_mouse_mode() &&
830 _properties.get_mouse_mode() == WindowProperties::M_confined &&
831 _hWnd == GetForegroundWindow()) {
834 if (GetCursorPos(&cpos) && PtInRect(&view_rect, cpos)) {
835 windisplay_cat.info()
836 <<
"ClipCursor() to " << view_rect.left <<
"," << view_rect.top
837 <<
" to " << view_rect.right <<
"," << view_rect.bottom << endl;
839 if (!ClipCursor(&view_rect)) {
840 windisplay_cat.warning()
841 <<
"Failed to re-confine cursor to window.\n";
847 properties.
set_size((view_rect.right - view_rect.left),
848 (view_rect.bottom - view_rect.top));
851 properties.
set_origin(view_rect.left, view_rect.top);
853 if (windisplay_cat.is_debug()) {
854 windisplay_cat.debug()
855 <<
"reshape to origin: (" << properties.
get_x_origin() <<
","
861 system_changed_properties(properties);
867bool WinGraphicsWindow::
868do_fullscreen_resize(
int x_size,
int y_size) {
869 HWND hDesktopWindow = GetDesktopWindow();
870 HDC scrnDC = GetDC(hDesktopWindow);
871 DWORD dwFullScreenBitDepth = GetDeviceCaps(scrnDC, BITSPIXEL);
872 ReleaseDC(hDesktopWindow, scrnDC);
880 if (!find_acceptable_display_mode(x_size, y_size,
881 dwFullScreenBitDepth, dm)) {
882 windisplay_cat.error()
883 <<
"window resize(" << x_size <<
", " << y_size
884 <<
") failed, no compatible fullscreen display mode found!\n";
889 SetWindowPos(_hWnd,
nullptr, 0,0, x_size, y_size,
890 SWP_NOZORDER | SWP_NOMOVE | SWP_NOSENDCHANGING);
891 int chg_result = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
893 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
894 windisplay_cat.error()
895 <<
"resize ChangeDisplaySettings failed (error code: "
896 << chg_result <<
") for specified res: "
897 << dm.dmPelsWidth <<
" x " << dm.dmPelsHeight
898 <<
" x " << dm.dmBitsPerPel <<
", "
899 << dm.dmDisplayFrequency <<
" Hz\n";
903 _fullscreen_display_mode = dm;
905 windisplay_cat.info()
906 <<
"Resized fullscreen window to " << x_size <<
", " << y_size
907 <<
" bitdepth " << dwFullScreenBitDepth <<
", "
908 << dm.dmDisplayFrequency <<
"Hz\n";
910 _properties.set_size(x_size, y_size);
919bool WinGraphicsWindow::
920do_fullscreen_switch() {
921 if (!do_fullscreen_enable()) {
927 props.set_fullscreen(
true);
928 DWORD window_style = make_style(props);
929 SetWindowLong(_hWnd, GWL_STYLE, window_style);
931 WINDOW_METRICS metrics;
933 if (!calculate_metrics(
true, window_style, metrics, has_origin)){
937 SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0, metrics.width, metrics.height,
938 SWP_FRAMECHANGED | SWP_SHOWWINDOW);
945bool WinGraphicsWindow::
946do_windowed_switch() {
947 do_fullscreen_disable();
950 props.set_fullscreen(
false);
951 DWORD window_style = make_style(props);
952 SetWindowLong(_hWnd, GWL_STYLE, window_style);
954 WINDOW_METRICS metrics;
957 if (!calculate_metrics(
false, window_style, metrics, has_origin)){
965 SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0,
966 metrics.width, metrics.height,
967 SWP_FRAMECHANGED | SWP_SHOWWINDOW);
970 if (_properties.has_mouse_mode() &&
971 _properties.get_mouse_mode() == WindowProperties::M_confined) {
982void WinGraphicsWindow::
983reconsider_fullscreen_size(DWORD &, DWORD &, DWORD &) {
992void WinGraphicsWindow::
993support_overlay_window(
bool) {
999DWORD WinGraphicsWindow::
1008 DWORD window_style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
1011 window_style |= WS_POPUP | WS_SYSMENU;
1013 else if (_parent_window_handle) {
1014 window_style |= WS_CHILD;
1017 window_style |= WS_POPUP;
1020 window_style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
1023 window_style |= (WS_SIZEBOX | WS_MAXIMIZEBOX);
1025 window_style |= WS_BORDER;
1029 return window_style;
1036bool WinGraphicsWindow::
1037calculate_metrics(
bool fullscreen, DWORD window_style, WINDOW_METRICS &metrics,
1041 has_origin = _properties.has_origin();
1042 if (!fullscreen && has_origin) {
1043 metrics.x = _properties.get_x_origin();
1044 metrics.y = _properties.get_y_origin();
1047 if (metrics.x == -2) {
1048 metrics.x = 0.5 * (_pipe->get_display_width() - _properties.get_x_size());
1050 if (metrics.y == -2) {
1051 metrics.y = 0.5 * (_pipe->get_display_height() - _properties.get_y_size());
1053 _properties.set_origin(metrics.x, metrics.y);
1055 if (metrics.x == -1 && metrics.y == -1) {
1062 metrics.width = _properties.get_x_size();
1063 metrics.height = _properties.get_y_size();
1067 SetRect(&win_rect, metrics.x, metrics.y,
1068 metrics.x + metrics.width, metrics.y + metrics.height);
1071 if (!AdjustWindowRect(&win_rect, window_style, FALSE)) {
1072 windisplay_cat.error()
1073 <<
"AdjustWindowRect failed!" << endl;
1078 metrics.x = win_rect.left;
1079 metrics.y = win_rect.top;
1081 metrics.x = CW_USEDEFAULT;
1082 metrics.y = CW_USEDEFAULT;
1084 metrics.width = win_rect.right - win_rect.left;
1085 metrics.height = win_rect.bottom - win_rect.top;
1094bool WinGraphicsWindow::
1095open_graphic_window() {
1096 DWORD window_style = make_style(_properties);
1099 if (_properties.has_title()) {
1101 title = encoder.
decode_text(_properties.get_title());
1104 if (!_properties.has_size()) {
1106 _properties.set_size(640, 480);
1109 WINDOW_METRICS metrics;
1111 if (!calculate_metrics(fullscreen, window_style, metrics, has_origin)){
1115 const WindowClass &wclass = register_window_class(_properties);
1116 HINSTANCE hinstance = GetModuleHandle(
nullptr);
1121 WindowHandle *window_handle = _properties.get_parent_window();
1122 if (window_handle !=
nullptr) {
1123 windisplay_cat.info()
1124 <<
"Got parent_window " << *window_handle <<
"\n";
1126 if (os_handle !=
nullptr) {
1127 windisplay_cat.info()
1128 <<
"os_handle type " << os_handle->get_type() <<
"\n";
1130 if (os_handle->
is_of_type(NativeWindowHandle::WinHandle::get_class_type())) {
1131 NativeWindowHandle::WinHandle *win_handle = DCAST(NativeWindowHandle::WinHandle, os_handle);
1132 _hparent = win_handle->get_handle();
1133 }
else if (os_handle->
is_of_type(NativeWindowHandle::IntHandle::get_class_type())) {
1135 _hparent = (HWND)int_handle->get_handle();
1139 _parent_window_handle = window_handle;
1141 _parent_window_handle =
nullptr;
1145 _hWnd = CreateWindowW(wclass._name.c_str(), title.c_str(), window_style,
1146 metrics.x, metrics.y,
1149 nullptr,
nullptr, hinstance, 0);
1154 if (!fullscreen && has_origin) {
1155 x_origin = _properties.get_x_origin();
1156 y_origin = _properties.get_y_origin();
1159 _hWnd = CreateWindowW(wclass._name.c_str(), title.c_str(),
1160 WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS ,
1162 _properties.get_x_size(), _properties.get_y_size(),
1163 _hparent,
nullptr, hinstance, 0);
1176 system_changed_properties(properties);
1181 windisplay_cat.error()
1182 <<
"CreateWindow() failed!" << endl;
1183 show_error_message();
1192 if (!do_fullscreen_enable()){
1204bool WinGraphicsWindow::
1205do_fullscreen_enable() {
1207 HWND hDesktopWindow = GetDesktopWindow();
1208 HDC scrnDC = GetDC(hDesktopWindow);
1209 DWORD cur_bitdepth = GetDeviceCaps(scrnDC, BITSPIXEL);
1213 ReleaseDC(hDesktopWindow, scrnDC);
1215 DWORD dwWidth = _properties.get_x_size();
1216 DWORD dwHeight = _properties.get_y_size();
1217 DWORD dwFullScreenBitDepth = cur_bitdepth;
1220 reconsider_fullscreen_size(dwWidth, dwHeight, dwFullScreenBitDepth);
1221 if (!find_acceptable_display_mode(dwWidth, dwHeight, dwFullScreenBitDepth, dm)) {
1222 windisplay_cat.error()
1223 <<
"Videocard has no supported display resolutions at specified res ("
1224 << dwWidth <<
" x " << dwHeight <<
" x " << dwFullScreenBitDepth <<
")\n";
1228 dm.dmPelsWidth = dwWidth;
1229 dm.dmPelsHeight = dwHeight;
1230 dm.dmBitsPerPel = dwFullScreenBitDepth;
1231 int chg_result = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
1233 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
1234 windisplay_cat.error()
1235 <<
"ChangeDisplaySettings failed (error code: "
1236 << chg_result <<
") for specified res: "
1237 << dm.dmPelsWidth <<
" x " << dm.dmPelsHeight
1238 <<
" x " << dm.dmBitsPerPel <<
", "
1239 << dm.dmDisplayFrequency <<
" Hz\n";
1243 _fullscreen_display_mode = dm;
1245 _properties.set_origin(0, 0);
1246 _properties.set_size(dwWidth, dwHeight);
1256bool WinGraphicsWindow::
1257do_fullscreen_disable() {
1258 int chg_result = ChangeDisplaySettings(
nullptr, 0x0);
1259 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
1260 windisplay_cat.warning()
1261 <<
"ChangeDisplaySettings failed to restore Windowed mode\n";
1270void WinGraphicsWindow::
1272 WindowProperties::ZOrder z_order = _properties.get_z_order();
1273 adjust_z_order(z_order, z_order);
1279void WinGraphicsWindow::
1280adjust_z_order(WindowProperties::ZOrder last_z_order,
1281 WindowProperties::ZOrder this_z_order) {
1283 bool do_change =
false;
1285 switch (this_z_order) {
1286 case WindowProperties::Z_bottom:
1287 order = HWND_BOTTOM;
1291 case WindowProperties::Z_normal:
1292 if ((last_z_order != WindowProperties::Z_normal) &&
1294 (last_z_order != WindowProperties::Z_bottom ||
1295 _properties.get_foreground())
1300 order = HWND_NOTOPMOST;
1305 case WindowProperties::Z_top:
1306 order = HWND_TOPMOST;
1311 BOOL result = SetWindowPos(_hWnd, order, 0,0,0,0,
1312 SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE);
1314 windisplay_cat.warning()
1315 <<
"SetWindowPos failed.\n";
1325void WinGraphicsWindow::
1326track_mouse_leaving(HWND hwnd) {
1328 DCAST_INTO_V(winpipe, _pipe);
1330 TRACKMOUSEEVENT tme = {
1331 sizeof(TRACKMOUSEEVENT),
1338 BOOL bSucceeded = TrackMouseEvent(&tme);
1340 if (!bSucceeded && windisplay_cat.is_debug()) {
1341 windisplay_cat.debug()
1342 <<
"TrackMouseEvent failed!, LastError=" << GetLastError() << endl;
1345 _tracking_mouse_leaving =
true;
1351bool WinGraphicsWindow::
1356 windisplay_cat.info()
1357 <<
"ClipCursor() to " << clip.left <<
"," << clip.top <<
" to "
1358 << clip.right <<
"," << clip.bottom << endl;
1360 if (!ClipCursor(&clip)) {
1361 windisplay_cat.warning()
1362 <<
"Failed to confine cursor to window.\n";
1373void WinGraphicsWindow::
1375 if (SetFocus(_hWnd) ==
nullptr && GetLastError() != 0) {
1381 if (_parent_window_handle !=
nullptr && _window_handle !=
nullptr) {
1382 _parent_window_handle->request_keyboard_focus(_window_handle);
1385 windisplay_cat.error()
1386 <<
"SetFocus failed: " << GetLastError() <<
"\n";
1412window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
1413 if (windisplay_cat.is_spam()) {
1414 windisplay_cat.spam()
1416 <<
" window_proc(" << (
void *)
this <<
", " << hwnd <<
", "
1417 << msg <<
", " << wparam <<
", " << lparam <<
")\n";
1423 if (!_tracking_mouse_leaving) {
1425 track_mouse_leaving(hwnd);
1427 set_cursor_in_window();
1428 if(handle_mouse_motion(translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam))))
1433 handle_raw_input((HRAWINPUT)lparam);
1437 _tracking_mouse_leaving =
false;
1438 handle_mouse_exit();
1439 set_cursor_out_of_window();
1444 track_mouse_leaving(hwnd);
1445 ClearToBlack(hwnd, _properties);
1448 GetCursorPos(&cpos);
1449 ScreenToClient(hwnd, &cpos);
1451 GetClientRect(hwnd, &clientRect);
1452 if (PtInRect(&clientRect,cpos)) {
1453 set_cursor_in_window();
1455 set_cursor_out_of_window();
1488 if (!close_request_event.empty()) {
1491 throw_event(close_request_event);
1499 system_changed_properties(properties);
1506 case WM_CHILDACTIVATE:
1507 if (windisplay_cat.is_debug()) {
1508 windisplay_cat.debug()
1509 <<
"WM_CHILDACTIVATE: " << hwnd <<
"\n";
1514 if (windisplay_cat.is_debug()) {
1515 windisplay_cat.debug()
1516 <<
"WM_ACTIVATE: " << hwnd <<
", " << wparam <<
", " << lparam <<
"\n";
1519 if ((wparam & 0xffff) != WA_INACTIVE)
1527 ChangeDisplaySettings(&_fullscreen_display_mode, CDS_FULLSCREEN);
1528 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
1529 const DEVMODE &dm = _fullscreen_display_mode;
1530 windisplay_cat.error()
1531 <<
"restore ChangeDisplaySettings failed (error code: "
1532 << chg_result <<
") for specified res: "
1533 << dm.dmPelsWidth <<
" x " << dm.dmPelsHeight
1534 <<
" x " << dm.dmBitsPerPel <<
", "
1535 << dm.dmDisplayFrequency <<
" Hz\n";
1539 SetWindowPos(_hWnd, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER);
1540 fullscreen_restored(properties);
1544 if (_properties.has_mouse_mode() &&
1545 _properties.get_mouse_mode() == WindowProperties::M_confined) {
1546 if (!confine_cursor()) {
1563 ShowWindow(_hWnd, SW_MINIMIZE);
1565 do_fullscreen_disable();
1566 fullscreen_minimized(properties);
1571 system_changed_properties(properties);
1577 if (windisplay_cat.is_debug()) {
1578 windisplay_cat.debug()
1579 <<
"WM_SIZE: " << hwnd <<
", " << wparam <<
"\n";
1583 case WM_EXITSIZEMOVE:
1584 if (windisplay_cat.is_debug()) {
1585 windisplay_cat.debug()
1586 <<
"WM_EXITSIZEMOVE: " << hwnd <<
", " << wparam <<
"\n";
1590 if (_properties.has_mouse_mode() &&
1591 _properties.get_mouse_mode() == WindowProperties::M_confined) {
1596 case WM_WINDOWPOSCHANGED:
1597 if (windisplay_cat.is_debug()) {
1598 windisplay_cat.debug()
1599 <<
"WM_WINDOWPOSCHANGED: " << hwnd <<
", " << wparam <<
"\n";
1601 if (_hWnd !=
nullptr) {
1611 if (GetUpdateRect(_hWnd,
nullptr,
false)) {
1612 if (windisplay_cat.is_spam()) {
1613 windisplay_cat.spam()
1614 <<
"Got update regions: " <<
this <<
"\n";
1616 _got_expose_event =
true;
1620 case WM_LBUTTONDOWN:
1621 if (_lost_keypresses) {
1622 resend_lost_keypresses();
1632 case WM_MBUTTONDOWN:
1633 if (_lost_keypresses) {
1634 resend_lost_keypresses();
1643 case WM_RBUTTONDOWN:
1644 if (_lost_keypresses) {
1645 resend_lost_keypresses();
1654 case WM_XBUTTONDOWN:
1656 if (_lost_keypresses) {
1657 resend_lost_keypresses();
1660 int whichButton = GET_XBUTTON_WPARAM(wparam);
1662 if (whichButton == XBUTTON1) {
1664 }
else if (whichButton == XBUTTON2) {
1671 if (_lost_keypresses) {
1672 resend_lost_keypresses();
1679 if (_lost_keypresses) {
1680 resend_lost_keypresses();
1687 if (_lost_keypresses) {
1688 resend_lost_keypresses();
1696 if (_lost_keypresses) {
1697 resend_lost_keypresses();
1700 int whichButton = GET_XBUTTON_WPARAM(wparam);
1701 if (whichButton == XBUTTON1) {
1703 }
else if (whichButton == XBUTTON2) {
1711 int delta = GET_WHEEL_DELTA_WPARAM(wparam);
1714 GetCursorPos(&point);
1715 ScreenToClient(hwnd, &point);
1716 double time = get_message_time();
1722 delta -= WHEEL_DELTA;
1728 delta += WHEEL_DELTA;
1735 case WM_MOUSEHWHEEL:
1737 int delta = GET_WHEEL_DELTA_WPARAM(wparam);
1740 GetCursorPos(&point);
1741 ScreenToClient(hwnd, &point);
1742 double time = get_message_time();
1748 delta -= WHEEL_DELTA;
1754 delta += WHEEL_DELTA;
1761 case WM_IME_SETCONTEXT:
1765 windisplay_cat.debug() <<
"hwnd = " << hwnd <<
" and GetFocus = " << GetFocus() << endl;
1766 _ime_hWnd = ImmGetDefaultIMEWnd(hwnd);
1767 if (::SendMessage(_ime_hWnd, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0))
1769 windisplay_cat.debug() <<
"SendMessage failed for " << _ime_hWnd << endl;
1771 windisplay_cat.debug() <<
"SendMessage Succeeded for " << _ime_hWnd << endl;
1773 windisplay_cat.debug() <<
"wparam is " << wparam <<
", lparam is " << lparam << endl;
1774 lparam &= ~ISC_SHOWUIALL;
1775 if (ImmIsUIMessage(_ime_hWnd, msg, wparam, lparam))
1776 windisplay_cat.debug() <<
"wparam is " << wparam <<
", lparam is " << lparam << endl;
1782 if (wparam == IMN_SETOPENSTATUS) {
1783 HIMC hIMC = ImmGetContext(hwnd);
1784 nassertr(hIMC != 0, 0);
1785 _ime_open = (ImmGetOpenStatus(hIMC) != 0);
1787 _ime_active =
false;
1791 COMPOSITIONFORM comf;
1793 ImmGetCompositionWindow(hIMC, &comf);
1794 ImmGetCandidateWindow(hIMC, 0, &canf);
1795 windisplay_cat.debug() <<
1796 "comf style " << comf.dwStyle <<
1797 " comf point: x" << comf.ptCurrentPos.x <<
",y " << comf.ptCurrentPos.y <<
1798 " comf rect: l " << comf.rcArea.left <<
",t " << comf.rcArea.top <<
",r " <<
1799 comf.rcArea.right <<
",b " << comf.rcArea.bottom << endl;
1800 windisplay_cat.debug() <<
1801 "canf style " << canf.dwStyle <<
1802 " canf point: x" << canf.ptCurrentPos.x <<
",y " << canf.ptCurrentPos.y <<
1803 " canf rect: l " << canf.rcArea.left <<
",t " << canf.rcArea.top <<
",r " <<
1804 canf.rcArea.right <<
",b " << canf.rcArea.bottom << endl;
1805 comf.dwStyle = CFS_POINT;
1806 comf.ptCurrentPos.x = 2000;
1807 comf.ptCurrentPos.y = 2000;
1809 canf.dwStyle = CFS_EXCLUDE;
1811 canf.ptCurrentPos.x = 0;
1812 canf.ptCurrentPos.y = 0;
1813 canf.rcArea.left = 0;
1814 canf.rcArea.top = 0;
1815 canf.rcArea.right = 640;
1816 canf.rcArea.bottom = 480;
1819 comf.rcArea.left = 200;
1820 comf.rcArea.top = 200;
1821 comf.rcArea.right = 0;
1822 comf.rcArea.bottom = 0;
1825 if (ImmSetCompositionWindow(hIMC, &comf))
1826 windisplay_cat.debug() <<
"set composition form: success\n";
1827 for (
int i=0; i<3; ++i) {
1828 if (ImmSetCandidateWindow(hIMC, &canf))
1829 windisplay_cat.debug() <<
"set candidate form: success\n";
1834 ImmReleaseContext(hwnd, hIMC);
1838 case WM_IME_STARTCOMPOSITION:
1839 support_overlay_window(
true);
1843 case WM_IME_ENDCOMPOSITION:
1844 support_overlay_window(
false);
1845 _ime_active =
false;
1854 case WM_IME_COMPOSITION:
1866 HIMC hIMC = ImmGetContext(hwnd);
1867 nassertr(hIMC != 0, 0);
1869 DWORD result_size = 0;
1870 static const int ime_buffer_size = 256;
1871 static const int ime_buffer_size_bytes = ime_buffer_size /
sizeof(wchar_t);
1872 wchar_t ime_buffer[ime_buffer_size];
1873 size_t cursor_pos, delta_start;
1875 if (lparam & GCS_RESULTSTR) {
1876 result_size = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR,
1877 ime_buffer, ime_buffer_size_bytes);
1878 size_t num_chars = result_size /
sizeof(wchar_t);
1879 for (
size_t i = 0; i < num_chars; ++i) {
1884 if (lparam & GCS_COMPSTR) {
1885 result_size = ImmGetCompositionStringW(hIMC, GCS_CURSORPOS,
nullptr, 0);
1886 cursor_pos = result_size & 0xffff;
1888 result_size = ImmGetCompositionStringW(hIMC, GCS_DELTASTART,
nullptr, 0);
1889 delta_start = result_size & 0xffff;
1890 result_size = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, ime_buffer, ime_buffer_size);
1891 size_t num_chars = result_size /
sizeof(wchar_t);
1893 _input->
candidate(wstring(ime_buffer, num_chars),
1894 std::min(cursor_pos, delta_start),
1895 std::max(cursor_pos, delta_start),
1898 ImmReleaseContext(hwnd, hIMC);
1919 if (_lost_keypresses) {
1920 resend_lost_keypresses();
1922 if (windisplay_cat.is_debug()) {
1923 windisplay_cat.debug()
1924 <<
"syskeydown: " << wparam <<
" (" << lookup_key(wparam) <<
")\n";
1930 GetCursorPos(&point);
1931 ScreenToClient(hwnd, &point);
1932 handle_keypress(lookup_key(wparam), point.x, point.y,
1933 get_message_time());
1935 if ((lparam & 0x40000000) == 0) {
1936 handle_raw_keypress(lookup_raw_key(lparam), get_message_time());
1947 if (wparam == VK_MENU) {
1948 if ((GetKeyState(VK_LMENU) & 0x8000) != 0 && ! _lalt_down) {
1949 handle_keypress(KeyboardButton::lalt(), point.x, point.y,
1950 get_message_time());
1953 if ((GetKeyState(VK_RMENU) & 0x8000) != 0 && ! _ralt_down) {
1954 handle_keypress(KeyboardButton::ralt(), point.x, point.y,
1955 get_message_time());
1959 if (wparam == VK_F10) {
1968 if (wparam == SC_KEYMENU) {
1980 if (_lost_keypresses) {
1981 resend_lost_keypresses();
1983 if (windisplay_cat.is_debug()) {
1984 windisplay_cat.debug()
1985 <<
"keydown: " << wparam <<
" (" << lookup_key(wparam) <<
")\n";
1990 if ((lparam & 0x40000000) == 0) {
1992 GetCursorPos(&point);
1993 ScreenToClient(hwnd, &point);
1994 handle_keypress(lookup_key(wparam), point.x, point.y,
1995 get_message_time());
1996 handle_raw_keypress(lookup_raw_key(lparam), get_message_time());
2002 if (wparam == VK_SHIFT) {
2003 if ((GetKeyState(VK_LSHIFT) & 0x8000) != 0 && ! _lshift_down) {
2004 handle_keypress(KeyboardButton::lshift(), point.x, point.y,
2005 get_message_time());
2006 _lshift_down =
true;
2008 if ((GetKeyState(VK_RSHIFT) & 0x8000) != 0 && ! _rshift_down) {
2009 handle_keypress(KeyboardButton::rshift(), point.x, point.y,
2010 get_message_time());
2011 _rshift_down =
true;
2013 }
else if(wparam == VK_CONTROL) {
2014 if ((GetKeyState(VK_LCONTROL) & 0x8000) != 0 && ! _lcontrol_down) {
2015 handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
2016 get_message_time());
2017 _lcontrol_down =
true;
2019 if ((GetKeyState(VK_RCONTROL) & 0x8000) != 0 && ! _rcontrol_down) {
2020 handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
2021 get_message_time());
2022 _rcontrol_down =
true;
2028 if ((wparam==
'V') && (GetKeyState(VK_CONTROL) < 0) &&
2029 !_input_devices.empty() && paste_emit_keystrokes) {
2033 if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(
nullptr)) {
2035 hglb = GetClipboardData(CF_TEXT);
2036 if (hglb!=
nullptr) {
2037 lptstr = (
char *) GlobalLock(hglb);
2038 if (lptstr !=
nullptr) {
2040 for (pChar = lptstr; *pChar; pChar++) {
2053 GetCursorPos(&point);
2054 ScreenToClient(hwnd, &point);
2055 handle_keypress(lookup_key(wparam), point.x, point.y,
2056 get_message_time());
2069 if (wparam == VK_SHIFT) {
2070 if (((GetKeyState(VK_LSHIFT) & 0x8000) != 0) && ! _lshift_down ) {
2071 handle_keypress(KeyboardButton::lshift(), point.x, point.y,
2072 get_message_time());
2073 _lshift_down =
true;
2074 }
else if (((GetKeyState(VK_RSHIFT) & 0x8000) != 0) && ! _rshift_down ) {
2075 handle_keypress(KeyboardButton::rshift(), point.x, point.y,
2076 get_message_time());
2077 _rshift_down =
true;
2079 if ((GetKeyState(VK_LSHIFT) & 0x8000) != 0) {
2080 handle_keypress(KeyboardButton::lshift(), point.x, point.y,
2081 get_message_time());
2083 if ((GetKeyState(VK_RSHIFT) & 0x8000) != 0) {
2084 handle_keypress(KeyboardButton::rshift(), point.x, point.y,
2085 get_message_time());
2088 }
else if(wparam == VK_CONTROL) {
2089 if (((GetKeyState(VK_LCONTROL) & 0x8000) != 0) && ! _lcontrol_down ) {
2090 handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
2091 get_message_time());
2092 _lcontrol_down =
true;
2093 }
else if (((GetKeyState(VK_RCONTROL) & 0x8000) != 0) && ! _rcontrol_down ) {
2094 handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
2095 get_message_time());
2096 _rcontrol_down =
true;
2098 if ((GetKeyState(VK_LCONTROL) & 0x8000) != 0) {
2099 handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
2100 get_message_time());
2102 if ((GetKeyState(VK_RCONTROL) & 0x8000) != 0) {
2103 handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
2104 get_message_time());
2113 if (_lost_keypresses) {
2114 resend_lost_keypresses();
2116 if (windisplay_cat.is_debug()) {
2117 windisplay_cat.debug()
2118 <<
"keyup: " << wparam <<
" (" << lookup_key(wparam) <<
")\n";
2120 handle_keyrelease(lookup_key(wparam), get_message_time());
2121 handle_raw_keyrelease(lookup_raw_key(lparam), get_message_time());
2126 if (wparam == VK_SHIFT) {
2127 if ((GetKeyState(VK_LSHIFT) & 0x8000) == 0 && _lshift_down) {
2128 handle_keyrelease(KeyboardButton::lshift(), get_message_time());
2129 _lshift_down =
false;
2131 if ((GetKeyState(VK_RSHIFT) & 0x8000) == 0 && _rshift_down) {
2132 handle_keyrelease(KeyboardButton::rshift(), get_message_time());
2133 _rshift_down =
false;
2135 }
else if(wparam == VK_CONTROL) {
2136 if ((GetKeyState(VK_LCONTROL) & 0x8000) == 0 && _lcontrol_down) {
2137 handle_keyrelease(KeyboardButton::lcontrol(), get_message_time());
2138 _lcontrol_down =
false;
2140 if ((GetKeyState(VK_RCONTROL) & 0x8000) == 0 && _rcontrol_down) {
2141 handle_keyrelease(KeyboardButton::rcontrol(), get_message_time());
2142 _rcontrol_down =
false;
2144 }
else if(wparam == VK_MENU) {
2145 if ((GetKeyState(VK_LMENU) & 0x8000) == 0 && _lalt_down) {
2146 handle_keyrelease(KeyboardButton::lalt(), get_message_time());
2149 if ((GetKeyState(VK_RMENU) & 0x8000) == 0 && _ralt_down) {
2150 handle_keyrelease(KeyboardButton::ralt(), get_message_time());
2157 if (windisplay_cat.is_debug()) {
2158 windisplay_cat.debug()
2164 system_changed_properties(properties);
2186 if (windisplay_cat.is_debug()) {
2187 windisplay_cat.debug()
2191 if (_lost_keypresses) {
2192 resend_lost_keypresses();
2196 system_changed_properties(properties);
2200 if (windisplay_cat.is_debug()) {
2201 windisplay_cat.debug()
2205 system_changed_properties(properties);
2209 if (windisplay_cat.is_debug()) {
2210 windisplay_cat.debug()
2214 system_changed_properties(properties);
2220 if (windisplay_cat.is_debug()) {
2221 windisplay_cat.debug() <<
"DPI changed to " << LOWORD(wparam);
2223 if (LOWORD(wparam) != HIWORD(wparam)) {
2224 windisplay_cat.debug(
false) <<
"x" << HIWORD(wparam) <<
"\n";
2226 windisplay_cat.debug(
false) <<
"\n";
2231 if (!_properties.get_fixed_size() && dpi_window_resize) {
2232 RECT &rect = *(LPRECT)lparam;
2233 SetWindowPos(_hWnd, HWND_TOP, rect.left, rect.top,
2234 rect.right - rect.left, rect.bottom - rect.top,
2235 SWP_NOZORDER | SWP_NOACTIVATE);
2240 _num_touches = LOWORD(wparam);
2241 if (_num_touches > MAX_TOUCHES) {
2242 _num_touches = MAX_TOUCHES;
2244 if (pGetTouchInputInfo != 0) {
2245 pGetTouchInputInfo((HTOUCHINPUT)lparam, _num_touches, _touches,
sizeof(TOUCHINPUT));
2246 pCloseTouchInputHandle((HTOUCHINPUT)lparam);
2252 for ( WinProcClasses::iterator it=_window_proc_classes.begin() ; it != _window_proc_classes.end(); it++ ){
2253 (*it)->wnd_proc(
this, hwnd, msg, wparam, lparam);
2256 return DefWindowProcW(hwnd, msg, wparam, lparam);
2267 WindowHandles::const_iterator wi;
2268 wi = _window_handles.find(hwnd);
2269 if (wi != _window_handles.end()) {
2271 return (*wi).second->window_proc(hwnd, msg, wparam, lparam);
2275 if (_creating_window !=
nullptr) {
2276 return _creating_window->
window_proc(hwnd, msg, wparam, lparam);
2281 return DefWindowProcW(hwnd, msg, wparam, lparam);
2287void WinGraphicsWindow::
2291 if (!GetMessage(&msg,
nullptr, 0, 0)) {
2298 TranslateMessage(&msg);
2300 DispatchMessage(&msg);
2308void WinGraphicsWindow::
2309resend_lost_keypresses() {
2310 nassertv(_lost_keypresses);
2315 _lost_keypresses =
false;
2322void WinGraphicsWindow::
2324 bool hide_cursor =
false;
2325 if (to_window ==
nullptr) {
2328 if (_got_saved_params) {
2329 SystemParametersInfo(SPI_SETMOUSETRAILS, _saved_mouse_trails,
2331 SystemParametersInfo(SPI_SETCURSORSHADOW, 0,
2332 _saved_cursor_shadow ? (PVOID)1 :
nullptr, 0);
2333 SystemParametersInfo(SPI_SETMOUSEVANISH, 0,
2334 _saved_mouse_vanish ? (PVOID)1 :
nullptr, 0);
2335 _got_saved_params =
false;
2347 if (!_got_saved_params) {
2348 SystemParametersInfo(SPI_GETMOUSETRAILS, 0,
2349 &_saved_mouse_trails, 0);
2350 SystemParametersInfo(SPI_GETCURSORSHADOW, 0,
2351 &_saved_cursor_shadow, 0);
2352 SystemParametersInfo(SPI_GETMOUSEVANISH, 0,
2353 &_saved_mouse_vanish, 0);
2354 _got_saved_params =
true;
2356 SystemParametersInfo(SPI_SETMOUSETRAILS, 0, (PVOID)0, 0);
2357 SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)
false, 0);
2358 SystemParametersInfo(SPI_SETMOUSEVANISH, 0, (PVOID)
false, 0);
2361 SetCursor(to_window->_cursor);
2364 hide_or_show_cursor(hide_cursor);
2366 _cursor_window = to_window;
2374void WinGraphicsWindow::
2375hide_or_show_cursor(
bool hide_cursor) {
2377 if (!_cursor_hidden) {
2379 _cursor_hidden =
true;
2382 if (_cursor_hidden) {
2384 _cursor_hidden =
false;
2390#define MIN_REFRESH_RATE 60
2393#define ACCEPTABLE_REFRESH_RATE(RATE) ((RATE >= MIN_REFRESH_RATE) || (RATE==0) || (RATE==1))
2399bool WinGraphicsWindow::
2400find_acceptable_display_mode(DWORD dwWidth, DWORD dwHeight, DWORD bpp,
2405 ZeroMemory(&cur_dm,
sizeof(cur_dm));
2406 cur_dm.dmSize =
sizeof(cur_dm);
2407 EnumDisplaySettings(
nullptr, ENUM_CURRENT_SETTINGS, &cur_dm);
2410 int saved_modenum = -1;
2413 ZeroMemory(&dm,
sizeof(dm));
2414 dm.dmSize =
sizeof(dm);
2416 if (!EnumDisplaySettings(
nullptr, modenum, &dm)) {
2420 if ((dm.dmPelsWidth == dwWidth) && (dm.dmPelsHeight == dwHeight) &&
2421 (dm.dmBitsPerPel == bpp)) {
2424 if (dm.dmDisplayFrequency == cur_dm.dmDisplayFrequency) {
2426 }
else if (saved_modenum == -1) {
2427 saved_modenum = modenum;
2435 if (saved_modenum != -1) {
2436 ZeroMemory(&dm,
sizeof(dm));
2437 dm.dmSize =
sizeof(dm);
2439 if (EnumDisplaySettings(
nullptr, saved_modenum, &dm)) {
2451void WinGraphicsWindow::
2452show_error_message(DWORD message_id) {
2453 LPTSTR message_buffer;
2455 if (message_id == 0) {
2456 message_id = GetLastError();
2459 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
2460 nullptr, message_id,
2461 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2462 (LPTSTR)&message_buffer,
2464 MessageBox(GetDesktopWindow(), message_buffer, _T(errorbox_title), MB_OK);
2465 windisplay_cat.fatal() <<
"System error msg: " << message_buffer << endl;
2466 LocalFree(message_buffer);
2472void WinGraphicsWindow::
2473handle_keypress(
ButtonHandle key,
int x,
int y,
double time) {
2475 if (key != ButtonHandle::none()) {
2484void WinGraphicsWindow::
2486 if (key != ButtonHandle::none()) {
2494void WinGraphicsWindow::
2496 if (key != ButtonHandle::none()) {
2504void WinGraphicsWindow::
2506 if (key != ButtonHandle::none()) {
2514void WinGraphicsWindow::
2516 if (key != ButtonHandle::none()) {
2526lookup_key(WPARAM wparam)
const {
2531 case VK_BACK:
return KeyboardButton::backspace();
2532 case VK_DELETE:
return KeyboardButton::del();
2533 case VK_ESCAPE:
return KeyboardButton::escape();
2534 case VK_SPACE:
return KeyboardButton::space();
2535 case VK_UP:
return KeyboardButton::up();
2536 case VK_DOWN:
return KeyboardButton::down();
2537 case VK_LEFT:
return KeyboardButton::left();
2538 case VK_RIGHT:
return KeyboardButton::right();
2545 case VK_TAB:
return KeyboardButton::tab();
2546 case VK_PRIOR:
return KeyboardButton::page_up();
2547 case VK_NEXT:
return KeyboardButton::page_down();
2548 case VK_HOME:
return KeyboardButton::home();
2549 case VK_END:
return KeyboardButton::end();
2550 case VK_F1:
return KeyboardButton::f1();
2551 case VK_F2:
return KeyboardButton::f2();
2552 case VK_F3:
return KeyboardButton::f3();
2553 case VK_F4:
return KeyboardButton::f4();
2554 case VK_F5:
return KeyboardButton::f5();
2555 case VK_F6:
return KeyboardButton::f6();
2556 case VK_F7:
return KeyboardButton::f7();
2557 case VK_F8:
return KeyboardButton::f8();
2558 case VK_F9:
return KeyboardButton::f9();
2559 case VK_F10:
return KeyboardButton::f10();
2560 case VK_F11:
return KeyboardButton::f11();
2561 case VK_F12:
return KeyboardButton::f12();
2562 case VK_INSERT:
return KeyboardButton::insert();
2563 case VK_CAPITAL:
return KeyboardButton::caps_lock();
2564 case VK_NUMLOCK:
return KeyboardButton::num_lock();
2565 case VK_SCROLL:
return KeyboardButton::scroll_lock();
2566 case VK_PAUSE:
return KeyboardButton::pause();
2567 case VK_SNAPSHOT:
return KeyboardButton::print_screen();
2569 case VK_SHIFT:
return KeyboardButton::shift();
2570 case VK_LSHIFT:
return KeyboardButton::lshift();
2571 case VK_RSHIFT:
return KeyboardButton::rshift();
2573 case VK_CONTROL:
return KeyboardButton::control();
2574 case VK_LCONTROL:
return KeyboardButton::lcontrol();
2575 case VK_RCONTROL:
return KeyboardButton::rcontrol();
2577 case VK_MENU:
return KeyboardButton::alt();
2578 case VK_LMENU:
return KeyboardButton::lalt();
2579 case VK_RMENU:
return KeyboardButton::ralt();
2581 case VK_LWIN:
return KeyboardButton::lmeta();
2582 case VK_RWIN:
return KeyboardButton::rmeta();
2583 case VK_APPS:
return KeyboardButton::menu();
2586 int key = MapVirtualKey(wparam, 2);
2587 if (isascii(key) && key != 0) {
2602 return ButtonHandle::none();
2610lookup_raw_key(LPARAM lparam)
const {
2611 unsigned char vsc = (lparam & 0xff0000) >> 16;
2613 if (lparam & 0x1000000) {
2616 case 28:
return KeyboardButton::enter();
2617 case 29:
return KeyboardButton::rcontrol();
2619 case 55:
return KeyboardButton::print_screen();
2620 case 56:
return KeyboardButton::ralt();
2621 case 69:
return KeyboardButton::num_lock();
2622 case 71:
return KeyboardButton::home();
2623 case 72:
return KeyboardButton::up();
2624 case 73:
return KeyboardButton::page_up();
2625 case 75:
return KeyboardButton::left();
2626 case 77:
return KeyboardButton::right();
2627 case 79:
return KeyboardButton::end();
2628 case 80:
return KeyboardButton::down();
2629 case 81:
return KeyboardButton::page_down();
2630 case 82:
return KeyboardButton::insert();
2631 case 83:
return KeyboardButton::del();
2632 case 91:
return KeyboardButton::lmeta();
2633 case 92:
return KeyboardButton::rmeta();
2634 case 93:
return KeyboardButton::menu();
2640 ButtonHandle::none(),
2641 KeyboardButton::escape(),
2654 KeyboardButton::backspace(),
2655 KeyboardButton::tab(),
2668 KeyboardButton::enter(),
2669 KeyboardButton::lcontrol(),
2682 KeyboardButton::lshift(),
2694 KeyboardButton::rshift(),
2696 KeyboardButton::lalt(),
2697 KeyboardButton::space(),
2698 KeyboardButton::caps_lock(),
2699 KeyboardButton::f1(),
2700 KeyboardButton::f2(),
2701 KeyboardButton::f3(),
2702 KeyboardButton::f4(),
2703 KeyboardButton::f5(),
2704 KeyboardButton::f6(),
2705 KeyboardButton::f7(),
2706 KeyboardButton::f8(),
2707 KeyboardButton::f9(),
2708 KeyboardButton::f10(),
2709 KeyboardButton::pause(),
2710 KeyboardButton::scroll_lock(),
2725 return raw_map[vsc];
2731 case 87:
return KeyboardButton::f11();
2732 case 88:
return KeyboardButton::f12();
2733 default:
return ButtonHandle::none();
2745get_keyboard_map()
const {
2750 unsigned short ex_vsc[] = {0x56, 0x57, 0x58,
2751 0x011c, 0x011d, 0x0135, 0x0137, 0x0138, 0x0145, 0x0147, 0x0148, 0x0149, 0x014b, 0x014d, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x015b, 0x015c, 0x015d};
2753 for (
int k = 1; k < 84 +
sizeof(ex_vsc) /
sizeof(
short); ++k) {
2755 vsc = ex_vsc[k - 84];
2760 UINT lparam = vsc << 16;
2762 if (raw_button == ButtonHandle::none()) {
2768 button = KeyboardButton::pause();
2770 }
else if (vsc >= 0x47 && vsc <= 0x53) {
2772 button = raw_button;
2784 UINT vk = MapVirtualKeyA(vsc, MAPVK_VSC_TO_VK_EX);
2785 button = lookup_key(vk);
2791 int len = GetKeyNameTextW(lparam, text, 256);
2803void WinGraphicsWindow::
2804handle_raw_input(HRAWINPUT hraw) {
2811 if (GetRawInputData(hraw, RID_INPUT,
nullptr, &dwSize,
sizeof(RAWINPUTHEADER)) == -1) {
2815 lpb = (LPBYTE)alloca(
sizeof(LPBYTE) * dwSize);
2816 if (lpb ==
nullptr) {
2820 if (GetRawInputData(hraw, RID_INPUT, lpb, &dwSize,
sizeof(RAWINPUTHEADER)) != dwSize) {
2824 RAWINPUT *raw = (RAWINPUT *)lpb;
2825 if (raw->header.hDevice == 0) {
2829 for (
size_t i = 1; i < _input_devices.size(); ++i) {
2830 if (_input_device_handle[i] == raw->header.hDevice) {
2834 int adjx = raw->data.mouse.lLastX;
2835 int adjy = raw->data.mouse.lLastY;
2837 if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) {
2838 input->set_pointer_in_window(adjx, adjy);
2840 input->pointer_moved(adjx, adjy);
2843 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) {
2846 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) {
2849 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) {
2852 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) {
2855 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) {
2858 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) {
2861 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) {
2864 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) {
2867 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) {
2870 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) {
2880bool WinGraphicsWindow::
2881handle_mouse_motion(
int x,
int y) {
2889void WinGraphicsWindow::
2890handle_mouse_exit() {
2899HICON WinGraphicsWindow::
2900get_icon(
const Filename &filename) {
2902 IconFilenames::iterator fi = _icon_filenames.find(filename);
2903 if (fi != _icon_filenames.end()) {
2904 return (HICON)((*fi).second);
2918 windisplay_cat.warning()
2919 <<
"Could not find icon filename " << filename <<
"\n";
2923 fi = _icon_filenames.find(resolved);
2924 if (fi != _icon_filenames.end()) {
2925 _icon_filenames[filename] = (*fi).second;
2926 return (HICON)((*fi).second);
2931 HANDLE h = LoadImage(
nullptr, os.c_str(),
2932 IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);
2934 windisplay_cat.warning()
2935 <<
"windows icon filename '" << os <<
"' could not be loaded!!\n";
2938 _icon_filenames[filename] = h;
2939 _icon_filenames[resolved] = h;
2947HCURSOR WinGraphicsWindow::
2948get_cursor(
const Filename &filename) {
2950 if (filename.empty()) {
2955 IconFilenames::iterator fi = _cursor_filenames.find(filename);
2956 if (fi != _cursor_filenames.end()) {
2957 return (HCURSOR)((*fi).second);
2967 windisplay_cat.warning()
2968 <<
"Could not find cursor filename " << filename <<
"\n";
2971 fi = _cursor_filenames.find(resolved);
2972 if (fi != _cursor_filenames.end()) {
2973 _cursor_filenames[filename] = (*fi).second;
2974 return (HCURSOR)((*fi).second);
2979 HANDLE h = LoadImage(
nullptr, os.c_str(),
2980 IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
2982 windisplay_cat.warning()
2983 <<
"windows cursor filename '" << os <<
"' could not be loaded!!\n";
2984 show_error_message();
2987 _cursor_filenames[filename] = h;
2988 _cursor_filenames[resolved] = h;
2992static HCURSOR get_cursor(
const Filename &filename);
2998const WinGraphicsWindow::WindowClass &WinGraphicsWindow::
3000 WindowClass wcreg(props);
3001 std::wostringstream wclass_name;
3002 wclass_name << L
"WinGraphicsWindow" << _window_class_index;
3003 wcreg._name = wclass_name.str();
3005 std::pair<WindowClasses::iterator, bool> found = _window_classes.insert(wcreg);
3006 const WindowClass &wclass = (*found.first);
3008 if (!found.second) {
3014 _window_class_index++;
3018 HINSTANCE instance = GetModuleHandle(
nullptr);
3021 ZeroMemory(&wc,
sizeof(wc));
3022 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
3024 wc.hInstance = instance;
3026 wc.hIcon = wclass._icon;
3028 wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
3029 wc.lpszMenuName =
nullptr;
3030 wc.lpszClassName = wclass._name.c_str();
3032 if (!RegisterClassW(&wc)) {
3033 windisplay_cat.error()
3034 <<
"could not register window class " << wclass._name <<
"!" << endl;
3044WinGraphicsWindow::WinWindowHandle::
3056void WinGraphicsWindow::WinWindowHandle::
3065void WinGraphicsWindow::WinWindowHandle::
3066receive_windows_message(
unsigned int msg,
int wparam,
int lparam) {
3067 if (_window !=
nullptr) {
3074void PrintErrorMessage(DWORD msgID) {
3075 LPTSTR pMessageBuffer;
3077 if (msgID==PRINT_LAST_ERROR)
3078 msgID=GetLastError();
3080 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
3082 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
3083 (LPTSTR) &pMessageBuffer,
3085 MessageBox(GetDesktopWindow(),pMessageBuffer,_T(errorbox_title),MB_OK);
3086 windisplay_cat.fatal() <<
"System error msg: " << pMessageBuffer << endl;
3087 LocalFree( pMessageBuffer );
3093 if (windisplay_cat.is_debug()) {
3094 windisplay_cat.debug()
3095 <<
"Skipping ClearToBlack, no origin specified yet.\n";
3100 if (windisplay_cat.is_debug()) {
3101 windisplay_cat.debug()
3102 <<
"ClearToBlack(" << hWnd <<
", " << props <<
")\n";
3105 HDC hDC=GetDC(hWnd);
3111 FillRect(hDC,&clrRect,(HBRUSH)GetStockObject(BLACK_BRUSH));
3112 ReleaseDC(hWnd,hDC);
3121 GetClientRect(hwnd, view_rect);
3124 ul.x = view_rect->left;
3125 ul.y = view_rect->top;
3126 lr.x = view_rect->right;
3127 lr.y = view_rect->bottom;
3129 ClientToScreen(hwnd, &ul);
3130 ClientToScreen(hwnd, &lr);
3132 view_rect->left = ul.x;
3133 view_rect->top = ul.y;
3134 view_rect->right = lr.x;
3135 view_rect->bottom = lr.y;
3144 nassertv(wnd_proc !=
nullptr);
3153 nassertv(wnd_proc !=
nullptr);
3162 _window_proc_classes.clear();
3179 return callbackData->get_msg() == WM_TOUCH;
3188 return _num_touches;
3197 nassertr(index >= 0 && index < MAX_TOUCHES,
TouchInfo());
3199 TOUCHINPUT ti = _touches[index];
3201 point.x = TOUCH_COORD_TO_PIXEL(ti.x);
3202 point.y = TOUCH_COORD_TO_PIXEL(ti.y);
3203 ScreenToClient(_hWnd, &point);
3208 ret.set_id(ti.dwID);
3209 ret.set_flags(ti.dwFlags);
get_real_time
Returns the actual number of seconds elapsed since the ClockObject was created, or since it was last ...
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
The name of a file, such as a texture file or an Egg file.
bool is_fully_qualified() const
Returns true if the filename is fully qualified, e.g.
bool resolve_filename(const DSearchPath &searchpath, const std::string &default_extension=std::string())
Searches the given search path for the filename.
std::string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
bool exists() const
Returns true if the filename exists on the disk, false otherwise.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
This class is the main interface to controlling the render process.
This is a base class for the various different classes that represent the result of a frame of render...
void set_size_and_recalc(int x, int y)
Changes the x_size and y_size, then recalculates structures that depend on size.
An object to create GraphicsOutputs that share a particular 3-D API.
Encapsulates all the communication with a particular instance of a given rendering backend.
This specialization on CallbackData is passed when the callback is initiated from from an implementat...
Defines an interface for storing platform-specific window processor methods.
A window, fullscreen or on a desktop, into which a graphics device sends its output for interactive d...
get_unexposed_draw
See set_unexposed_draw().
get_properties
Returns the current properties of the window.
bool is_fullscreen() const
Returns true if the window has been opened as a fullscreen window, false otherwise.
get_close_request_event
Returns the name of the event set via set_close_request_event().
virtual void process_events()
Do whatever processing is necessary to ensure that the window responds to user events.
virtual void set_properties_now(WindowProperties &properties)
Applies the requested set of properties to the window, if possible, for instance to request a change ...
Similar to MutexHolder, but for a light mutex.
This class can be used to convert text between multiple representations, e.g.
std::wstring decode_text(const std::string &text) const
Returns the given wstring decoded to a single-byte string, via the current encoding system.
get_text
Returns the current text, as encoded via the current encoding system.
void set_wtext(const std::wstring &wtext)
Changes the text that is stored in the encoder.
Stores information for a single touch event.
TypeHandle is the identifier used to differentiate C++ class types.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
This is an abstract base class for wglGraphicsPipe and wdxGraphicsPipe; that is, those graphics pipes...
An abstract base class for glGraphicsWindow and dxGraphicsWindow (and, in general,...
virtual void set_properties_now(WindowProperties &properties)
Applies the requested set of properties to the window, if possible, for instance to request a change ...
void receive_windows_message(unsigned int msg, int wparam, int lparam)
This is called to receive a keyboard event generated by proxy by another window in a parent process.
virtual bool is_touch_event(GraphicsWindowProcCallbackData *callbackData)
Returns whether the specified event msg is a touch message.
virtual MouseData get_pointer(int device) const
Returns the MouseData associated with the nth input device's pointer.
virtual bool move_pointer(int device, int x, int y)
Forces the pointer to the indicated position within the window, if possible.
virtual LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
This is the nonstatic window_proc function.
virtual int get_num_touches()
Returns the current number of touches on this window.
virtual bool supports_window_procs() const
Returns whether this window supports adding of windows proc handlers.
virtual void begin_flip()
This function will be called within the draw thread after end_frame() has been called on all windows,...
virtual void close_ime()
Forces the ime window to close, if any.
static LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
This is attached to the window class for all WinGraphicsWindow windows; it is called to handle window...
virtual void remove_window_proc(const GraphicsWindowProc *wnd_proc_object)
Removes the specified Windows proc event handler.
virtual TouchInfo get_touch_info(int index)
Returns the TouchInfo object describing the specified touch.
virtual void clear_window_procs()
Removes all Windows proc event handlers.
virtual void process_events()
Do whatever processing is necessary to ensure that the window responds to user events.
virtual void add_window_proc(const GraphicsWindowProc *wnd_proc_object)
Adds the specified Windows proc event handler to be called whenever a Windows event occurs.
This object represents a window on the desktop, not necessarily a Panda window.
virtual void receive_windows_message(unsigned int msg, int wparam, int lparam)
Called on a child handle to deliver a keyboard button event generated in the parent window.
get_os_handle
Returns the OS-specific handle stored internally to the WindowHandle wrapper.
A container for the various kinds of properties we might ask to have on a graphics window before we o...
clear_cursor_filename
Removes the cursor_filename specification from the properties.
has_cursor_filename
Returns true if set_cursor_filename() has been specified.
get_title
Returns the window's title.
get_undecorated
Returns true if the window has no border.
clear_cursor_hidden
Removes the cursor_hidden specification from the properties.
int get_y_size() const
Returns size in pixels in the y dimension of the useful part of the window, not including decorations...
set_mouse_mode
Specifies the mode in which the window is to operate its mouse pointer.
int get_x_size() const
Returns size in pixels in the x dimension of the useful part of the window, not including decorations...
int get_y_origin() const
Returns the y coordinate of the window's top-left corner, not including decorations.
has_undecorated
Returns true if set_undecorated() has been specified.
clear_z_order
Removes the z_order specification from the properties.
get_minimized
Returns true if the window is minimized.
clear_mouse_mode
Removes the mouse_mode specification from the properties.
has_fullscreen
Returns true if set_fullscreen() has been specified.
clear_title
Removes the title specification from the properties.
has_minimized
Returns true if set_minimized() has been specified.
set_size
Specifies the requested size of the window, in pixels.
get_foreground
Returns true if the window is in the foreground.
has_fixed_size
Returns true if set_fixed_size() has been specified.
bool is_any_specified() const
Returns true if any properties have been specified, false otherwise.
clear_fixed_size
Removes the fixed_size specification from the properties.
clear_fullscreen
Removes the fullscreen specification from the properties.
set_foreground
Specifies whether the window should be opened in the foreground (true), or left in the background (fa...
set_open
Specifies whether the window should be open.
get_z_order
Returns the window's z_order.
get_icon_filename
Returns the icon filename associated with the window.
get_fullscreen
Returns true if the window is in fullscreen mode.
has_title
Returns true if the window title has been specified, false otherwise.
get_mouse_mode
See set_mouse_mode().
has_origin
Returns true if the window origin has been specified, false otherwise.
has_foreground
Returns true if set_foreground() has been specified.
clear_foreground
Removes the foreground specification from the properties.
get_cursor_filename
Returns the icon filename associated with the mouse cursor.
clear_undecorated
Removes the undecorated specification from the properties.
get_cursor_hidden
Returns true if the mouse cursor is invisible.
clear_minimized
Removes the minimized specification from the properties.
has_cursor_hidden
Returns true if set_cursor_hidden() has been specified.
set_minimized
Specifies whether the window should be created minimized (true), or normal (false).
clear_icon_filename
Removes the icon_filename specification from the properties.
has_z_order
Returns true if the window z_order has been specified, false otherwise.
get_fixed_size
Returns true if the window cannot be resized by the user, false otherwise.
int get_x_origin() const
Returns the x coordinate of the window's top-left corner, not including decorations.
set_origin
Specifies the origin on the screen (in pixels, relative to the top-left corner) at which the window s...
has_icon_filename
Returns true if set_icon_filename() has been specified.
This is our own Panda specialization on the default STL map.
This is our own Panda specialization on the default STL set.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BEGIN_PUBLISH typedef PointerData MouseData
Deprecated alias for PointerData.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void get_client_rect_screen(HWND hwnd, RECT *view_rect)
Fills view_rect with the coordinates of the client area of the indicated window, converted to screen ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.