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);
291 windisplay_cat.warning()
292 <<
"Switching to windowed mode failed!\n";
302 x_size = _properties.get_x_size();
303 y_size = _properties.get_y_size();
305 if (do_fullscreen_switch(x_size, y_size)) {
306 _properties.set_fullscreen(
true);
307 _properties.set_size(x_size, y_size);
311 windisplay_cat.warning()
312 <<
"Switching to fullscreen mode failed!\n";
337 if (_parent_window_handle ==
nullptr) {
338 LPoint2i top_left = _properties.get_origin();
339 LPoint2i bottom_right = top_left + _properties.get_size();
341 DWORD window_style = make_style(_properties);
342 SetWindowLong(_hWnd, GWL_STYLE, window_style);
346 SetRect(&view_rect, top_left[0], top_left[1],
347 bottom_right[0], bottom_right[1]);
349 GetWindowInfo(_hWnd, &wi);
350 AdjustWindowRectEx(&view_rect, wi.dwStyle, FALSE, wi.dwExStyle);
353 SetWindowPos(_hWnd, HWND_NOTOPMOST, view_rect.left, view_rect.top,
354 view_rect.right - view_rect.left,
355 view_rect.bottom - view_rect.top,
356 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED |
357 SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
362 std::string title = properties.
get_title();
363 _properties.set_title(title);
366 SetWindowTextW(_hWnd, title_w.c_str());
373 ::SendMessage(_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)icon);
374 ::SendMessage(_hWnd, WM_SETICON, ICON_BIG, (LPARAM)icon);
383 _properties.set_cursor_hidden(hide_cursor);
384 if (_cursor_window ==
this) {
385 hide_or_show_cursor(hide_cursor);
393 _properties.set_cursor_filename(filename);
395 _cursor = get_cursor(filename);
397 _cursor = LoadCursor(
nullptr, IDC_ARROW);
400 if (_cursor_window ==
this) {
408 WindowProperties::ZOrder last_z_order = _properties.get_z_order();
410 adjust_z_order(last_z_order, properties.
get_z_order());
416 if (!SetActiveWindow(_hWnd)) {
417 windisplay_cat.warning()
418 <<
"SetForegroundWindow() failed!\n";
420 _properties.set_foreground(
true);
427 if (_properties.get_minimized() != properties.
get_minimized()) {
429 ShowWindow(_hWnd, SW_MINIMIZE);
431 ShowWindow(_hWnd, SW_RESTORE);
441 if (do_fullscreen_switch()){
442 _properties.set_fullscreen(
true);
445 windisplay_cat.warning()
446 <<
"Switching to fullscreen mode failed!\n";
451 if (properties.has_mouse_mode()) {
452 if (properties.
get_mouse_mode() != _properties.get_mouse_mode()) {
454 case WindowProperties::M_absolute:
455 case WindowProperties::M_relative:
457 if (_properties.get_mouse_mode() == WindowProperties::M_confined) {
459 windisplay_cat.info() <<
"Unconfining cursor from window\n";
461 _properties.set_mouse_mode(WindowProperties::M_absolute);
464 case WindowProperties::M_confined:
467 if (GetForegroundWindow() != _hWnd || confine_cursor()) {
468 _properties.set_mouse_mode(WindowProperties::M_confined);
482void WinGraphicsWindow::
484 GraphicsWindow::trigger_flip();
490 InvalidateRect(_hWnd,
nullptr, FALSE);
491 _got_expose_event =
false;
493 if (windisplay_cat.is_spam()) {
494 windisplay_cat.spam()
495 <<
"InvalidateRect: " <<
this <<
"\n";
503void WinGraphicsWindow::
505 set_cursor_out_of_window();
506 DestroyWindow(_hWnd);
508 if (_properties.has_mouse_mode() &&
509 _properties.get_mouse_mode() == WindowProperties::M_confined) {
515 do_fullscreen_disable();
519 _window_handles.erase(_hWnd);
522 GraphicsWindow::close_window();
529bool WinGraphicsWindow::
531 if (_properties.has_cursor_filename()) {
532 _cursor = get_cursor(_properties.get_cursor_filename());
535 _cursor = LoadCursor(
nullptr, IDC_ARROW);
537 bool want_foreground = (!_properties.has_foreground() || _properties.get_foreground());
538 bool want_minimized = (_properties.has_minimized() && _properties.get_minimized()) && !want_foreground;
540 HWND old_foreground_window = GetForegroundWindow();
545 _creating_window =
this;
546 bool opened = open_graphic_window();
547 _creating_window =
nullptr;
555 _window_handles.insert(WindowHandles::value_type(_hWnd,
this));
558 SetWindowPos(_hWnd, HWND_TOP, 0,0,0,0,
559 SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE);
562 if (want_minimized) {
563 ShowWindow(_hWnd, SW_MINIMIZE);
564 ShowWindow(_hWnd, SW_MINIMIZE);
566 ShowWindow(_hWnd, SW_SHOWNORMAL);
567 ShowWindow(_hWnd, SW_SHOWNORMAL);
570 HWND new_foreground_window = _hWnd;
571 if (!want_foreground) {
574 new_foreground_window = old_foreground_window;
577 if (!SetActiveWindow(new_foreground_window)) {
578 windisplay_cat.warning()
579 <<
"SetActiveWindow() failed!\n";
585 if (!SetForegroundWindow(new_foreground_window)) {
586 windisplay_cat.warning()
587 <<
"SetForegroundWindow() failed!\n";
593 HIMC hIMC = ImmGetContext(_hWnd);
595 _ime_open = (ImmGetOpenStatus(hIMC) != 0);
596 ImmReleaseContext(_hWnd, hIMC);
600 if (_input_devices.size() > 1) {
602 Rid.usUsagePage = 0x01;
605 Rid.hwndTarget = _hWnd;
606 RegisterRawInputDevices(&Rid, 1,
sizeof (Rid));
610 _window_handle = NativeWindowHandle::make_win(_hWnd);
613 _window_handle =
new WinWindowHandle(
this, *_window_handle);
616 if (_parent_window_handle !=
nullptr) {
617 _parent_window_handle->attach_child(_window_handle);
624 static bool initialized =
false;
627 HMODULE user32 = GetModuleHandleA(
"user32.dll");
630 pRegisterTouchWindow = (PFN_REGISTERTOUCHWINDOW)GetProcAddress(user32,
"RegisterTouchWindow");
631 pGetTouchInputInfo = (PFN_GETTOUCHINPUTINFO)GetProcAddress(user32,
"GetTouchInputInfo");
632 pCloseTouchInputHandle = (PFN_CLOSETOUCHINPUTHANDLE)GetProcAddress(user32,
"CloseTouchInputHandle");
637 if (pRegisterTouchWindow !=
nullptr) {
638 pRegisterTouchWindow(_hWnd, 0);
650void WinGraphicsWindow::
651initialize_input_devices() {
653 PRAWINPUTDEVICELIST pRawInputDeviceList;
655 nassertv(_input_devices.size() == 0);
658 memset(_input_device_handle, 0,
sizeof(_input_device_handle));
660 GraphicsWindowInputDevice::pointer_and_keyboard(
this,
"keyboard_mouse");
661 add_input_device(device);
665 if ((
int)GetRawInputDeviceList(
nullptr, &nInputDevices,
sizeof(RAWINPUTDEVICELIST)) != 0) {
670 pRawInputDeviceList = (PRAWINPUTDEVICELIST)alloca(
sizeof(RAWINPUTDEVICELIST) * nInputDevices);
671 if (pRawInputDeviceList ==
nullptr) {
676 if ((
int)GetRawInputDeviceList(pRawInputDeviceList, &nInputDevices,
sizeof(RAWINPUTDEVICELIST)) == -1) {
681 for (
int i = 0; i < (int)nInputDevices; i++) {
682 if (pRawInputDeviceList[i].dwType == RIM_TYPEMOUSE) {
685 if ((
int)GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)
nullptr, &nSize) != 0) {
688 char *psName = (
char*)alloca(
sizeof(TCHAR) * nSize);
689 if (psName ==
nullptr)
continue;
690 if ((
int)GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)psName, &nSize) < 0) {
695 if (strncmp(psName,
"\\??\\Root#RDP_MOU#0000#",22)!=0) {
696 if (_input_devices.size() < 32) {
697 if (strncmp(psName,
"\\??\\",4)==0) psName += 4;
698 char *pound1 = strchr(psName,
'#');
699 char *pound2 = pound1 ? strchr(pound1+1,
'#') : 0;
700 char *pound3 = pound2 ? strchr(pound2+1,
'#') : 0;
701 if (pound3) *pound3 = 0;
702 for (
char *p = psName; *p; p++) {
707 if (pound2) *pound2 =
'.';
708 _input_device_handle[_input_devices.size()] = pRawInputDeviceList[i].hDevice;
711 device->set_pointer_in_window(0, 0);
712 add_input_device(device);
725void WinGraphicsWindow::
735void WinGraphicsWindow::
745bool WinGraphicsWindow::
746do_reshape_request(
int x_origin,
int y_origin,
bool has_origin,
747 int x_size,
int y_size) {
748 if (windisplay_cat.is_debug()) {
749 windisplay_cat.debug()
750 <<
"Got reshape request (" << x_origin <<
", " << y_origin
751 <<
", " << has_origin <<
", " << x_size <<
", " << y_size <<
")\n";
756 if (x_origin == -2) {
757 x_origin = 0.5 * (_pipe->get_display_width() - x_size);
759 if (y_origin == -2) {
760 y_origin = 0.5 * (_pipe->get_display_height() - y_size);
762 _properties.set_origin(x_origin, y_origin);
764 if (x_origin == -1 && y_origin == -1) {
774 SetRect(&view_rect, x_origin, y_origin,
775 x_origin + x_size, y_origin + y_size);
777 GetWindowInfo(_hWnd, &wi);
778 AdjustWindowRectEx(&view_rect, wi.dwStyle, FALSE, wi.dwExStyle);
780 UINT flags = SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOACTIVATE;
783 x_origin = view_rect.left;
784 y_origin = view_rect.top;
786 x_origin = CW_USEDEFAULT;
787 y_origin = CW_USEDEFAULT;
791 SetWindowPos(_hWnd,
nullptr, x_origin, y_origin,
792 view_rect.right - view_rect.left,
793 view_rect.bottom - view_rect.top,
801 return do_fullscreen_resize(x_size, y_size);
808void WinGraphicsWindow::
811 if (!GetClientRect(_hWnd, &view_rect)) {
814 if (windisplay_cat.is_debug()) {
815 windisplay_cat.debug()
816 <<
"GetClientRect() failed in handle_reshape. Ignoring.\n";
823 if (view_rect.left == 0 && view_rect.right == 0 &&
824 view_rect.bottom == 0 && view_rect.top == 0) {
825 if (windisplay_cat.is_debug()) {
826 windisplay_cat.debug()
827 <<
"GetClientRect() returned all zeroes in handle_reshape. Ignoring.\n";
832 bool result = (FALSE != ClientToScreen(_hWnd, (POINT*)&view_rect.left));
834 result = (FALSE != ClientToScreen(_hWnd, (POINT*)&view_rect.right));
838 if (windisplay_cat.is_debug()) {
839 windisplay_cat.debug()
840 <<
"ClientToScreen() failed in handle_reshape. Ignoring.\n";
850 if (_properties.has_mouse_mode() &&
851 _properties.get_mouse_mode() == WindowProperties::M_confined &&
852 _hWnd == GetForegroundWindow()) {
855 if (GetCursorPos(&cpos) && PtInRect(&view_rect, cpos)) {
856 windisplay_cat.info()
857 <<
"ClipCursor() to " << view_rect.left <<
"," << view_rect.top
858 <<
" to " << view_rect.right <<
"," << view_rect.bottom << endl;
860 if (!ClipCursor(&view_rect)) {
861 windisplay_cat.warning()
862 <<
"Failed to re-confine cursor to window.\n";
868 properties.
set_size((view_rect.right - view_rect.left),
869 (view_rect.bottom - view_rect.top));
872 properties.
set_origin(view_rect.left, view_rect.top);
874 if (windisplay_cat.is_debug()) {
875 windisplay_cat.debug()
876 <<
"reshape to origin: (" << properties.
get_x_origin() <<
","
882 system_changed_properties(properties);
888bool WinGraphicsWindow::
889do_fullscreen_resize(
int x_size,
int y_size) {
890 HWND hDesktopWindow = GetDesktopWindow();
891 HDC scrnDC = GetDC(hDesktopWindow);
892 DWORD dwFullScreenBitDepth = GetDeviceCaps(scrnDC, BITSPIXEL);
893 ReleaseDC(hDesktopWindow, scrnDC);
901 if (!find_acceptable_display_mode(x_size, y_size,
902 dwFullScreenBitDepth, dm)) {
903 windisplay_cat.error()
904 <<
"window resize(" << x_size <<
", " << y_size
905 <<
") failed, no compatible fullscreen display mode found!\n";
910 SetWindowPos(_hWnd,
nullptr, 0,0, x_size, y_size,
911 SWP_NOZORDER | SWP_NOMOVE | SWP_NOSENDCHANGING);
912 int chg_result = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
914 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
915 windisplay_cat.error()
916 <<
"resize ChangeDisplaySettings failed (error code: "
917 << chg_result <<
") for specified res: "
918 << dm.dmPelsWidth <<
" x " << dm.dmPelsHeight
919 <<
" x " << dm.dmBitsPerPel <<
", "
920 << dm.dmDisplayFrequency <<
" Hz\n";
924 _fullscreen_display_mode = dm;
926 windisplay_cat.info()
927 <<
"Resized fullscreen window to " << x_size <<
", " << y_size
928 <<
" bitdepth " << dwFullScreenBitDepth <<
", "
929 << dm.dmDisplayFrequency <<
"Hz\n";
931 _properties.set_size(x_size, y_size);
940bool WinGraphicsWindow::
941do_fullscreen_switch(
int x_size,
int y_size) {
942 if (!do_fullscreen_enable(x_size, y_size)) {
948 props.set_fullscreen(
true);
949 DWORD window_style = make_style(props);
950 SetWindowLong(_hWnd, GWL_STYLE, window_style);
952 SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0, x_size, y_size,
953 SWP_FRAMECHANGED | SWP_SHOWWINDOW);
962bool WinGraphicsWindow::
963do_fullscreen_switch() {
964 return do_fullscreen_switch(_properties.get_x_size(), _properties.get_y_size());
970bool WinGraphicsWindow::
971do_windowed_switch() {
972 do_fullscreen_disable();
975 props.set_fullscreen(
false);
976 DWORD window_style = make_style(props);
977 SetWindowLong(_hWnd, GWL_STYLE, window_style);
979 WINDOW_METRICS metrics;
982 if (!calculate_metrics(
false, window_style, metrics, has_origin)){
990 SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0,
991 metrics.width, metrics.height,
992 SWP_FRAMECHANGED | SWP_SHOWWINDOW);
995 if (_properties.has_mouse_mode() &&
996 _properties.get_mouse_mode() == WindowProperties::M_confined) {
1007void WinGraphicsWindow::
1008reconsider_fullscreen_size(DWORD &, DWORD &, DWORD &) {
1017void WinGraphicsWindow::
1018support_overlay_window(
bool) {
1024DWORD WinGraphicsWindow::
1033 DWORD window_style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
1036 window_style |= WS_POPUP | WS_SYSMENU;
1038 else if (_parent_window_handle) {
1039 window_style |= WS_CHILD;
1042 window_style |= WS_POPUP;
1045 window_style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
1048 window_style |= (WS_SIZEBOX | WS_MAXIMIZEBOX);
1050 window_style |= WS_BORDER;
1054 return window_style;
1061bool WinGraphicsWindow::
1062calculate_metrics(
bool fullscreen, DWORD window_style, WINDOW_METRICS &metrics,
1066 has_origin = _properties.has_origin();
1067 if (!fullscreen && has_origin) {
1068 metrics.x = _properties.get_x_origin();
1069 metrics.y = _properties.get_y_origin();
1072 if (metrics.x == -2) {
1073 metrics.x = 0.5 * (_pipe->get_display_width() - _properties.get_x_size());
1075 if (metrics.y == -2) {
1076 metrics.y = 0.5 * (_pipe->get_display_height() - _properties.get_y_size());
1078 _properties.set_origin(metrics.x, metrics.y);
1080 if (metrics.x == -1 && metrics.y == -1) {
1087 metrics.width = _properties.get_x_size();
1088 metrics.height = _properties.get_y_size();
1092 SetRect(&win_rect, metrics.x, metrics.y,
1093 metrics.x + metrics.width, metrics.y + metrics.height);
1096 if (!AdjustWindowRect(&win_rect, window_style, FALSE)) {
1097 windisplay_cat.error()
1098 <<
"AdjustWindowRect failed!" << endl;
1103 metrics.x = win_rect.left;
1104 metrics.y = win_rect.top;
1106 metrics.x = CW_USEDEFAULT;
1107 metrics.y = CW_USEDEFAULT;
1109 metrics.width = win_rect.right - win_rect.left;
1110 metrics.height = win_rect.bottom - win_rect.top;
1119bool WinGraphicsWindow::
1120open_graphic_window() {
1121 DWORD window_style = make_style(_properties);
1124 if (_properties.has_title()) {
1126 title = encoder.
decode_text(_properties.get_title());
1129 if (!_properties.has_size()) {
1131 _properties.set_size(640, 480);
1134 WINDOW_METRICS metrics;
1136 if (!calculate_metrics(fullscreen, window_style, metrics, has_origin)){
1140 const WindowClass &wclass = register_window_class(_properties);
1141 HINSTANCE hinstance = GetModuleHandle(
nullptr);
1146 WindowHandle *window_handle = _properties.get_parent_window();
1147 if (window_handle !=
nullptr) {
1148 windisplay_cat.info()
1149 <<
"Got parent_window " << *window_handle <<
"\n";
1151 if (os_handle !=
nullptr) {
1152 windisplay_cat.info()
1153 <<
"os_handle type " << os_handle->get_type() <<
"\n";
1155 if (os_handle->
is_of_type(NativeWindowHandle::WinHandle::get_class_type())) {
1156 NativeWindowHandle::WinHandle *win_handle = DCAST(NativeWindowHandle::WinHandle, os_handle);
1157 _hparent = win_handle->get_handle();
1158 }
else if (os_handle->
is_of_type(NativeWindowHandle::IntHandle::get_class_type())) {
1160 _hparent = (HWND)int_handle->get_handle();
1164 _parent_window_handle = window_handle;
1166 _parent_window_handle =
nullptr;
1170 _hWnd = CreateWindowW(wclass._name.c_str(), title.c_str(), window_style,
1171 metrics.x, metrics.y,
1174 nullptr,
nullptr, hinstance, 0);
1179 if (!fullscreen && has_origin) {
1180 x_origin = _properties.get_x_origin();
1181 y_origin = _properties.get_y_origin();
1184 _hWnd = CreateWindowW(wclass._name.c_str(), title.c_str(),
1185 WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS ,
1187 _properties.get_x_size(), _properties.get_y_size(),
1188 _hparent,
nullptr, hinstance, 0);
1201 system_changed_properties(properties);
1206 windisplay_cat.error()
1207 <<
"CreateWindow() failed!" << endl;
1208 show_error_message();
1217 if (!do_fullscreen_enable()) {
1229bool WinGraphicsWindow::
1230do_fullscreen_enable(
int x_size,
int y_size) {
1232 HWND hDesktopWindow = GetDesktopWindow();
1233 HDC scrnDC = GetDC(hDesktopWindow);
1234 DWORD cur_bitdepth = GetDeviceCaps(scrnDC, BITSPIXEL);
1238 ReleaseDC(hDesktopWindow, scrnDC);
1240 DWORD dwWidth = x_size;
1241 DWORD dwHeight = y_size;
1242 DWORD dwFullScreenBitDepth = cur_bitdepth;
1245 reconsider_fullscreen_size(dwWidth, dwHeight, dwFullScreenBitDepth);
1246 if (!find_acceptable_display_mode(dwWidth, dwHeight, dwFullScreenBitDepth, dm)) {
1247 windisplay_cat.error()
1248 <<
"Videocard has no supported display resolutions at specified res ("
1249 << dwWidth <<
" x " << dwHeight <<
" x " << dwFullScreenBitDepth <<
")\n";
1253 dm.dmPelsWidth = dwWidth;
1254 dm.dmPelsHeight = dwHeight;
1255 dm.dmBitsPerPel = dwFullScreenBitDepth;
1256 int chg_result = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
1258 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
1259 windisplay_cat.error()
1260 <<
"ChangeDisplaySettings failed (error code: "
1261 << chg_result <<
") for specified res: "
1262 << dm.dmPelsWidth <<
" x " << dm.dmPelsHeight
1263 <<
" x " << dm.dmBitsPerPel <<
", "
1264 << dm.dmDisplayFrequency <<
" Hz\n";
1268 _fullscreen_display_mode = dm;
1276bool WinGraphicsWindow::
1277do_fullscreen_enable() {
1278 return do_fullscreen_enable(_properties.get_x_size(), _properties.get_y_size());
1285bool WinGraphicsWindow::
1286do_fullscreen_disable() {
1287 int chg_result = ChangeDisplaySettings(
nullptr, 0x0);
1288 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
1289 windisplay_cat.warning()
1290 <<
"ChangeDisplaySettings failed to restore Windowed mode\n";
1299void WinGraphicsWindow::
1301 WindowProperties::ZOrder z_order = _properties.get_z_order();
1302 adjust_z_order(z_order, z_order);
1308void WinGraphicsWindow::
1309adjust_z_order(WindowProperties::ZOrder last_z_order,
1310 WindowProperties::ZOrder this_z_order) {
1312 bool do_change =
false;
1314 switch (this_z_order) {
1315 case WindowProperties::Z_bottom:
1316 order = HWND_BOTTOM;
1320 case WindowProperties::Z_normal:
1321 if ((last_z_order != WindowProperties::Z_normal) &&
1323 (last_z_order != WindowProperties::Z_bottom ||
1324 _properties.get_foreground())
1329 order = HWND_NOTOPMOST;
1334 case WindowProperties::Z_top:
1335 order = HWND_TOPMOST;
1340 BOOL result = SetWindowPos(_hWnd, order, 0,0,0,0,
1341 SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE);
1343 windisplay_cat.warning()
1344 <<
"SetWindowPos failed.\n";
1354void WinGraphicsWindow::
1355track_mouse_leaving(HWND hwnd) {
1357 DCAST_INTO_V(winpipe, _pipe);
1359 TRACKMOUSEEVENT tme = {
1360 sizeof(TRACKMOUSEEVENT),
1367 BOOL bSucceeded = TrackMouseEvent(&tme);
1369 if (!bSucceeded && windisplay_cat.is_debug()) {
1370 windisplay_cat.debug()
1371 <<
"TrackMouseEvent failed!, LastError=" << GetLastError() << endl;
1374 _tracking_mouse_leaving =
true;
1380bool WinGraphicsWindow::
1385 windisplay_cat.info()
1386 <<
"ClipCursor() to " << clip.left <<
"," << clip.top <<
" to "
1387 << clip.right <<
"," << clip.bottom << endl;
1389 if (!ClipCursor(&clip)) {
1390 windisplay_cat.warning()
1391 <<
"Failed to confine cursor to window.\n";
1402void WinGraphicsWindow::
1404 if (SetFocus(_hWnd) ==
nullptr && GetLastError() != 0) {
1410 if (_parent_window_handle !=
nullptr && _window_handle !=
nullptr) {
1411 _parent_window_handle->request_keyboard_focus(_window_handle);
1414 windisplay_cat.error()
1415 <<
"SetFocus failed: " << GetLastError() <<
"\n";
1441window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
1442 if (windisplay_cat.is_spam()) {
1443 windisplay_cat.spam()
1445 <<
" window_proc(" << (
void *)
this <<
", " << hwnd <<
", "
1446 << msg <<
", " << wparam <<
", " << lparam <<
")\n";
1452 if (!_tracking_mouse_leaving) {
1454 track_mouse_leaving(hwnd);
1456 set_cursor_in_window();
1457 if(handle_mouse_motion(translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam))))
1462 handle_raw_input((HRAWINPUT)lparam);
1466 _tracking_mouse_leaving =
false;
1467 handle_mouse_exit();
1468 set_cursor_out_of_window();
1473 track_mouse_leaving(hwnd);
1474 ClearToBlack(hwnd, _properties);
1477 GetCursorPos(&cpos);
1478 ScreenToClient(hwnd, &cpos);
1480 GetClientRect(hwnd, &clientRect);
1481 if (PtInRect(&clientRect,cpos)) {
1482 set_cursor_in_window();
1484 set_cursor_out_of_window();
1517 if (!close_request_event.empty()) {
1520 throw_event(close_request_event);
1528 system_changed_properties(properties);
1535 case WM_CHILDACTIVATE:
1536 if (windisplay_cat.is_debug()) {
1537 windisplay_cat.debug()
1538 <<
"WM_CHILDACTIVATE: " << hwnd <<
"\n";
1543 if (windisplay_cat.is_debug()) {
1544 windisplay_cat.debug()
1545 <<
"WM_ACTIVATE: " << hwnd <<
", " << wparam <<
", " << lparam <<
"\n";
1548 if ((wparam & 0xffff) != WA_INACTIVE)
1556 ChangeDisplaySettings(&_fullscreen_display_mode, CDS_FULLSCREEN);
1557 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
1558 const DEVMODE &dm = _fullscreen_display_mode;
1559 windisplay_cat.error()
1560 <<
"restore ChangeDisplaySettings failed (error code: "
1561 << chg_result <<
") for specified res: "
1562 << dm.dmPelsWidth <<
" x " << dm.dmPelsHeight
1563 <<
" x " << dm.dmBitsPerPel <<
", "
1564 << dm.dmDisplayFrequency <<
" Hz\n";
1568 SetWindowPos(_hWnd, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER);
1569 fullscreen_restored(properties);
1573 if (_properties.has_mouse_mode() &&
1574 _properties.get_mouse_mode() == WindowProperties::M_confined) {
1575 if (!confine_cursor()) {
1592 ShowWindow(_hWnd, SW_MINIMIZE);
1594 do_fullscreen_disable();
1595 fullscreen_minimized(properties);
1600 system_changed_properties(properties);
1606 if (windisplay_cat.is_debug()) {
1607 windisplay_cat.debug()
1608 <<
"WM_SIZE: " << hwnd <<
", " << wparam <<
"\n";
1612 case WM_EXITSIZEMOVE:
1613 if (windisplay_cat.is_debug()) {
1614 windisplay_cat.debug()
1615 <<
"WM_EXITSIZEMOVE: " << hwnd <<
", " << wparam <<
"\n";
1619 if (_properties.has_mouse_mode() &&
1620 _properties.get_mouse_mode() == WindowProperties::M_confined) {
1625 case WM_WINDOWPOSCHANGED:
1626 if (windisplay_cat.is_debug()) {
1627 windisplay_cat.debug()
1628 <<
"WM_WINDOWPOSCHANGED: " << hwnd <<
", " << wparam <<
"\n";
1630 if (_hWnd !=
nullptr) {
1640 if (GetUpdateRect(_hWnd,
nullptr,
false)) {
1641 if (windisplay_cat.is_spam()) {
1642 windisplay_cat.spam()
1643 <<
"Got update regions: " <<
this <<
"\n";
1645 _got_expose_event =
true;
1649 case WM_LBUTTONDOWN:
1650 if (_lost_keypresses) {
1651 resend_lost_keypresses();
1661 case WM_MBUTTONDOWN:
1662 if (_lost_keypresses) {
1663 resend_lost_keypresses();
1672 case WM_RBUTTONDOWN:
1673 if (_lost_keypresses) {
1674 resend_lost_keypresses();
1683 case WM_XBUTTONDOWN:
1685 if (_lost_keypresses) {
1686 resend_lost_keypresses();
1689 int whichButton = GET_XBUTTON_WPARAM(wparam);
1691 if (whichButton == XBUTTON1) {
1693 }
else if (whichButton == XBUTTON2) {
1700 if (_lost_keypresses) {
1701 resend_lost_keypresses();
1710 if (_lost_keypresses) {
1711 resend_lost_keypresses();
1720 if (_lost_keypresses) {
1721 resend_lost_keypresses();
1731 if (_lost_keypresses) {
1732 resend_lost_keypresses();
1737 int whichButton = GET_XBUTTON_WPARAM(wparam);
1738 if (whichButton == XBUTTON1) {
1740 }
else if (whichButton == XBUTTON2) {
1748 int delta = GET_WHEEL_DELTA_WPARAM(wparam);
1751 GetCursorPos(&point);
1752 ScreenToClient(hwnd, &point);
1753 double time = get_message_time();
1759 delta -= WHEEL_DELTA;
1765 delta += WHEEL_DELTA;
1772 case WM_MOUSEHWHEEL:
1774 int delta = GET_WHEEL_DELTA_WPARAM(wparam);
1777 GetCursorPos(&point);
1778 ScreenToClient(hwnd, &point);
1779 double time = get_message_time();
1785 delta -= WHEEL_DELTA;
1791 delta += WHEEL_DELTA;
1798 case WM_IME_SETCONTEXT:
1802 windisplay_cat.debug() <<
"hwnd = " << hwnd <<
" and GetFocus = " << GetFocus() << endl;
1803 _ime_hWnd = ImmGetDefaultIMEWnd(hwnd);
1804 if (::SendMessage(_ime_hWnd, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0))
1806 windisplay_cat.debug() <<
"SendMessage failed for " << _ime_hWnd << endl;
1808 windisplay_cat.debug() <<
"SendMessage Succeeded for " << _ime_hWnd << endl;
1810 windisplay_cat.debug() <<
"wparam is " << wparam <<
", lparam is " << lparam << endl;
1811 lparam &= ~ISC_SHOWUIALL;
1812 if (ImmIsUIMessage(_ime_hWnd, msg, wparam, lparam))
1813 windisplay_cat.debug() <<
"wparam is " << wparam <<
", lparam is " << lparam << endl;
1819 if (wparam == IMN_SETOPENSTATUS) {
1820 HIMC hIMC = ImmGetContext(hwnd);
1821 nassertr(hIMC != 0, 0);
1822 _ime_open = (ImmGetOpenStatus(hIMC) != 0);
1824 _ime_active =
false;
1828 COMPOSITIONFORM comf;
1830 ImmGetCompositionWindow(hIMC, &comf);
1831 ImmGetCandidateWindow(hIMC, 0, &canf);
1832 windisplay_cat.debug() <<
1833 "comf style " << comf.dwStyle <<
1834 " comf point: x" << comf.ptCurrentPos.x <<
",y " << comf.ptCurrentPos.y <<
1835 " comf rect: l " << comf.rcArea.left <<
",t " << comf.rcArea.top <<
",r " <<
1836 comf.rcArea.right <<
",b " << comf.rcArea.bottom << endl;
1837 windisplay_cat.debug() <<
1838 "canf style " << canf.dwStyle <<
1839 " canf point: x" << canf.ptCurrentPos.x <<
",y " << canf.ptCurrentPos.y <<
1840 " canf rect: l " << canf.rcArea.left <<
",t " << canf.rcArea.top <<
",r " <<
1841 canf.rcArea.right <<
",b " << canf.rcArea.bottom << endl;
1842 comf.dwStyle = CFS_POINT;
1843 comf.ptCurrentPos.x = 2000;
1844 comf.ptCurrentPos.y = 2000;
1846 canf.dwStyle = CFS_EXCLUDE;
1848 canf.ptCurrentPos.x = 0;
1849 canf.ptCurrentPos.y = 0;
1850 canf.rcArea.left = 0;
1851 canf.rcArea.top = 0;
1852 canf.rcArea.right = 640;
1853 canf.rcArea.bottom = 480;
1856 comf.rcArea.left = 200;
1857 comf.rcArea.top = 200;
1858 comf.rcArea.right = 0;
1859 comf.rcArea.bottom = 0;
1862 if (ImmSetCompositionWindow(hIMC, &comf))
1863 windisplay_cat.debug() <<
"set composition form: success\n";
1864 for (
int i=0; i<3; ++i) {
1865 if (ImmSetCandidateWindow(hIMC, &canf))
1866 windisplay_cat.debug() <<
"set candidate form: success\n";
1871 ImmReleaseContext(hwnd, hIMC);
1875 case WM_IME_STARTCOMPOSITION:
1876 support_overlay_window(
true);
1880 case WM_IME_ENDCOMPOSITION:
1881 support_overlay_window(
false);
1882 _ime_active =
false;
1891 case WM_IME_COMPOSITION:
1903 HIMC hIMC = ImmGetContext(hwnd);
1904 nassertr(hIMC != 0, 0);
1906 DWORD result_size = 0;
1907 static const int ime_buffer_size = 256;
1908 static const int ime_buffer_size_bytes = ime_buffer_size /
sizeof(wchar_t);
1909 wchar_t ime_buffer[ime_buffer_size];
1910 size_t cursor_pos, delta_start;
1912 if (lparam & GCS_RESULTSTR) {
1913 result_size = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR,
1914 ime_buffer, ime_buffer_size_bytes);
1915 size_t num_chars = result_size /
sizeof(wchar_t);
1916 for (
size_t i = 0; i < num_chars; ++i) {
1921 if (lparam & GCS_COMPSTR) {
1922 result_size = ImmGetCompositionStringW(hIMC, GCS_CURSORPOS,
nullptr, 0);
1923 cursor_pos = result_size & 0xffff;
1925 result_size = ImmGetCompositionStringW(hIMC, GCS_DELTASTART,
nullptr, 0);
1926 delta_start = result_size & 0xffff;
1927 result_size = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, ime_buffer, ime_buffer_size);
1928 size_t num_chars = result_size /
sizeof(wchar_t);
1930 _input->
candidate(wstring(ime_buffer, num_chars),
1931 std::min(cursor_pos, delta_start),
1932 std::max(cursor_pos, delta_start),
1935 ImmReleaseContext(hwnd, hIMC);
1956 if (_lost_keypresses) {
1957 resend_lost_keypresses();
1959 if (windisplay_cat.is_debug()) {
1960 windisplay_cat.debug()
1961 <<
"syskeydown: " << wparam <<
" (" << lookup_key(wparam) <<
")\n";
1967 GetCursorPos(&point);
1968 ScreenToClient(hwnd, &point);
1969 handle_keypress(lookup_key(wparam), point.x, point.y,
1970 get_message_time());
1972 if ((lparam & 0x40000000) == 0) {
1973 handle_raw_keypress(lookup_raw_key(lparam), get_message_time());
1984 if (wparam == VK_MENU) {
1985 if ((GetKeyState(VK_LMENU) & 0x8000) != 0 && ! _lalt_down) {
1986 handle_keypress(KeyboardButton::lalt(), point.x, point.y,
1987 get_message_time());
1990 if ((GetKeyState(VK_RMENU) & 0x8000) != 0 && ! _ralt_down) {
1991 handle_keypress(KeyboardButton::ralt(), point.x, point.y,
1992 get_message_time());
1996 if (wparam == VK_F10) {
2005 if (wparam == SC_KEYMENU) {
2017 if (_lost_keypresses) {
2018 resend_lost_keypresses();
2020 if (windisplay_cat.is_debug()) {
2021 windisplay_cat.debug()
2022 <<
"keydown: " << wparam <<
" (" << lookup_key(wparam) <<
")\n";
2027 if ((lparam & 0x40000000) == 0) {
2029 GetCursorPos(&point);
2030 ScreenToClient(hwnd, &point);
2031 handle_keypress(lookup_key(wparam), point.x, point.y,
2032 get_message_time());
2033 handle_raw_keypress(lookup_raw_key(lparam), get_message_time());
2039 if (wparam == VK_SHIFT) {
2040 if ((GetKeyState(VK_LSHIFT) & 0x8000) != 0 && ! _lshift_down) {
2041 handle_keypress(KeyboardButton::lshift(), point.x, point.y,
2042 get_message_time());
2043 _lshift_down =
true;
2045 if ((GetKeyState(VK_RSHIFT) & 0x8000) != 0 && ! _rshift_down) {
2046 handle_keypress(KeyboardButton::rshift(), point.x, point.y,
2047 get_message_time());
2048 _rshift_down =
true;
2050 }
else if(wparam == VK_CONTROL) {
2051 if ((GetKeyState(VK_LCONTROL) & 0x8000) != 0 && ! _lcontrol_down) {
2052 handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
2053 get_message_time());
2054 _lcontrol_down =
true;
2056 if ((GetKeyState(VK_RCONTROL) & 0x8000) != 0 && ! _rcontrol_down) {
2057 handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
2058 get_message_time());
2059 _rcontrol_down =
true;
2065 if ((wparam==
'V') && (GetKeyState(VK_CONTROL) < 0) &&
2066 !_input_devices.empty() && paste_emit_keystrokes) {
2070 if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(
nullptr)) {
2072 hglb = GetClipboardData(CF_TEXT);
2073 if (hglb!=
nullptr) {
2074 lptstr = (
char *) GlobalLock(hglb);
2075 if (lptstr !=
nullptr) {
2077 for (pChar = lptstr; *pChar; pChar++) {
2090 GetCursorPos(&point);
2091 ScreenToClient(hwnd, &point);
2092 handle_keypress(lookup_key(wparam), point.x, point.y,
2093 get_message_time());
2106 if (wparam == VK_SHIFT) {
2107 if (((GetKeyState(VK_LSHIFT) & 0x8000) != 0) && ! _lshift_down ) {
2108 handle_keypress(KeyboardButton::lshift(), point.x, point.y,
2109 get_message_time());
2110 _lshift_down =
true;
2111 }
else if (((GetKeyState(VK_RSHIFT) & 0x8000) != 0) && ! _rshift_down ) {
2112 handle_keypress(KeyboardButton::rshift(), point.x, point.y,
2113 get_message_time());
2114 _rshift_down =
true;
2116 if ((GetKeyState(VK_LSHIFT) & 0x8000) != 0) {
2117 handle_keypress(KeyboardButton::lshift(), point.x, point.y,
2118 get_message_time());
2120 if ((GetKeyState(VK_RSHIFT) & 0x8000) != 0) {
2121 handle_keypress(KeyboardButton::rshift(), point.x, point.y,
2122 get_message_time());
2125 }
else if(wparam == VK_CONTROL) {
2126 if (((GetKeyState(VK_LCONTROL) & 0x8000) != 0) && ! _lcontrol_down ) {
2127 handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
2128 get_message_time());
2129 _lcontrol_down =
true;
2130 }
else if (((GetKeyState(VK_RCONTROL) & 0x8000) != 0) && ! _rcontrol_down ) {
2131 handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
2132 get_message_time());
2133 _rcontrol_down =
true;
2135 if ((GetKeyState(VK_LCONTROL) & 0x8000) != 0) {
2136 handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
2137 get_message_time());
2139 if ((GetKeyState(VK_RCONTROL) & 0x8000) != 0) {
2140 handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
2141 get_message_time());
2150 if (_lost_keypresses) {
2151 resend_lost_keypresses();
2153 if (windisplay_cat.is_debug()) {
2154 windisplay_cat.debug()
2155 <<
"keyup: " << wparam <<
" (" << lookup_key(wparam) <<
")\n";
2157 handle_keyrelease(lookup_key(wparam), get_message_time());
2158 handle_raw_keyrelease(lookup_raw_key(lparam), get_message_time());
2163 if (wparam == VK_SHIFT) {
2164 if ((GetKeyState(VK_LSHIFT) & 0x8000) == 0 && _lshift_down) {
2165 handle_keyrelease(KeyboardButton::lshift(), get_message_time());
2166 _lshift_down =
false;
2168 if ((GetKeyState(VK_RSHIFT) & 0x8000) == 0 && _rshift_down) {
2169 handle_keyrelease(KeyboardButton::rshift(), get_message_time());
2170 _rshift_down =
false;
2172 }
else if(wparam == VK_CONTROL) {
2173 if ((GetKeyState(VK_LCONTROL) & 0x8000) == 0 && _lcontrol_down) {
2174 handle_keyrelease(KeyboardButton::lcontrol(), get_message_time());
2175 _lcontrol_down =
false;
2177 if ((GetKeyState(VK_RCONTROL) & 0x8000) == 0 && _rcontrol_down) {
2178 handle_keyrelease(KeyboardButton::rcontrol(), get_message_time());
2179 _rcontrol_down =
false;
2181 }
else if(wparam == VK_MENU) {
2182 if ((GetKeyState(VK_LMENU) & 0x8000) == 0 && _lalt_down) {
2183 handle_keyrelease(KeyboardButton::lalt(), get_message_time());
2186 if ((GetKeyState(VK_RMENU) & 0x8000) == 0 && _ralt_down) {
2187 handle_keyrelease(KeyboardButton::ralt(), get_message_time());
2194 if (windisplay_cat.is_debug()) {
2195 windisplay_cat.debug()
2201 system_changed_properties(properties);
2223 if (windisplay_cat.is_debug()) {
2224 windisplay_cat.debug()
2228 if (_lost_keypresses) {
2229 resend_lost_keypresses();
2233 system_changed_properties(properties);
2237 if (windisplay_cat.is_debug()) {
2238 windisplay_cat.debug()
2242 system_changed_properties(properties);
2246 if (windisplay_cat.is_debug()) {
2247 windisplay_cat.debug()
2251 system_changed_properties(properties);
2257 if (windisplay_cat.is_debug()) {
2258 windisplay_cat.debug() <<
"DPI changed to " << LOWORD(wparam);
2260 if (LOWORD(wparam) != HIWORD(wparam)) {
2261 windisplay_cat.debug(
false) <<
"x" << HIWORD(wparam) <<
"\n";
2263 windisplay_cat.debug(
false) <<
"\n";
2268 if (!_properties.get_fixed_size() && dpi_window_resize) {
2269 RECT &rect = *(LPRECT)lparam;
2270 SetWindowPos(_hWnd, HWND_TOP, rect.left, rect.top,
2271 rect.right - rect.left, rect.bottom - rect.top,
2272 SWP_NOZORDER | SWP_NOACTIVATE);
2277 _num_touches = LOWORD(wparam);
2278 if (_num_touches > MAX_TOUCHES) {
2279 _num_touches = MAX_TOUCHES;
2281 if (pGetTouchInputInfo != 0) {
2282 pGetTouchInputInfo((HTOUCHINPUT)lparam, _num_touches, _touches,
sizeof(TOUCHINPUT));
2283 pCloseTouchInputHandle((HTOUCHINPUT)lparam);
2289 for ( WinProcClasses::iterator it=_window_proc_classes.begin() ; it != _window_proc_classes.end(); it++ ){
2290 (*it)->wnd_proc(
this, hwnd, msg, wparam, lparam);
2293 return DefWindowProcW(hwnd, msg, wparam, lparam);
2304 WindowHandles::const_iterator wi;
2305 wi = _window_handles.find(hwnd);
2306 if (wi != _window_handles.end()) {
2308 return (*wi).second->window_proc(hwnd, msg, wparam, lparam);
2312 if (_creating_window !=
nullptr) {
2313 return _creating_window->
window_proc(hwnd, msg, wparam, lparam);
2318 return DefWindowProcW(hwnd, msg, wparam, lparam);
2324void WinGraphicsWindow::
2328 if (!GetMessage(&msg,
nullptr, 0, 0)) {
2335 TranslateMessage(&msg);
2337 DispatchMessage(&msg);
2345void WinGraphicsWindow::
2346resend_lost_keypresses() {
2347 nassertv(_lost_keypresses);
2352 _lost_keypresses =
false;
2359void WinGraphicsWindow::
2361 bool hide_cursor =
false;
2362 if (to_window ==
nullptr) {
2365 if (_got_saved_params) {
2366 SystemParametersInfo(SPI_SETMOUSETRAILS, _saved_mouse_trails,
2368 SystemParametersInfo(SPI_SETCURSORSHADOW, 0,
2369 _saved_cursor_shadow ? (PVOID)1 : nullptr, 0);
2370 SystemParametersInfo(SPI_SETMOUSEVANISH, 0,
2371 _saved_mouse_vanish ? (PVOID)1 : nullptr, 0);
2372 _got_saved_params =
false;
2384 if (!_got_saved_params) {
2385 SystemParametersInfo(SPI_GETMOUSETRAILS, 0,
2386 &_saved_mouse_trails, 0);
2387 SystemParametersInfo(SPI_GETCURSORSHADOW, 0,
2388 &_saved_cursor_shadow, 0);
2389 SystemParametersInfo(SPI_GETMOUSEVANISH, 0,
2390 &_saved_mouse_vanish, 0);
2391 _got_saved_params =
true;
2393 SystemParametersInfo(SPI_SETMOUSETRAILS, 0, (PVOID)0, 0);
2394 SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)
false, 0);
2395 SystemParametersInfo(SPI_SETMOUSEVANISH, 0, (PVOID)
false, 0);
2398 SetCursor(to_window->_cursor);
2401 hide_or_show_cursor(hide_cursor);
2403 _cursor_window = to_window;
2411void WinGraphicsWindow::
2412hide_or_show_cursor(
bool hide_cursor) {
2414 if (!_cursor_hidden) {
2416 _cursor_hidden =
true;
2419 if (_cursor_hidden) {
2421 _cursor_hidden =
false;
2427#define MIN_REFRESH_RATE 60
2430#define ACCEPTABLE_REFRESH_RATE(RATE) ((RATE >= MIN_REFRESH_RATE) || (RATE==0) || (RATE==1))
2436bool WinGraphicsWindow::
2437find_acceptable_display_mode(DWORD dwWidth, DWORD dwHeight, DWORD bpp,
2442 ZeroMemory(&cur_dm,
sizeof(cur_dm));
2443 cur_dm.dmSize =
sizeof(cur_dm);
2444 EnumDisplaySettings(
nullptr, ENUM_CURRENT_SETTINGS, &cur_dm);
2447 int saved_modenum = -1;
2450 ZeroMemory(&dm,
sizeof(dm));
2451 dm.dmSize =
sizeof(dm);
2453 if (!EnumDisplaySettings(
nullptr, modenum, &dm)) {
2457 if ((dm.dmPelsWidth == dwWidth) && (dm.dmPelsHeight == dwHeight) &&
2458 (dm.dmBitsPerPel == bpp)) {
2461 if (dm.dmDisplayFrequency == cur_dm.dmDisplayFrequency) {
2463 }
else if (saved_modenum == -1) {
2464 saved_modenum = modenum;
2472 if (saved_modenum != -1) {
2473 ZeroMemory(&dm,
sizeof(dm));
2474 dm.dmSize =
sizeof(dm);
2476 if (EnumDisplaySettings(
nullptr, saved_modenum, &dm)) {
2488void WinGraphicsWindow::
2489show_error_message(DWORD message_id) {
2490 LPTSTR message_buffer;
2492 if (message_id == 0) {
2493 message_id = GetLastError();
2496 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
2497 nullptr, message_id,
2498 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2499 (LPTSTR)&message_buffer,
2501 MessageBox(GetDesktopWindow(), message_buffer, _T(errorbox_title), MB_OK);
2502 windisplay_cat.fatal() <<
"System error msg: " << message_buffer << endl;
2503 LocalFree(message_buffer);
2509void WinGraphicsWindow::
2510handle_keypress(
ButtonHandle key,
int x,
int y,
double time) {
2512 if (key != ButtonHandle::none()) {
2521void WinGraphicsWindow::
2523 if (key != ButtonHandle::none()) {
2531void WinGraphicsWindow::
2533 if (key != ButtonHandle::none()) {
2541void WinGraphicsWindow::
2543 if (key != ButtonHandle::none()) {
2551void WinGraphicsWindow::
2553 if (key != ButtonHandle::none()) {
2563lookup_key(WPARAM wparam)
const {
2568 case VK_BACK:
return KeyboardButton::backspace();
2569 case VK_DELETE:
return KeyboardButton::del();
2570 case VK_ESCAPE:
return KeyboardButton::escape();
2571 case VK_SPACE:
return KeyboardButton::space();
2572 case VK_UP:
return KeyboardButton::up();
2573 case VK_DOWN:
return KeyboardButton::down();
2574 case VK_LEFT:
return KeyboardButton::left();
2575 case VK_RIGHT:
return KeyboardButton::right();
2582 case VK_TAB:
return KeyboardButton::tab();
2583 case VK_PRIOR:
return KeyboardButton::page_up();
2584 case VK_NEXT:
return KeyboardButton::page_down();
2585 case VK_HOME:
return KeyboardButton::home();
2586 case VK_END:
return KeyboardButton::end();
2587 case VK_F1:
return KeyboardButton::f1();
2588 case VK_F2:
return KeyboardButton::f2();
2589 case VK_F3:
return KeyboardButton::f3();
2590 case VK_F4:
return KeyboardButton::f4();
2591 case VK_F5:
return KeyboardButton::f5();
2592 case VK_F6:
return KeyboardButton::f6();
2593 case VK_F7:
return KeyboardButton::f7();
2594 case VK_F8:
return KeyboardButton::f8();
2595 case VK_F9:
return KeyboardButton::f9();
2596 case VK_F10:
return KeyboardButton::f10();
2597 case VK_F11:
return KeyboardButton::f11();
2598 case VK_F12:
return KeyboardButton::f12();
2599 case VK_INSERT:
return KeyboardButton::insert();
2600 case VK_CAPITAL:
return KeyboardButton::caps_lock();
2601 case VK_NUMLOCK:
return KeyboardButton::num_lock();
2602 case VK_SCROLL:
return KeyboardButton::scroll_lock();
2603 case VK_PAUSE:
return KeyboardButton::pause();
2604 case VK_SNAPSHOT:
return KeyboardButton::print_screen();
2606 case VK_SHIFT:
return KeyboardButton::shift();
2607 case VK_LSHIFT:
return KeyboardButton::lshift();
2608 case VK_RSHIFT:
return KeyboardButton::rshift();
2610 case VK_CONTROL:
return KeyboardButton::control();
2611 case VK_LCONTROL:
return KeyboardButton::lcontrol();
2612 case VK_RCONTROL:
return KeyboardButton::rcontrol();
2614 case VK_MENU:
return KeyboardButton::alt();
2615 case VK_LMENU:
return KeyboardButton::lalt();
2616 case VK_RMENU:
return KeyboardButton::ralt();
2618 case VK_LWIN:
return KeyboardButton::lmeta();
2619 case VK_RWIN:
return KeyboardButton::rmeta();
2620 case VK_APPS:
return KeyboardButton::menu();
2623 int key = MapVirtualKey(wparam, 2);
2624 if (isascii(key) && key != 0) {
2639 return ButtonHandle::none();
2647lookup_raw_key(LPARAM lparam)
const {
2648 unsigned char vsc = (lparam & 0xff0000) >> 16;
2650 if (lparam & 0x1000000) {
2653 case 28:
return KeyboardButton::enter();
2654 case 29:
return KeyboardButton::rcontrol();
2656 case 55:
return KeyboardButton::print_screen();
2657 case 56:
return KeyboardButton::ralt();
2658 case 69:
return KeyboardButton::num_lock();
2659 case 71:
return KeyboardButton::home();
2660 case 72:
return KeyboardButton::up();
2661 case 73:
return KeyboardButton::page_up();
2662 case 75:
return KeyboardButton::left();
2663 case 77:
return KeyboardButton::right();
2664 case 79:
return KeyboardButton::end();
2665 case 80:
return KeyboardButton::down();
2666 case 81:
return KeyboardButton::page_down();
2667 case 82:
return KeyboardButton::insert();
2668 case 83:
return KeyboardButton::del();
2669 case 91:
return KeyboardButton::lmeta();
2670 case 92:
return KeyboardButton::rmeta();
2671 case 93:
return KeyboardButton::menu();
2677 ButtonHandle::none(),
2678 KeyboardButton::escape(),
2691 KeyboardButton::backspace(),
2692 KeyboardButton::tab(),
2705 KeyboardButton::enter(),
2706 KeyboardButton::lcontrol(),
2719 KeyboardButton::lshift(),
2731 KeyboardButton::rshift(),
2733 KeyboardButton::lalt(),
2734 KeyboardButton::space(),
2735 KeyboardButton::caps_lock(),
2736 KeyboardButton::f1(),
2737 KeyboardButton::f2(),
2738 KeyboardButton::f3(),
2739 KeyboardButton::f4(),
2740 KeyboardButton::f5(),
2741 KeyboardButton::f6(),
2742 KeyboardButton::f7(),
2743 KeyboardButton::f8(),
2744 KeyboardButton::f9(),
2745 KeyboardButton::f10(),
2746 KeyboardButton::pause(),
2747 KeyboardButton::scroll_lock(),
2762 return raw_map[vsc];
2768 case 87:
return KeyboardButton::f11();
2769 case 88:
return KeyboardButton::f12();
2770 default:
return ButtonHandle::none();
2782get_keyboard_map()
const {
2787 unsigned short ex_vsc[] = {0x56, 0x57, 0x58,
2788 0x011c, 0x011d, 0x0135, 0x0137, 0x0138, 0x0145, 0x0147, 0x0148, 0x0149, 0x014b, 0x014d, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x015b, 0x015c, 0x015d};
2790 for (
int k = 1; k < 84 +
sizeof(ex_vsc) /
sizeof(
short); ++k) {
2792 vsc = ex_vsc[k - 84];
2797 UINT lparam = vsc << 16;
2799 if (raw_button == ButtonHandle::none()) {
2805 button = KeyboardButton::pause();
2807 }
else if (vsc >= 0x47 && vsc <= 0x53) {
2809 button = raw_button;
2821 UINT vk = MapVirtualKeyA(vsc, MAPVK_VSC_TO_VK_EX);
2822 button = lookup_key(vk);
2828 int len = GetKeyNameTextW(lparam, text, 256);
2840void WinGraphicsWindow::
2841handle_raw_input(HRAWINPUT hraw) {
2848 if (GetRawInputData(hraw, RID_INPUT,
nullptr, &dwSize,
sizeof(RAWINPUTHEADER)) == -1) {
2852 lpb = (LPBYTE)alloca(
sizeof(LPBYTE) * dwSize);
2853 if (lpb ==
nullptr) {
2857 if (GetRawInputData(hraw, RID_INPUT, lpb, &dwSize,
sizeof(RAWINPUTHEADER)) != dwSize) {
2861 RAWINPUT *raw = (RAWINPUT *)lpb;
2862 if (raw->header.hDevice == 0) {
2866 for (
size_t i = 1; i < _input_devices.size(); ++i) {
2867 if (_input_device_handle[i] == raw->header.hDevice) {
2871 int adjx = raw->data.mouse.lLastX;
2872 int adjy = raw->data.mouse.lLastY;
2874 if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) {
2875 input->set_pointer_in_window(adjx, adjy);
2877 input->pointer_moved(adjx, adjy);
2880 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) {
2883 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) {
2886 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) {
2889 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) {
2892 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) {
2895 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) {
2898 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) {
2901 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) {
2904 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) {
2907 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) {
2917bool WinGraphicsWindow::
2918handle_mouse_motion(
int x,
int y) {
2926void WinGraphicsWindow::
2927handle_mouse_exit() {
2936HICON WinGraphicsWindow::
2937get_icon(
const Filename &filename) {
2939 IconFilenames::iterator fi = _icon_filenames.find(filename);
2940 if (fi != _icon_filenames.end()) {
2941 return (HICON)((*fi).second);
2955 windisplay_cat.warning()
2956 <<
"Could not find icon filename " << filename <<
"\n";
2960 fi = _icon_filenames.find(resolved);
2961 if (fi != _icon_filenames.end()) {
2962 _icon_filenames[filename] = (*fi).second;
2963 return (HICON)((*fi).second);
2968 HANDLE h = LoadImage(
nullptr, os.c_str(),
2969 IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);
2971 windisplay_cat.warning()
2972 <<
"windows icon filename '" << os <<
"' could not be loaded!!\n";
2975 _icon_filenames[filename] = h;
2976 _icon_filenames[resolved] = h;
2984HCURSOR WinGraphicsWindow::
2985get_cursor(
const Filename &filename) {
2987 if (filename.empty()) {
2992 IconFilenames::iterator fi = _cursor_filenames.find(filename);
2993 if (fi != _cursor_filenames.end()) {
2994 return (HCURSOR)((*fi).second);
3004 windisplay_cat.warning()
3005 <<
"Could not find cursor filename " << filename <<
"\n";
3008 fi = _cursor_filenames.find(resolved);
3009 if (fi != _cursor_filenames.end()) {
3010 _cursor_filenames[filename] = (*fi).second;
3011 return (HCURSOR)((*fi).second);
3016 HANDLE h = LoadImage(
nullptr, os.c_str(),
3017 IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
3019 windisplay_cat.warning()
3020 <<
"windows cursor filename '" << os <<
"' could not be loaded!!\n";
3021 show_error_message();
3024 _cursor_filenames[filename] = h;
3025 _cursor_filenames[resolved] = h;
3029static HCURSOR get_cursor(
const Filename &filename);
3035const WinGraphicsWindow::WindowClass &WinGraphicsWindow::
3037 WindowClass wcreg(props);
3038 std::wostringstream wclass_name;
3039 wclass_name << L
"WinGraphicsWindow" << _window_class_index;
3040 wcreg._name = wclass_name.str();
3042 std::pair<WindowClasses::iterator, bool> found = _window_classes.insert(wcreg);
3043 const WindowClass &wclass = (*found.first);
3045 if (!found.second) {
3051 _window_class_index++;
3055 HINSTANCE instance = GetModuleHandle(
nullptr);
3058 ZeroMemory(&wc,
sizeof(wc));
3059 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
3061 wc.hInstance = instance;
3063 wc.hIcon = wclass._icon;
3065 wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
3066 wc.lpszMenuName =
nullptr;
3067 wc.lpszClassName = wclass._name.c_str();
3069 if (!RegisterClassW(&wc)) {
3070 windisplay_cat.error()
3071 <<
"could not register window class " << wclass._name <<
"!" << endl;
3081WinGraphicsWindow::WinWindowHandle::
3093void WinGraphicsWindow::WinWindowHandle::
3102void WinGraphicsWindow::WinWindowHandle::
3103receive_windows_message(
unsigned int msg,
int wparam,
int lparam) {
3104 if (_window !=
nullptr) {
3111void PrintErrorMessage(DWORD msgID) {
3112 LPTSTR pMessageBuffer;
3114 if (msgID==PRINT_LAST_ERROR)
3115 msgID=GetLastError();
3117 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
3119 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
3120 (LPTSTR) &pMessageBuffer,
3122 MessageBox(GetDesktopWindow(),pMessageBuffer,_T(errorbox_title),MB_OK);
3123 windisplay_cat.fatal() <<
"System error msg: " << pMessageBuffer << endl;
3124 LocalFree( pMessageBuffer );
3130 if (windisplay_cat.is_debug()) {
3131 windisplay_cat.debug()
3132 <<
"Skipping ClearToBlack, no origin specified yet.\n";
3137 if (windisplay_cat.is_debug()) {
3138 windisplay_cat.debug()
3139 <<
"ClearToBlack(" << hWnd <<
", " << props <<
")\n";
3142 HDC hDC=GetDC(hWnd);
3148 FillRect(hDC,&clrRect,(HBRUSH)GetStockObject(BLACK_BRUSH));
3149 ReleaseDC(hWnd,hDC);
3158 GetClientRect(hwnd, view_rect);
3161 ul.x = view_rect->left;
3162 ul.y = view_rect->top;
3163 lr.x = view_rect->right;
3164 lr.y = view_rect->bottom;
3166 ClientToScreen(hwnd, &ul);
3167 ClientToScreen(hwnd, &lr);
3169 view_rect->left = ul.x;
3170 view_rect->top = ul.y;
3171 view_rect->right = lr.x;
3172 view_rect->bottom = lr.y;
3181 nassertv(wnd_proc !=
nullptr);
3190 nassertv(wnd_proc !=
nullptr);
3199 _window_proc_classes.clear();
3216 return callbackData->get_msg() == WM_TOUCH;
3225 return _num_touches;
3234 nassertr(index >= 0 && index < MAX_TOUCHES,
TouchInfo());
3236 TOUCHINPUT ti = _touches[index];
3238 point.x = TOUCH_COORD_TO_PIXEL(ti.x);
3239 point.y = TOUCH_COORD_TO_PIXEL(ti.y);
3240 ScreenToClient(_hWnd, &point);
3245 ret.set_id(ti.dwID);
3246 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 physical 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.
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.
has_size
Returns true if the window size has been specified, false otherwise.
clear_title
Removes the title specification from the properties.
clear_origin
Removes the origin 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...
clear_size
Removes the size specification from the properties.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EXPCL_PANDAWIN 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 ...