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)) {
305 if (_parent_window_handle ==
nullptr) {
306 LPoint2i top_left = _properties.get_origin();
307 LPoint2i bottom_right = top_left + _properties.get_size();
309 DWORD window_style = make_style(_properties);
310 SetWindowLong(_hWnd, GWL_STYLE, window_style);
314 SetRect(&view_rect, top_left[0], top_left[1],
315 bottom_right[0], bottom_right[1]);
317 GetWindowInfo(_hWnd, &wi);
318 AdjustWindowRectEx(&view_rect, wi.dwStyle, FALSE, wi.dwExStyle);
321 SetWindowPos(_hWnd, HWND_NOTOPMOST, view_rect.left, view_rect.top,
322 view_rect.right - view_rect.left,
323 view_rect.bottom - view_rect.top,
324 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED |
325 SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
330 std::string title = properties.
get_title();
331 _properties.set_title(title);
334 SetWindowTextW(_hWnd, title_w.c_str());
341 ::SendMessage(_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)icon);
342 ::SendMessage(_hWnd, WM_SETICON, ICON_BIG, (LPARAM)icon);
351 _properties.set_cursor_hidden(hide_cursor);
352 if (_cursor_window ==
this) {
353 hide_or_show_cursor(hide_cursor);
361 _properties.set_cursor_filename(filename);
363 _cursor = get_cursor(filename);
365 _cursor = LoadCursor(
nullptr, IDC_ARROW);
368 if (_cursor_window ==
this) {
376 WindowProperties::ZOrder last_z_order = _properties.get_z_order();
378 adjust_z_order(last_z_order, properties.
get_z_order());
384 if (!SetActiveWindow(_hWnd)) {
385 windisplay_cat.warning()
386 <<
"SetForegroundWindow() failed!\n";
388 _properties.set_foreground(
true);
395 if (_properties.get_minimized() != properties.
get_minimized()) {
397 ShowWindow(_hWnd, SW_MINIMIZE);
399 ShowWindow(_hWnd, SW_RESTORE);
409 if (do_fullscreen_switch()){
410 _properties.set_fullscreen(
true);
413 windisplay_cat.warning()
414 <<
"Switching to fullscreen mode failed!\n";
417 if (do_windowed_switch()){
418 _properties.set_fullscreen(
false);
421 windisplay_cat.warning()
422 <<
"Switching to windowed mode failed!\n";
427 if (properties.has_mouse_mode()) {
428 if (properties.
get_mouse_mode() != _properties.get_mouse_mode()) {
430 case WindowProperties::M_absolute:
431 case WindowProperties::M_relative:
433 if (_properties.get_mouse_mode() == WindowProperties::M_confined) {
435 windisplay_cat.info() <<
"Unconfining cursor from window\n";
437 _properties.set_mouse_mode(WindowProperties::M_absolute);
440 case WindowProperties::M_confined:
443 if (GetForegroundWindow() != _hWnd || confine_cursor()) {
444 _properties.set_mouse_mode(WindowProperties::M_confined);
458void WinGraphicsWindow::
460 GraphicsWindow::trigger_flip();
466 InvalidateRect(_hWnd,
nullptr, FALSE);
467 _got_expose_event =
false;
469 if (windisplay_cat.is_spam()) {
470 windisplay_cat.spam()
471 <<
"InvalidateRect: " <<
this <<
"\n";
479void WinGraphicsWindow::
481 set_cursor_out_of_window();
482 DestroyWindow(_hWnd);
484 if (_properties.has_mouse_mode() &&
485 _properties.get_mouse_mode() == WindowProperties::M_confined) {
491 do_fullscreen_disable();
495 _window_handles.erase(_hWnd);
498 GraphicsWindow::close_window();
505bool WinGraphicsWindow::
507 if (_properties.has_cursor_filename()) {
508 _cursor = get_cursor(_properties.get_cursor_filename());
511 _cursor = LoadCursor(
nullptr, IDC_ARROW);
513 bool want_foreground = (!_properties.has_foreground() || _properties.get_foreground());
514 bool want_minimized = (_properties.has_minimized() && _properties.get_minimized()) && !want_foreground;
516 HWND old_foreground_window = GetForegroundWindow();
521 _creating_window =
this;
522 bool opened = open_graphic_window();
523 _creating_window =
nullptr;
531 _window_handles.insert(WindowHandles::value_type(_hWnd,
this));
534 SetWindowPos(_hWnd, HWND_TOP, 0,0,0,0,
535 SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE);
538 if (want_minimized) {
539 ShowWindow(_hWnd, SW_MINIMIZE);
540 ShowWindow(_hWnd, SW_MINIMIZE);
542 ShowWindow(_hWnd, SW_SHOWNORMAL);
543 ShowWindow(_hWnd, SW_SHOWNORMAL);
546 HWND new_foreground_window = _hWnd;
547 if (!want_foreground) {
550 new_foreground_window = old_foreground_window;
553 if (!SetActiveWindow(new_foreground_window)) {
554 windisplay_cat.warning()
555 <<
"SetActiveWindow() failed!\n";
561 if (!SetForegroundWindow(new_foreground_window)) {
562 windisplay_cat.warning()
563 <<
"SetForegroundWindow() failed!\n";
569 HIMC hIMC = ImmGetContext(_hWnd);
571 _ime_open = (ImmGetOpenStatus(hIMC) != 0);
572 ImmReleaseContext(_hWnd, hIMC);
576 if (_input_devices.size() > 1) {
578 Rid.usUsagePage = 0x01;
581 Rid.hwndTarget = _hWnd;
582 RegisterRawInputDevices(&Rid, 1,
sizeof (Rid));
586 _window_handle = NativeWindowHandle::make_win(_hWnd);
589 _window_handle =
new WinWindowHandle(
this, *_window_handle);
592 if (_parent_window_handle !=
nullptr) {
593 _parent_window_handle->attach_child(_window_handle);
600 static bool initialized =
false;
603 HMODULE user32 = GetModuleHandleA(
"user32.dll");
606 pRegisterTouchWindow = (PFN_REGISTERTOUCHWINDOW)GetProcAddress(user32,
"RegisterTouchWindow");
607 pGetTouchInputInfo = (PFN_GETTOUCHINPUTINFO)GetProcAddress(user32,
"GetTouchInputInfo");
608 pCloseTouchInputHandle = (PFN_CLOSETOUCHINPUTHANDLE)GetProcAddress(user32,
"CloseTouchInputHandle");
613 if (pRegisterTouchWindow !=
nullptr) {
614 pRegisterTouchWindow(_hWnd, 0);
626void WinGraphicsWindow::
627initialize_input_devices() {
629 PRAWINPUTDEVICELIST pRawInputDeviceList;
631 nassertv(_input_devices.size() == 0);
634 memset(_input_device_handle, 0,
sizeof(_input_device_handle));
636 GraphicsWindowInputDevice::pointer_and_keyboard(
this,
"keyboard_mouse");
637 add_input_device(device);
641 if (GetRawInputDeviceList(
nullptr, &nInputDevices,
sizeof(RAWINPUTDEVICELIST)) != 0) {
646 pRawInputDeviceList = (PRAWINPUTDEVICELIST)alloca(
sizeof(RAWINPUTDEVICELIST) * nInputDevices);
647 if (pRawInputDeviceList==0) {
652 if (GetRawInputDeviceList(pRawInputDeviceList, &nInputDevices,
sizeof(RAWINPUTDEVICELIST)) == -1) {
657 for (
int i = 0; i < (int)nInputDevices; i++) {
658 if (pRawInputDeviceList[i].dwType == RIM_TYPEMOUSE) {
661 if (GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)0, &nSize) != 0) {
664 char *psName = (
char*)alloca(
sizeof(TCHAR) * nSize);
665 if (psName == 0)
return;
666 if (GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)psName, &nSize) < 0) {
671 if (strncmp(psName,
"\\??\\Root#RDP_MOU#0000#",22)!=0) {
672 if (_input_devices.size() < 32) {
673 if (strncmp(psName,
"\\??\\",4)==0) psName += 4;
674 char *pound1 = strchr(psName,
'#');
675 char *pound2 = pound1 ? strchr(pound1+1,
'#') : 0;
676 char *pound3 = pound2 ? strchr(pound2+1,
'#') : 0;
677 if (pound3) *pound3 = 0;
678 for (
char *p = psName; *p; p++) {
683 if (pound2) *pound2 =
'.';
684 _input_device_handle[_input_devices.size()] = pRawInputDeviceList[i].hDevice;
687 device->set_pointer_in_window(0, 0);
688 add_input_device(device);
701void WinGraphicsWindow::
711void WinGraphicsWindow::
721bool WinGraphicsWindow::
722do_reshape_request(
int x_origin,
int y_origin,
bool has_origin,
723 int x_size,
int y_size) {
724 if (windisplay_cat.is_debug()) {
725 windisplay_cat.debug()
726 <<
"Got reshape request (" << x_origin <<
", " << y_origin
727 <<
", " << has_origin <<
", " << x_size <<
", " << y_size <<
")\n";
732 if (x_origin == -2) {
733 x_origin = 0.5 * (_pipe->get_display_width() - x_size);
735 if (y_origin == -2) {
736 y_origin = 0.5 * (_pipe->get_display_height() - y_size);
738 _properties.set_origin(x_origin, y_origin);
740 if (x_origin == -1 && y_origin == -1) {
750 SetRect(&view_rect, x_origin, y_origin,
751 x_origin + x_size, y_origin + y_size);
753 GetWindowInfo(_hWnd, &wi);
754 AdjustWindowRectEx(&view_rect, wi.dwStyle, FALSE, wi.dwExStyle);
756 UINT flags = SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOACTIVATE;
759 x_origin = view_rect.left;
760 y_origin = view_rect.top;
762 x_origin = CW_USEDEFAULT;
763 y_origin = CW_USEDEFAULT;
767 SetWindowPos(_hWnd,
nullptr, x_origin, y_origin,
768 view_rect.right - view_rect.left,
769 view_rect.bottom - view_rect.top,
777 return do_fullscreen_resize(x_size, y_size);
784void WinGraphicsWindow::
787 if (!GetClientRect(_hWnd, &view_rect)) {
790 if (windisplay_cat.is_debug()) {
791 windisplay_cat.debug()
792 <<
"GetClientRect() failed in handle_reshape. Ignoring.\n";
799 if (view_rect.left == 0 && view_rect.right == 0 &&
800 view_rect.bottom == 0 && view_rect.top == 0) {
801 if (windisplay_cat.is_debug()) {
802 windisplay_cat.debug()
803 <<
"GetClientRect() returned all zeroes in handle_reshape. Ignoring.\n";
808 bool result = (FALSE != ClientToScreen(_hWnd, (POINT*)&view_rect.left));
810 result = (FALSE != ClientToScreen(_hWnd, (POINT*)&view_rect.right));
814 if (windisplay_cat.is_debug()) {
815 windisplay_cat.debug()
816 <<
"ClientToScreen() failed in handle_reshape. Ignoring.\n";
826 if (_properties.has_mouse_mode() &&
827 _properties.get_mouse_mode() == WindowProperties::M_confined &&
828 _hWnd == GetForegroundWindow()) {
831 if (GetCursorPos(&cpos) && PtInRect(&view_rect, cpos)) {
832 windisplay_cat.info()
833 <<
"ClipCursor() to " << view_rect.left <<
"," << view_rect.top
834 <<
" to " << view_rect.right <<
"," << view_rect.bottom << endl;
836 if (!ClipCursor(&view_rect)) {
837 windisplay_cat.warning()
838 <<
"Failed to re-confine cursor to window.\n";
844 properties.
set_size((view_rect.right - view_rect.left),
845 (view_rect.bottom - view_rect.top));
848 properties.
set_origin(view_rect.left, view_rect.top);
850 if (windisplay_cat.is_debug()) {
851 windisplay_cat.debug()
852 <<
"reshape to origin: (" << properties.
get_x_origin() <<
","
858 system_changed_properties(properties);
864bool WinGraphicsWindow::
865do_fullscreen_resize(
int x_size,
int y_size) {
866 HWND hDesktopWindow = GetDesktopWindow();
867 HDC scrnDC = GetDC(hDesktopWindow);
868 DWORD dwFullScreenBitDepth = GetDeviceCaps(scrnDC, BITSPIXEL);
869 ReleaseDC(hDesktopWindow, scrnDC);
877 if (!find_acceptable_display_mode(x_size, y_size,
878 dwFullScreenBitDepth, dm)) {
879 windisplay_cat.error()
880 <<
"window resize(" << x_size <<
", " << y_size
881 <<
") failed, no compatible fullscreen display mode found!\n";
886 SetWindowPos(_hWnd,
nullptr, 0,0, x_size, y_size,
887 SWP_NOZORDER | SWP_NOMOVE | SWP_NOSENDCHANGING);
888 int chg_result = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
890 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
891 windisplay_cat.error()
892 <<
"resize ChangeDisplaySettings failed (error code: "
893 << chg_result <<
") for specified res: "
894 << dm.dmPelsWidth <<
" x " << dm.dmPelsHeight
895 <<
" x " << dm.dmBitsPerPel <<
", "
896 << dm.dmDisplayFrequency <<
" Hz\n";
900 _fullscreen_display_mode = dm;
902 windisplay_cat.info()
903 <<
"Resized fullscreen window to " << x_size <<
", " << y_size
904 <<
" bitdepth " << dwFullScreenBitDepth <<
", "
905 << dm.dmDisplayFrequency <<
"Hz\n";
907 _properties.set_size(x_size, y_size);
916bool WinGraphicsWindow::
917do_fullscreen_switch() {
918 if (!do_fullscreen_enable()) {
924 props.set_fullscreen(
true);
925 DWORD window_style = make_style(props);
926 SetWindowLong(_hWnd, GWL_STYLE, window_style);
928 WINDOW_METRICS metrics;
930 if (!calculate_metrics(
true, window_style, metrics, has_origin)){
934 SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0, metrics.width, metrics.height,
935 SWP_FRAMECHANGED | SWP_SHOWWINDOW);
942bool WinGraphicsWindow::
943do_windowed_switch() {
944 do_fullscreen_disable();
947 props.set_fullscreen(
false);
948 DWORD window_style = make_style(props);
949 SetWindowLong(_hWnd, GWL_STYLE, window_style);
951 WINDOW_METRICS metrics;
954 if (!calculate_metrics(
false, window_style, metrics, has_origin)){
962 SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0,
963 metrics.width, metrics.height,
964 SWP_FRAMECHANGED | SWP_SHOWWINDOW);
967 if (_properties.has_mouse_mode() &&
968 _properties.get_mouse_mode() == WindowProperties::M_confined) {
979void WinGraphicsWindow::
980reconsider_fullscreen_size(DWORD &, DWORD &, DWORD &) {
989void WinGraphicsWindow::
990support_overlay_window(
bool) {
996DWORD WinGraphicsWindow::
1005 DWORD window_style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
1008 window_style |= WS_POPUP | WS_SYSMENU;
1010 else if (_parent_window_handle) {
1011 window_style |= WS_CHILD;
1014 window_style |= WS_POPUP;
1017 window_style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
1020 window_style |= (WS_SIZEBOX | WS_MAXIMIZEBOX);
1022 window_style |= WS_BORDER;
1026 return window_style;
1033bool WinGraphicsWindow::
1034calculate_metrics(
bool fullscreen, DWORD window_style, WINDOW_METRICS &metrics,
1038 has_origin = _properties.has_origin();
1039 if (!fullscreen && has_origin) {
1040 metrics.x = _properties.get_x_origin();
1041 metrics.y = _properties.get_y_origin();
1044 if (metrics.x == -2) {
1045 metrics.x = 0.5 * (_pipe->get_display_width() - _properties.get_x_size());
1047 if (metrics.y == -2) {
1048 metrics.y = 0.5 * (_pipe->get_display_height() - _properties.get_y_size());
1050 _properties.set_origin(metrics.x, metrics.y);
1052 if (metrics.x == -1 && metrics.y == -1) {
1059 metrics.width = _properties.get_x_size();
1060 metrics.height = _properties.get_y_size();
1064 SetRect(&win_rect, metrics.x, metrics.y,
1065 metrics.x + metrics.width, metrics.y + metrics.height);
1068 if (!AdjustWindowRect(&win_rect, window_style, FALSE)) {
1069 windisplay_cat.error()
1070 <<
"AdjustWindowRect failed!" << endl;
1075 metrics.x = win_rect.left;
1076 metrics.y = win_rect.top;
1078 metrics.x = CW_USEDEFAULT;
1079 metrics.y = CW_USEDEFAULT;
1081 metrics.width = win_rect.right - win_rect.left;
1082 metrics.height = win_rect.bottom - win_rect.top;
1091bool WinGraphicsWindow::
1092open_graphic_window() {
1093 DWORD window_style = make_style(_properties);
1096 if (_properties.has_title()) {
1098 title = encoder.
decode_text(_properties.get_title());
1101 if (!_properties.has_size()) {
1103 _properties.set_size(640, 480);
1106 WINDOW_METRICS metrics;
1108 if (!calculate_metrics(fullscreen, window_style, metrics, has_origin)){
1112 const WindowClass &wclass = register_window_class(_properties);
1113 HINSTANCE hinstance = GetModuleHandle(
nullptr);
1118 WindowHandle *window_handle = _properties.get_parent_window();
1119 if (window_handle !=
nullptr) {
1120 windisplay_cat.info()
1121 <<
"Got parent_window " << *window_handle <<
"\n";
1123 if (os_handle !=
nullptr) {
1124 windisplay_cat.info()
1125 <<
"os_handle type " << os_handle->get_type() <<
"\n";
1127 if (os_handle->
is_of_type(NativeWindowHandle::WinHandle::get_class_type())) {
1128 NativeWindowHandle::WinHandle *win_handle = DCAST(NativeWindowHandle::WinHandle, os_handle);
1129 _hparent = win_handle->get_handle();
1130 }
else if (os_handle->
is_of_type(NativeWindowHandle::IntHandle::get_class_type())) {
1132 _hparent = (HWND)int_handle->get_handle();
1136 _parent_window_handle = window_handle;
1138 _parent_window_handle =
nullptr;
1142 _hWnd = CreateWindowW(wclass._name.c_str(), title.c_str(), window_style,
1143 metrics.x, metrics.y,
1146 nullptr,
nullptr, hinstance, 0);
1151 if (!fullscreen && has_origin) {
1152 x_origin = _properties.get_x_origin();
1153 y_origin = _properties.get_y_origin();
1156 _hWnd = CreateWindowW(wclass._name.c_str(), title.c_str(),
1157 WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS ,
1159 _properties.get_x_size(), _properties.get_y_size(),
1160 _hparent,
nullptr, hinstance, 0);
1173 system_changed_properties(properties);
1178 windisplay_cat.error()
1179 <<
"CreateWindow() failed!" << endl;
1180 show_error_message();
1189 if (!do_fullscreen_enable()){
1201bool WinGraphicsWindow::
1202do_fullscreen_enable() {
1204 HWND hDesktopWindow = GetDesktopWindow();
1205 HDC scrnDC = GetDC(hDesktopWindow);
1206 DWORD cur_bitdepth = GetDeviceCaps(scrnDC, BITSPIXEL);
1210 ReleaseDC(hDesktopWindow, scrnDC);
1212 DWORD dwWidth = _properties.get_x_size();
1213 DWORD dwHeight = _properties.get_y_size();
1214 DWORD dwFullScreenBitDepth = cur_bitdepth;
1217 reconsider_fullscreen_size(dwWidth, dwHeight, dwFullScreenBitDepth);
1218 if (!find_acceptable_display_mode(dwWidth, dwHeight, dwFullScreenBitDepth, dm)) {
1219 windisplay_cat.error()
1220 <<
"Videocard has no supported display resolutions at specified res ("
1221 << dwWidth <<
" x " << dwHeight <<
" x " << dwFullScreenBitDepth <<
")\n";
1225 dm.dmPelsWidth = dwWidth;
1226 dm.dmPelsHeight = dwHeight;
1227 dm.dmBitsPerPel = dwFullScreenBitDepth;
1228 int chg_result = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
1230 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
1231 windisplay_cat.error()
1232 <<
"ChangeDisplaySettings failed (error code: "
1233 << chg_result <<
") for specified res: "
1234 << dm.dmPelsWidth <<
" x " << dm.dmPelsHeight
1235 <<
" x " << dm.dmBitsPerPel <<
", "
1236 << dm.dmDisplayFrequency <<
" Hz\n";
1240 _fullscreen_display_mode = dm;
1242 _properties.set_origin(0, 0);
1243 _properties.set_size(dwWidth, dwHeight);
1253bool WinGraphicsWindow::
1254do_fullscreen_disable() {
1255 int chg_result = ChangeDisplaySettings(
nullptr, 0x0);
1256 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
1257 windisplay_cat.warning()
1258 <<
"ChangeDisplaySettings failed to restore Windowed mode\n";
1267void WinGraphicsWindow::
1269 WindowProperties::ZOrder z_order = _properties.get_z_order();
1270 adjust_z_order(z_order, z_order);
1276void WinGraphicsWindow::
1277adjust_z_order(WindowProperties::ZOrder last_z_order,
1278 WindowProperties::ZOrder this_z_order) {
1280 bool do_change =
false;
1282 switch (this_z_order) {
1283 case WindowProperties::Z_bottom:
1284 order = HWND_BOTTOM;
1288 case WindowProperties::Z_normal:
1289 if ((last_z_order != WindowProperties::Z_normal) &&
1291 (last_z_order != WindowProperties::Z_bottom ||
1292 _properties.get_foreground())
1297 order = HWND_NOTOPMOST;
1302 case WindowProperties::Z_top:
1303 order = HWND_TOPMOST;
1308 BOOL result = SetWindowPos(_hWnd, order, 0,0,0,0,
1309 SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE);
1311 windisplay_cat.warning()
1312 <<
"SetWindowPos failed.\n";
1322void WinGraphicsWindow::
1323track_mouse_leaving(HWND hwnd) {
1325 DCAST_INTO_V(winpipe, _pipe);
1327 TRACKMOUSEEVENT tme = {
1328 sizeof(TRACKMOUSEEVENT),
1335 BOOL bSucceeded = TrackMouseEvent(&tme);
1337 if (!bSucceeded && windisplay_cat.is_debug()) {
1338 windisplay_cat.debug()
1339 <<
"TrackMouseEvent failed!, LastError=" << GetLastError() << endl;
1342 _tracking_mouse_leaving =
true;
1348bool WinGraphicsWindow::
1353 windisplay_cat.info()
1354 <<
"ClipCursor() to " << clip.left <<
"," << clip.top <<
" to "
1355 << clip.right <<
"," << clip.bottom << endl;
1357 if (!ClipCursor(&clip)) {
1358 windisplay_cat.warning()
1359 <<
"Failed to confine cursor to window.\n";
1370void WinGraphicsWindow::
1372 if (SetFocus(_hWnd) ==
nullptr && GetLastError() != 0) {
1378 if (_parent_window_handle !=
nullptr && _window_handle !=
nullptr) {
1379 _parent_window_handle->request_keyboard_focus(_window_handle);
1382 windisplay_cat.error()
1383 <<
"SetFocus failed: " << GetLastError() <<
"\n";
1409window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
1410 if (windisplay_cat.is_spam()) {
1411 windisplay_cat.spam()
1413 <<
" window_proc(" << (
void *)
this <<
", " << hwnd <<
", "
1414 << msg <<
", " << wparam <<
", " << lparam <<
")\n";
1420 if (!_tracking_mouse_leaving) {
1422 track_mouse_leaving(hwnd);
1424 set_cursor_in_window();
1425 if(handle_mouse_motion(translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam))))
1430 handle_raw_input((HRAWINPUT)lparam);
1434 _tracking_mouse_leaving =
false;
1435 handle_mouse_exit();
1436 set_cursor_out_of_window();
1441 track_mouse_leaving(hwnd);
1442 ClearToBlack(hwnd, _properties);
1445 GetCursorPos(&cpos);
1446 ScreenToClient(hwnd, &cpos);
1448 GetClientRect(hwnd, &clientRect);
1449 if (PtInRect(&clientRect,cpos)) {
1450 set_cursor_in_window();
1452 set_cursor_out_of_window();
1485 if (!close_request_event.empty()) {
1488 throw_event(close_request_event);
1496 system_changed_properties(properties);
1503 case WM_CHILDACTIVATE:
1504 if (windisplay_cat.is_debug()) {
1505 windisplay_cat.debug()
1506 <<
"WM_CHILDACTIVATE: " << hwnd <<
"\n";
1511 if (windisplay_cat.is_debug()) {
1512 windisplay_cat.debug()
1513 <<
"WM_ACTIVATE: " << hwnd <<
", " << wparam <<
", " << lparam <<
"\n";
1516 if ((wparam & 0xffff) != WA_INACTIVE)
1524 ChangeDisplaySettings(&_fullscreen_display_mode, CDS_FULLSCREEN);
1525 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
1526 const DEVMODE &dm = _fullscreen_display_mode;
1527 windisplay_cat.error()
1528 <<
"restore ChangeDisplaySettings failed (error code: "
1529 << chg_result <<
") for specified res: "
1530 << dm.dmPelsWidth <<
" x " << dm.dmPelsHeight
1531 <<
" x " << dm.dmBitsPerPel <<
", "
1532 << dm.dmDisplayFrequency <<
" Hz\n";
1536 SetWindowPos(_hWnd, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER);
1537 fullscreen_restored(properties);
1541 if (_properties.has_mouse_mode() &&
1542 _properties.get_mouse_mode() == WindowProperties::M_confined) {
1543 if (!confine_cursor()) {
1560 ShowWindow(_hWnd, SW_MINIMIZE);
1562 do_fullscreen_disable();
1563 fullscreen_minimized(properties);
1568 system_changed_properties(properties);
1574 if (windisplay_cat.is_debug()) {
1575 windisplay_cat.debug()
1576 <<
"WM_SIZE: " << hwnd <<
", " << wparam <<
"\n";
1580 case WM_EXITSIZEMOVE:
1581 if (windisplay_cat.is_debug()) {
1582 windisplay_cat.debug()
1583 <<
"WM_EXITSIZEMOVE: " << hwnd <<
", " << wparam <<
"\n";
1587 if (_properties.has_mouse_mode() &&
1588 _properties.get_mouse_mode() == WindowProperties::M_confined) {
1593 case WM_WINDOWPOSCHANGED:
1594 if (windisplay_cat.is_debug()) {
1595 windisplay_cat.debug()
1596 <<
"WM_WINDOWPOSCHANGED: " << hwnd <<
", " << wparam <<
"\n";
1598 if (_hWnd !=
nullptr) {
1608 if (GetUpdateRect(_hWnd,
nullptr,
false)) {
1609 if (windisplay_cat.is_spam()) {
1610 windisplay_cat.spam()
1611 <<
"Got update regions: " <<
this <<
"\n";
1613 _got_expose_event =
true;
1617 case WM_LBUTTONDOWN:
1618 if (_lost_keypresses) {
1619 resend_lost_keypresses();
1629 case WM_MBUTTONDOWN:
1630 if (_lost_keypresses) {
1631 resend_lost_keypresses();
1640 case WM_RBUTTONDOWN:
1641 if (_lost_keypresses) {
1642 resend_lost_keypresses();
1651 case WM_XBUTTONDOWN:
1653 if (_lost_keypresses) {
1654 resend_lost_keypresses();
1657 int whichButton = GET_XBUTTON_WPARAM(wparam);
1659 if (whichButton == XBUTTON1) {
1661 }
else if (whichButton == XBUTTON2) {
1668 if (_lost_keypresses) {
1669 resend_lost_keypresses();
1676 if (_lost_keypresses) {
1677 resend_lost_keypresses();
1684 if (_lost_keypresses) {
1685 resend_lost_keypresses();
1693 if (_lost_keypresses) {
1694 resend_lost_keypresses();
1697 int whichButton = GET_XBUTTON_WPARAM(wparam);
1698 if (whichButton == XBUTTON1) {
1700 }
else if (whichButton == XBUTTON2) {
1708 int delta = GET_WHEEL_DELTA_WPARAM(wparam);
1711 GetCursorPos(&point);
1712 ScreenToClient(hwnd, &point);
1713 double time = get_message_time();
1719 delta -= WHEEL_DELTA;
1725 delta += WHEEL_DELTA;
1732 case WM_MOUSEHWHEEL:
1734 int delta = GET_WHEEL_DELTA_WPARAM(wparam);
1737 GetCursorPos(&point);
1738 ScreenToClient(hwnd, &point);
1739 double time = get_message_time();
1745 delta -= WHEEL_DELTA;
1751 delta += WHEEL_DELTA;
1758 case WM_IME_SETCONTEXT:
1762 windisplay_cat.debug() <<
"hwnd = " << hwnd <<
" and GetFocus = " << GetFocus() << endl;
1763 _ime_hWnd = ImmGetDefaultIMEWnd(hwnd);
1764 if (::SendMessage(_ime_hWnd, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0))
1766 windisplay_cat.debug() <<
"SendMessage failed for " << _ime_hWnd << endl;
1768 windisplay_cat.debug() <<
"SendMessage Succeeded for " << _ime_hWnd << endl;
1770 windisplay_cat.debug() <<
"wparam is " << wparam <<
", lparam is " << lparam << endl;
1771 lparam &= ~ISC_SHOWUIALL;
1772 if (ImmIsUIMessage(_ime_hWnd, msg, wparam, lparam))
1773 windisplay_cat.debug() <<
"wparam is " << wparam <<
", lparam is " << lparam << endl;
1779 if (wparam == IMN_SETOPENSTATUS) {
1780 HIMC hIMC = ImmGetContext(hwnd);
1781 nassertr(hIMC != 0, 0);
1782 _ime_open = (ImmGetOpenStatus(hIMC) != 0);
1784 _ime_active =
false;
1788 COMPOSITIONFORM comf;
1790 ImmGetCompositionWindow(hIMC, &comf);
1791 ImmGetCandidateWindow(hIMC, 0, &canf);
1792 windisplay_cat.debug() <<
1793 "comf style " << comf.dwStyle <<
1794 " comf point: x" << comf.ptCurrentPos.x <<
",y " << comf.ptCurrentPos.y <<
1795 " comf rect: l " << comf.rcArea.left <<
",t " << comf.rcArea.top <<
",r " <<
1796 comf.rcArea.right <<
",b " << comf.rcArea.bottom << endl;
1797 windisplay_cat.debug() <<
1798 "canf style " << canf.dwStyle <<
1799 " canf point: x" << canf.ptCurrentPos.x <<
",y " << canf.ptCurrentPos.y <<
1800 " canf rect: l " << canf.rcArea.left <<
",t " << canf.rcArea.top <<
",r " <<
1801 canf.rcArea.right <<
",b " << canf.rcArea.bottom << endl;
1802 comf.dwStyle = CFS_POINT;
1803 comf.ptCurrentPos.x = 2000;
1804 comf.ptCurrentPos.y = 2000;
1806 canf.dwStyle = CFS_EXCLUDE;
1808 canf.ptCurrentPos.x = 0;
1809 canf.ptCurrentPos.y = 0;
1810 canf.rcArea.left = 0;
1811 canf.rcArea.top = 0;
1812 canf.rcArea.right = 640;
1813 canf.rcArea.bottom = 480;
1816 comf.rcArea.left = 200;
1817 comf.rcArea.top = 200;
1818 comf.rcArea.right = 0;
1819 comf.rcArea.bottom = 0;
1822 if (ImmSetCompositionWindow(hIMC, &comf))
1823 windisplay_cat.debug() <<
"set composition form: success\n";
1824 for (
int i=0; i<3; ++i) {
1825 if (ImmSetCandidateWindow(hIMC, &canf))
1826 windisplay_cat.debug() <<
"set candidate form: success\n";
1831 ImmReleaseContext(hwnd, hIMC);
1835 case WM_IME_STARTCOMPOSITION:
1836 support_overlay_window(
true);
1840 case WM_IME_ENDCOMPOSITION:
1841 support_overlay_window(
false);
1842 _ime_active =
false;
1851 case WM_IME_COMPOSITION:
1863 HIMC hIMC = ImmGetContext(hwnd);
1864 nassertr(hIMC != 0, 0);
1866 DWORD result_size = 0;
1867 static const int ime_buffer_size = 256;
1868 static const int ime_buffer_size_bytes = ime_buffer_size /
sizeof(wchar_t);
1869 wchar_t ime_buffer[ime_buffer_size];
1870 size_t cursor_pos, delta_start;
1872 if (lparam & GCS_RESULTSTR) {
1873 result_size = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR,
1874 ime_buffer, ime_buffer_size_bytes);
1875 size_t num_chars = result_size /
sizeof(wchar_t);
1876 for (
size_t i = 0; i < num_chars; ++i) {
1881 if (lparam & GCS_COMPSTR) {
1882 result_size = ImmGetCompositionStringW(hIMC, GCS_CURSORPOS,
nullptr, 0);
1883 cursor_pos = result_size & 0xffff;
1885 result_size = ImmGetCompositionStringW(hIMC, GCS_DELTASTART,
nullptr, 0);
1886 delta_start = result_size & 0xffff;
1887 result_size = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, ime_buffer, ime_buffer_size);
1888 size_t num_chars = result_size /
sizeof(wchar_t);
1890 _input->
candidate(wstring(ime_buffer, num_chars),
1891 std::min(cursor_pos, delta_start),
1892 std::max(cursor_pos, delta_start),
1895 ImmReleaseContext(hwnd, hIMC);
1916 if (_lost_keypresses) {
1917 resend_lost_keypresses();
1919 if (windisplay_cat.is_debug()) {
1920 windisplay_cat.debug()
1921 <<
"syskeydown: " << wparam <<
" (" << lookup_key(wparam) <<
")\n";
1927 GetCursorPos(&point);
1928 ScreenToClient(hwnd, &point);
1929 handle_keypress(lookup_key(wparam), point.x, point.y,
1930 get_message_time());
1932 if ((lparam & 0x40000000) == 0) {
1933 handle_raw_keypress(lookup_raw_key(lparam), get_message_time());
1944 if (wparam == VK_MENU) {
1945 if ((GetKeyState(VK_LMENU) & 0x8000) != 0 && ! _lalt_down) {
1946 handle_keypress(KeyboardButton::lalt(), point.x, point.y,
1947 get_message_time());
1950 if ((GetKeyState(VK_RMENU) & 0x8000) != 0 && ! _ralt_down) {
1951 handle_keypress(KeyboardButton::ralt(), point.x, point.y,
1952 get_message_time());
1956 if (wparam == VK_F10) {
1965 if (wparam == SC_KEYMENU) {
1977 if (_lost_keypresses) {
1978 resend_lost_keypresses();
1980 if (windisplay_cat.is_debug()) {
1981 windisplay_cat.debug()
1982 <<
"keydown: " << wparam <<
" (" << lookup_key(wparam) <<
")\n";
1987 if ((lparam & 0x40000000) == 0) {
1989 GetCursorPos(&point);
1990 ScreenToClient(hwnd, &point);
1991 handle_keypress(lookup_key(wparam), point.x, point.y,
1992 get_message_time());
1993 handle_raw_keypress(lookup_raw_key(lparam), get_message_time());
1999 if (wparam == VK_SHIFT) {
2000 if ((GetKeyState(VK_LSHIFT) & 0x8000) != 0 && ! _lshift_down) {
2001 handle_keypress(KeyboardButton::lshift(), point.x, point.y,
2002 get_message_time());
2003 _lshift_down =
true;
2005 if ((GetKeyState(VK_RSHIFT) & 0x8000) != 0 && ! _rshift_down) {
2006 handle_keypress(KeyboardButton::rshift(), point.x, point.y,
2007 get_message_time());
2008 _rshift_down =
true;
2010 }
else if(wparam == VK_CONTROL) {
2011 if ((GetKeyState(VK_LCONTROL) & 0x8000) != 0 && ! _lcontrol_down) {
2012 handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
2013 get_message_time());
2014 _lcontrol_down =
true;
2016 if ((GetKeyState(VK_RCONTROL) & 0x8000) != 0 && ! _rcontrol_down) {
2017 handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
2018 get_message_time());
2019 _rcontrol_down =
true;
2025 if ((wparam==
'V') && (GetKeyState(VK_CONTROL) < 0) &&
2026 !_input_devices.empty() && paste_emit_keystrokes) {
2030 if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(
nullptr)) {
2032 hglb = GetClipboardData(CF_TEXT);
2033 if (hglb!=
nullptr) {
2034 lptstr = (
char *) GlobalLock(hglb);
2035 if (lptstr !=
nullptr) {
2037 for (pChar = lptstr; *pChar; pChar++) {
2050 GetCursorPos(&point);
2051 ScreenToClient(hwnd, &point);
2052 handle_keypress(lookup_key(wparam), point.x, point.y,
2053 get_message_time());
2066 if (wparam == VK_SHIFT) {
2067 if (((GetKeyState(VK_LSHIFT) & 0x8000) != 0) && ! _lshift_down ) {
2068 handle_keypress(KeyboardButton::lshift(), point.x, point.y,
2069 get_message_time());
2070 _lshift_down =
true;
2071 }
else if (((GetKeyState(VK_RSHIFT) & 0x8000) != 0) && ! _rshift_down ) {
2072 handle_keypress(KeyboardButton::rshift(), point.x, point.y,
2073 get_message_time());
2074 _rshift_down =
true;
2076 if ((GetKeyState(VK_LSHIFT) & 0x8000) != 0) {
2077 handle_keypress(KeyboardButton::lshift(), point.x, point.y,
2078 get_message_time());
2080 if ((GetKeyState(VK_RSHIFT) & 0x8000) != 0) {
2081 handle_keypress(KeyboardButton::rshift(), point.x, point.y,
2082 get_message_time());
2085 }
else if(wparam == VK_CONTROL) {
2086 if (((GetKeyState(VK_LCONTROL) & 0x8000) != 0) && ! _lcontrol_down ) {
2087 handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
2088 get_message_time());
2089 _lcontrol_down =
true;
2090 }
else if (((GetKeyState(VK_RCONTROL) & 0x8000) != 0) && ! _rcontrol_down ) {
2091 handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
2092 get_message_time());
2093 _rcontrol_down =
true;
2095 if ((GetKeyState(VK_LCONTROL) & 0x8000) != 0) {
2096 handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
2097 get_message_time());
2099 if ((GetKeyState(VK_RCONTROL) & 0x8000) != 0) {
2100 handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
2101 get_message_time());
2110 if (_lost_keypresses) {
2111 resend_lost_keypresses();
2113 if (windisplay_cat.is_debug()) {
2114 windisplay_cat.debug()
2115 <<
"keyup: " << wparam <<
" (" << lookup_key(wparam) <<
")\n";
2117 handle_keyrelease(lookup_key(wparam), get_message_time());
2118 handle_raw_keyrelease(lookup_raw_key(lparam), get_message_time());
2123 if (wparam == VK_SHIFT) {
2124 if ((GetKeyState(VK_LSHIFT) & 0x8000) == 0 && _lshift_down) {
2125 handle_keyrelease(KeyboardButton::lshift(), get_message_time());
2126 _lshift_down =
false;
2128 if ((GetKeyState(VK_RSHIFT) & 0x8000) == 0 && _rshift_down) {
2129 handle_keyrelease(KeyboardButton::rshift(), get_message_time());
2130 _rshift_down =
false;
2132 }
else if(wparam == VK_CONTROL) {
2133 if ((GetKeyState(VK_LCONTROL) & 0x8000) == 0 && _lcontrol_down) {
2134 handle_keyrelease(KeyboardButton::lcontrol(), get_message_time());
2135 _lcontrol_down =
false;
2137 if ((GetKeyState(VK_RCONTROL) & 0x8000) == 0 && _rcontrol_down) {
2138 handle_keyrelease(KeyboardButton::rcontrol(), get_message_time());
2139 _rcontrol_down =
false;
2141 }
else if(wparam == VK_MENU) {
2142 if ((GetKeyState(VK_LMENU) & 0x8000) == 0 && _lalt_down) {
2143 handle_keyrelease(KeyboardButton::lalt(), get_message_time());
2146 if ((GetKeyState(VK_RMENU) & 0x8000) == 0 && _ralt_down) {
2147 handle_keyrelease(KeyboardButton::ralt(), get_message_time());
2154 if (windisplay_cat.is_debug()) {
2155 windisplay_cat.debug()
2161 system_changed_properties(properties);
2183 if (windisplay_cat.is_debug()) {
2184 windisplay_cat.debug()
2188 if (_lost_keypresses) {
2189 resend_lost_keypresses();
2193 system_changed_properties(properties);
2197 if (windisplay_cat.is_debug()) {
2198 windisplay_cat.debug()
2202 system_changed_properties(properties);
2206 if (windisplay_cat.is_debug()) {
2207 windisplay_cat.debug()
2211 system_changed_properties(properties);
2217 if (windisplay_cat.is_debug()) {
2218 windisplay_cat.debug() <<
"DPI changed to " << LOWORD(wparam);
2220 if (LOWORD(wparam) != HIWORD(wparam)) {
2221 windisplay_cat.debug(
false) <<
"x" << HIWORD(wparam) <<
"\n";
2223 windisplay_cat.debug(
false) <<
"\n";
2228 if (!_properties.get_fixed_size() && dpi_window_resize) {
2229 RECT &rect = *(LPRECT)lparam;
2230 SetWindowPos(_hWnd, HWND_TOP, rect.left, rect.top,
2231 rect.right - rect.left, rect.bottom - rect.top,
2232 SWP_NOZORDER | SWP_NOACTIVATE);
2237 _num_touches = LOWORD(wparam);
2238 if (_num_touches > MAX_TOUCHES) {
2239 _num_touches = MAX_TOUCHES;
2241 if (pGetTouchInputInfo != 0) {
2242 pGetTouchInputInfo((HTOUCHINPUT)lparam, _num_touches, _touches,
sizeof(TOUCHINPUT));
2243 pCloseTouchInputHandle((HTOUCHINPUT)lparam);
2249 for ( WinProcClasses::iterator it=_window_proc_classes.begin() ; it != _window_proc_classes.end(); it++ ){
2250 (*it)->wnd_proc(
this, hwnd, msg, wparam, lparam);
2253 return DefWindowProcW(hwnd, msg, wparam, lparam);
2264 WindowHandles::const_iterator wi;
2265 wi = _window_handles.find(hwnd);
2266 if (wi != _window_handles.end()) {
2268 return (*wi).second->window_proc(hwnd, msg, wparam, lparam);
2272 if (_creating_window !=
nullptr) {
2273 return _creating_window->
window_proc(hwnd, msg, wparam, lparam);
2278 return DefWindowProcW(hwnd, msg, wparam, lparam);
2284void WinGraphicsWindow::
2288 if (!GetMessage(&msg,
nullptr, 0, 0)) {
2295 TranslateMessage(&msg);
2297 DispatchMessage(&msg);
2305void WinGraphicsWindow::
2306resend_lost_keypresses() {
2307 nassertv(_lost_keypresses);
2312 _lost_keypresses =
false;
2319void WinGraphicsWindow::
2321 bool hide_cursor =
false;
2322 if (to_window ==
nullptr) {
2325 if (_got_saved_params) {
2326 SystemParametersInfo(SPI_SETMOUSETRAILS, _saved_mouse_trails,
2328 SystemParametersInfo(SPI_SETCURSORSHADOW, 0,
2329 _saved_cursor_shadow ? (PVOID)1 :
nullptr, 0);
2330 SystemParametersInfo(SPI_SETMOUSEVANISH, 0,
2331 _saved_mouse_vanish ? (PVOID)1 :
nullptr, 0);
2332 _got_saved_params =
false;
2344 if (!_got_saved_params) {
2345 SystemParametersInfo(SPI_GETMOUSETRAILS, 0,
2346 &_saved_mouse_trails, 0);
2347 SystemParametersInfo(SPI_GETCURSORSHADOW, 0,
2348 &_saved_cursor_shadow, 0);
2349 SystemParametersInfo(SPI_GETMOUSEVANISH, 0,
2350 &_saved_mouse_vanish, 0);
2351 _got_saved_params =
true;
2353 SystemParametersInfo(SPI_SETMOUSETRAILS, 0, (PVOID)0, 0);
2354 SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)
false, 0);
2355 SystemParametersInfo(SPI_SETMOUSEVANISH, 0, (PVOID)
false, 0);
2358 SetCursor(to_window->_cursor);
2361 hide_or_show_cursor(hide_cursor);
2363 _cursor_window = to_window;
2371void WinGraphicsWindow::
2372hide_or_show_cursor(
bool hide_cursor) {
2374 if (!_cursor_hidden) {
2376 _cursor_hidden =
true;
2379 if (_cursor_hidden) {
2381 _cursor_hidden =
false;
2387#define MIN_REFRESH_RATE 60
2390#define ACCEPTABLE_REFRESH_RATE(RATE) ((RATE >= MIN_REFRESH_RATE) || (RATE==0) || (RATE==1))
2396bool WinGraphicsWindow::
2397find_acceptable_display_mode(DWORD dwWidth, DWORD dwHeight, DWORD bpp,
2402 ZeroMemory(&cur_dm,
sizeof(cur_dm));
2403 cur_dm.dmSize =
sizeof(cur_dm);
2404 EnumDisplaySettings(
nullptr, ENUM_CURRENT_SETTINGS, &cur_dm);
2407 int saved_modenum = -1;
2410 ZeroMemory(&dm,
sizeof(dm));
2411 dm.dmSize =
sizeof(dm);
2413 if (!EnumDisplaySettings(
nullptr, modenum, &dm)) {
2417 if ((dm.dmPelsWidth == dwWidth) && (dm.dmPelsHeight == dwHeight) &&
2418 (dm.dmBitsPerPel == bpp)) {
2421 if (dm.dmDisplayFrequency == cur_dm.dmDisplayFrequency) {
2423 }
else if (saved_modenum == -1) {
2424 saved_modenum = modenum;
2432 if (saved_modenum != -1) {
2433 ZeroMemory(&dm,
sizeof(dm));
2434 dm.dmSize =
sizeof(dm);
2436 if (EnumDisplaySettings(
nullptr, saved_modenum, &dm)) {
2448void WinGraphicsWindow::
2449show_error_message(DWORD message_id) {
2450 LPTSTR message_buffer;
2452 if (message_id == 0) {
2453 message_id = GetLastError();
2456 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
2457 nullptr, message_id,
2458 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2459 (LPTSTR)&message_buffer,
2461 MessageBox(GetDesktopWindow(), message_buffer, _T(errorbox_title), MB_OK);
2462 windisplay_cat.fatal() <<
"System error msg: " << message_buffer << endl;
2463 LocalFree(message_buffer);
2469void WinGraphicsWindow::
2470handle_keypress(
ButtonHandle key,
int x,
int y,
double time) {
2472 if (key != ButtonHandle::none()) {
2481void WinGraphicsWindow::
2483 if (key != ButtonHandle::none()) {
2491void WinGraphicsWindow::
2493 if (key != ButtonHandle::none()) {
2501void WinGraphicsWindow::
2503 if (key != ButtonHandle::none()) {
2511void WinGraphicsWindow::
2513 if (key != ButtonHandle::none()) {
2523lookup_key(WPARAM wparam)
const {
2528 case VK_BACK:
return KeyboardButton::backspace();
2529 case VK_DELETE:
return KeyboardButton::del();
2530 case VK_ESCAPE:
return KeyboardButton::escape();
2531 case VK_SPACE:
return KeyboardButton::space();
2532 case VK_UP:
return KeyboardButton::up();
2533 case VK_DOWN:
return KeyboardButton::down();
2534 case VK_LEFT:
return KeyboardButton::left();
2535 case VK_RIGHT:
return KeyboardButton::right();
2542 case VK_TAB:
return KeyboardButton::tab();
2543 case VK_PRIOR:
return KeyboardButton::page_up();
2544 case VK_NEXT:
return KeyboardButton::page_down();
2545 case VK_HOME:
return KeyboardButton::home();
2546 case VK_END:
return KeyboardButton::end();
2547 case VK_F1:
return KeyboardButton::f1();
2548 case VK_F2:
return KeyboardButton::f2();
2549 case VK_F3:
return KeyboardButton::f3();
2550 case VK_F4:
return KeyboardButton::f4();
2551 case VK_F5:
return KeyboardButton::f5();
2552 case VK_F6:
return KeyboardButton::f6();
2553 case VK_F7:
return KeyboardButton::f7();
2554 case VK_F8:
return KeyboardButton::f8();
2555 case VK_F9:
return KeyboardButton::f9();
2556 case VK_F10:
return KeyboardButton::f10();
2557 case VK_F11:
return KeyboardButton::f11();
2558 case VK_F12:
return KeyboardButton::f12();
2559 case VK_INSERT:
return KeyboardButton::insert();
2560 case VK_CAPITAL:
return KeyboardButton::caps_lock();
2561 case VK_NUMLOCK:
return KeyboardButton::num_lock();
2562 case VK_SCROLL:
return KeyboardButton::scroll_lock();
2563 case VK_PAUSE:
return KeyboardButton::pause();
2564 case VK_SNAPSHOT:
return KeyboardButton::print_screen();
2566 case VK_SHIFT:
return KeyboardButton::shift();
2567 case VK_LSHIFT:
return KeyboardButton::lshift();
2568 case VK_RSHIFT:
return KeyboardButton::rshift();
2570 case VK_CONTROL:
return KeyboardButton::control();
2571 case VK_LCONTROL:
return KeyboardButton::lcontrol();
2572 case VK_RCONTROL:
return KeyboardButton::rcontrol();
2574 case VK_MENU:
return KeyboardButton::alt();
2575 case VK_LMENU:
return KeyboardButton::lalt();
2576 case VK_RMENU:
return KeyboardButton::ralt();
2578 case VK_LWIN:
return KeyboardButton::lmeta();
2579 case VK_RWIN:
return KeyboardButton::rmeta();
2580 case VK_APPS:
return KeyboardButton::menu();
2583 int key = MapVirtualKey(wparam, 2);
2584 if (isascii(key) && key != 0) {
2599 return ButtonHandle::none();
2607lookup_raw_key(LPARAM lparam)
const {
2608 unsigned char vsc = (lparam & 0xff0000) >> 16;
2610 if (lparam & 0x1000000) {
2613 case 28:
return KeyboardButton::enter();
2614 case 29:
return KeyboardButton::rcontrol();
2616 case 55:
return KeyboardButton::print_screen();
2617 case 56:
return KeyboardButton::ralt();
2618 case 69:
return KeyboardButton::num_lock();
2619 case 71:
return KeyboardButton::home();
2620 case 72:
return KeyboardButton::up();
2621 case 73:
return KeyboardButton::page_up();
2622 case 75:
return KeyboardButton::left();
2623 case 77:
return KeyboardButton::right();
2624 case 79:
return KeyboardButton::end();
2625 case 80:
return KeyboardButton::down();
2626 case 81:
return KeyboardButton::page_down();
2627 case 82:
return KeyboardButton::insert();
2628 case 83:
return KeyboardButton::del();
2629 case 91:
return KeyboardButton::lmeta();
2630 case 92:
return KeyboardButton::rmeta();
2631 case 93:
return KeyboardButton::menu();
2637 ButtonHandle::none(),
2638 KeyboardButton::escape(),
2651 KeyboardButton::backspace(),
2652 KeyboardButton::tab(),
2665 KeyboardButton::enter(),
2666 KeyboardButton::lcontrol(),
2679 KeyboardButton::lshift(),
2691 KeyboardButton::rshift(),
2693 KeyboardButton::lalt(),
2694 KeyboardButton::space(),
2695 KeyboardButton::caps_lock(),
2696 KeyboardButton::f1(),
2697 KeyboardButton::f2(),
2698 KeyboardButton::f3(),
2699 KeyboardButton::f4(),
2700 KeyboardButton::f5(),
2701 KeyboardButton::f6(),
2702 KeyboardButton::f7(),
2703 KeyboardButton::f8(),
2704 KeyboardButton::f9(),
2705 KeyboardButton::f10(),
2706 KeyboardButton::pause(),
2707 KeyboardButton::scroll_lock(),
2722 return raw_map[vsc];
2728 case 87:
return KeyboardButton::f11();
2729 case 88:
return KeyboardButton::f12();
2730 default:
return ButtonHandle::none();
2742get_keyboard_map()
const {
2747 unsigned short ex_vsc[] = {0x56, 0x57, 0x58,
2748 0x011c, 0x011d, 0x0135, 0x0137, 0x0138, 0x0145, 0x0147, 0x0148, 0x0149, 0x014b, 0x014d, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x015b, 0x015c, 0x015d};
2750 for (
int k = 1; k < 84 +
sizeof(ex_vsc) /
sizeof(
short); ++k) {
2752 vsc = ex_vsc[k - 84];
2757 UINT lparam = vsc << 16;
2759 if (raw_button == ButtonHandle::none()) {
2765 button = KeyboardButton::pause();
2767 }
else if (vsc >= 0x47 && vsc <= 0x53) {
2769 button = raw_button;
2781 UINT vk = MapVirtualKeyA(vsc, MAPVK_VSC_TO_VK_EX);
2782 button = lookup_key(vk);
2788 int len = GetKeyNameTextW(lparam, text, 256);
2800void WinGraphicsWindow::
2801handle_raw_input(HRAWINPUT hraw) {
2808 if (GetRawInputData(hraw, RID_INPUT,
nullptr, &dwSize,
sizeof(RAWINPUTHEADER)) == -1) {
2812 lpb = (LPBYTE)alloca(
sizeof(LPBYTE) * dwSize);
2813 if (lpb ==
nullptr) {
2817 if (GetRawInputData(hraw, RID_INPUT, lpb, &dwSize,
sizeof(RAWINPUTHEADER)) != dwSize) {
2821 RAWINPUT *raw = (RAWINPUT *)lpb;
2822 if (raw->header.hDevice == 0) {
2826 for (
size_t i = 1; i < _input_devices.size(); ++i) {
2827 if (_input_device_handle[i] == raw->header.hDevice) {
2831 int adjx = raw->data.mouse.lLastX;
2832 int adjy = raw->data.mouse.lLastY;
2834 if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) {
2835 input->set_pointer_in_window(adjx, adjy);
2837 input->pointer_moved(adjx, adjy);
2840 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) {
2843 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) {
2846 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) {
2849 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) {
2852 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) {
2855 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) {
2858 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) {
2861 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) {
2864 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) {
2867 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) {
2877bool WinGraphicsWindow::
2878handle_mouse_motion(
int x,
int y) {
2886void WinGraphicsWindow::
2887handle_mouse_exit() {
2896HICON WinGraphicsWindow::
2897get_icon(
const Filename &filename) {
2899 IconFilenames::iterator fi = _icon_filenames.find(filename);
2900 if (fi != _icon_filenames.end()) {
2901 return (HICON)((*fi).second);
2915 windisplay_cat.warning()
2916 <<
"Could not find icon filename " << filename <<
"\n";
2920 fi = _icon_filenames.find(resolved);
2921 if (fi != _icon_filenames.end()) {
2922 _icon_filenames[filename] = (*fi).second;
2923 return (HICON)((*fi).second);
2928 HANDLE h = LoadImage(
nullptr, os.c_str(),
2929 IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);
2931 windisplay_cat.warning()
2932 <<
"windows icon filename '" << os <<
"' could not be loaded!!\n";
2935 _icon_filenames[filename] = h;
2936 _icon_filenames[resolved] = h;
2944HCURSOR WinGraphicsWindow::
2945get_cursor(
const Filename &filename) {
2947 if (filename.empty()) {
2952 IconFilenames::iterator fi = _cursor_filenames.find(filename);
2953 if (fi != _cursor_filenames.end()) {
2954 return (HCURSOR)((*fi).second);
2964 windisplay_cat.warning()
2965 <<
"Could not find cursor filename " << filename <<
"\n";
2968 fi = _cursor_filenames.find(resolved);
2969 if (fi != _cursor_filenames.end()) {
2970 _cursor_filenames[filename] = (*fi).second;
2971 return (HCURSOR)((*fi).second);
2976 HANDLE h = LoadImage(
nullptr, os.c_str(),
2977 IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
2979 windisplay_cat.warning()
2980 <<
"windows cursor filename '" << os <<
"' could not be loaded!!\n";
2981 show_error_message();
2984 _cursor_filenames[filename] = h;
2985 _cursor_filenames[resolved] = h;
2989static HCURSOR get_cursor(
const Filename &filename);
2995const WinGraphicsWindow::WindowClass &WinGraphicsWindow::
2997 WindowClass wcreg(props);
2998 std::wostringstream wclass_name;
2999 wclass_name << L
"WinGraphicsWindow" << _window_class_index;
3000 wcreg._name = wclass_name.str();
3002 std::pair<WindowClasses::iterator, bool> found = _window_classes.insert(wcreg);
3003 const WindowClass &wclass = (*found.first);
3005 if (!found.second) {
3011 _window_class_index++;
3015 HINSTANCE instance = GetModuleHandle(
nullptr);
3018 ZeroMemory(&wc,
sizeof(wc));
3019 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
3021 wc.hInstance = instance;
3023 wc.hIcon = wclass._icon;
3025 wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
3026 wc.lpszMenuName =
nullptr;
3027 wc.lpszClassName = wclass._name.c_str();
3029 if (!RegisterClassW(&wc)) {
3030 windisplay_cat.error()
3031 <<
"could not register window class " << wclass._name <<
"!" << endl;
3041WinGraphicsWindow::WinWindowHandle::
3053void WinGraphicsWindow::WinWindowHandle::
3062void WinGraphicsWindow::WinWindowHandle::
3063receive_windows_message(
unsigned int msg,
int wparam,
int lparam) {
3064 if (_window !=
nullptr) {
3071void PrintErrorMessage(DWORD msgID) {
3072 LPTSTR pMessageBuffer;
3074 if (msgID==PRINT_LAST_ERROR)
3075 msgID=GetLastError();
3077 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
3079 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
3080 (LPTSTR) &pMessageBuffer,
3082 MessageBox(GetDesktopWindow(),pMessageBuffer,_T(errorbox_title),MB_OK);
3083 windisplay_cat.fatal() <<
"System error msg: " << pMessageBuffer << endl;
3084 LocalFree( pMessageBuffer );
3090 if (windisplay_cat.is_debug()) {
3091 windisplay_cat.debug()
3092 <<
"Skipping ClearToBlack, no origin specified yet.\n";
3097 if (windisplay_cat.is_debug()) {
3098 windisplay_cat.debug()
3099 <<
"ClearToBlack(" << hWnd <<
", " << props <<
")\n";
3102 HDC hDC=GetDC(hWnd);
3108 FillRect(hDC,&clrRect,(HBRUSH)GetStockObject(BLACK_BRUSH));
3109 ReleaseDC(hWnd,hDC);
3118 GetClientRect(hwnd, view_rect);
3121 ul.x = view_rect->left;
3122 ul.y = view_rect->top;
3123 lr.x = view_rect->right;
3124 lr.y = view_rect->bottom;
3126 ClientToScreen(hwnd, &ul);
3127 ClientToScreen(hwnd, &lr);
3129 view_rect->left = ul.x;
3130 view_rect->top = ul.y;
3131 view_rect->right = lr.x;
3132 view_rect->bottom = lr.y;
3141 nassertv(wnd_proc !=
nullptr);
3150 nassertv(wnd_proc !=
nullptr);
3159 _window_proc_classes.clear();
3176 return callbackData->get_msg() == WM_TOUCH;
3185 return _num_touches;
3194 nassertr(index >= 0 && index < MAX_TOUCHES,
TouchInfo());
3196 TOUCHINPUT ti = _touches[index];
3198 point.x = TOUCH_COORD_TO_PIXEL(ti.x);
3199 point.y = TOUCH_COORD_TO_PIXEL(ti.y);
3200 ScreenToClient(_hWnd, &point);
3205 ret.set_id(ti.dwID);
3206 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.