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;
69WinGraphicsWindow::IconFilenames WinGraphicsWindow::_icon_filenames;
70WinGraphicsWindow::IconFilenames WinGraphicsWindow::_cursor_filenames;
72WinGraphicsWindow::WindowClasses WinGraphicsWindow::_window_classes;
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);
182 _input->set_pointer_in_window(x, 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));
659 PT(GraphicsWindowInputDevice) device =
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;
710 PT(GraphicsWindowInputDevice) device = GraphicsWindowInputDevice::pointer_only(
this, psName);
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";
867 WindowProperties properties;
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)) {
947 WindowProperties props(_properties);
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();
974 WindowProperties props(_properties);
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()) {
1125 TextEncoder encoder;
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";
1150 WindowHandle::OSHandle *os_handle = window_handle->
get_os_handle();
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())) {
1159 NativeWindowHandle::IntHandle *int_handle = DCAST(NativeWindowHandle::IntHandle, os_handle);
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);
1199 WindowProperties properties;
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 if (_in_adjust_z_order) {
1317 bool do_change =
false;
1319 switch (this_z_order) {
1320 case WindowProperties::Z_bottom:
1321 order = HWND_BOTTOM;
1325 case WindowProperties::Z_normal:
1326 if ((last_z_order != WindowProperties::Z_normal) &&
1328 (last_z_order != WindowProperties::Z_bottom ||
1329 _properties.get_foreground())
1334 order = HWND_NOTOPMOST;
1339 case WindowProperties::Z_top:
1340 order = HWND_TOPMOST;
1345 _in_adjust_z_order =
true;
1346 BOOL result = SetWindowPos(_hWnd, order, 0,0,0,0,
1347 SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE);
1348 _in_adjust_z_order =
false;
1350 windisplay_cat.warning()
1351 <<
"SetWindowPos failed.\n";
1361void WinGraphicsWindow::
1362track_mouse_leaving(HWND hwnd) {
1363 WinGraphicsPipe *winpipe;
1364 DCAST_INTO_V(winpipe, _pipe);
1366 TRACKMOUSEEVENT tme = {
1367 sizeof(TRACKMOUSEEVENT),
1374 BOOL bSucceeded = TrackMouseEvent(&tme);
1376 if (!bSucceeded && windisplay_cat.is_debug()) {
1377 windisplay_cat.debug()
1378 <<
"TrackMouseEvent failed!, LastError=" << GetLastError() << endl;
1381 _tracking_mouse_leaving =
true;
1387bool WinGraphicsWindow::
1392 windisplay_cat.info()
1393 <<
"ClipCursor() to " << clip.left <<
"," << clip.top <<
" to "
1394 << clip.right <<
"," << clip.bottom << endl;
1396 if (!ClipCursor(&clip)) {
1397 windisplay_cat.warning()
1398 <<
"Failed to confine cursor to window.\n";
1409void WinGraphicsWindow::
1411 if (SetFocus(_hWnd) ==
nullptr && GetLastError() != 0) {
1417 if (_parent_window_handle !=
nullptr && _window_handle !=
nullptr) {
1418 _parent_window_handle->request_keyboard_focus(_window_handle);
1421 windisplay_cat.error()
1422 <<
"SetFocus failed: " << GetLastError() <<
"\n";
1448window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
1449 if (windisplay_cat.is_spam()) {
1450 windisplay_cat.spam()
1452 <<
" window_proc(" << (
void *)
this <<
", " << hwnd <<
", "
1453 << msg <<
", " << wparam <<
", " << lparam <<
")\n";
1459 if (!_tracking_mouse_leaving) {
1461 track_mouse_leaving(hwnd);
1463 set_cursor_in_window();
1464 if(handle_mouse_motion(translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam))))
1469 handle_raw_input((HRAWINPUT)lparam);
1473 _tracking_mouse_leaving =
false;
1474 handle_mouse_exit();
1475 set_cursor_out_of_window();
1480 track_mouse_leaving(hwnd);
1481 ClearToBlack(hwnd, _properties);
1484 GetCursorPos(&cpos);
1485 ScreenToClient(hwnd, &cpos);
1487 GetClientRect(hwnd, &clientRect);
1488 if (PtInRect(&clientRect,cpos)) {
1489 set_cursor_in_window();
1491 set_cursor_out_of_window();
1524 if (!close_request_event.empty()) {
1527 throw_event(close_request_event);
1535 system_changed_properties(properties);
1542 case WM_CHILDACTIVATE:
1543 if (windisplay_cat.is_debug()) {
1544 windisplay_cat.debug()
1545 <<
"WM_CHILDACTIVATE: " << hwnd <<
"\n";
1550 if (windisplay_cat.is_debug()) {
1551 windisplay_cat.debug()
1552 <<
"WM_ACTIVATE: " << hwnd <<
", " << wparam <<
", " << lparam <<
"\n";
1555 if ((wparam & 0xffff) != WA_INACTIVE)
1563 ChangeDisplaySettings(&_fullscreen_display_mode, CDS_FULLSCREEN);
1564 if (chg_result != DISP_CHANGE_SUCCESSFUL) {
1565 const DEVMODE &dm = _fullscreen_display_mode;
1566 windisplay_cat.error()
1567 <<
"restore ChangeDisplaySettings failed (error code: "
1568 << chg_result <<
") for specified res: "
1569 << dm.dmPelsWidth <<
" x " << dm.dmPelsHeight
1570 <<
" x " << dm.dmBitsPerPel <<
", "
1571 << dm.dmDisplayFrequency <<
" Hz\n";
1575 SetWindowPos(_hWnd, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER);
1576 fullscreen_restored(properties);
1580 if (_properties.has_mouse_mode() &&
1581 _properties.get_mouse_mode() == WindowProperties::M_confined) {
1582 if (!confine_cursor()) {
1599 ShowWindow(_hWnd, SW_MINIMIZE);
1601 do_fullscreen_disable();
1602 fullscreen_minimized(properties);
1607 system_changed_properties(properties);
1613 if (windisplay_cat.is_debug()) {
1614 windisplay_cat.debug()
1615 <<
"WM_SIZE: " << hwnd <<
", " << wparam <<
"\n";
1619 case WM_EXITSIZEMOVE:
1620 if (windisplay_cat.is_debug()) {
1621 windisplay_cat.debug()
1622 <<
"WM_EXITSIZEMOVE: " << hwnd <<
", " << wparam <<
"\n";
1626 if (_properties.has_mouse_mode() &&
1627 _properties.get_mouse_mode() == WindowProperties::M_confined) {
1632 case WM_WINDOWPOSCHANGED:
1633 if (windisplay_cat.is_debug()) {
1634 windisplay_cat.debug()
1635 <<
"WM_WINDOWPOSCHANGED: " << hwnd <<
", " << wparam <<
"\n";
1637 if (_hWnd !=
nullptr) {
1640 if (!_in_adjust_z_order) {
1649 if (GetUpdateRect(_hWnd,
nullptr,
false)) {
1650 if (windisplay_cat.is_spam()) {
1651 windisplay_cat.spam()
1652 <<
"Got update regions: " <<
this <<
"\n";
1654 _got_expose_event =
true;
1658 case WM_LBUTTONDOWN:
1659 if (_lost_keypresses) {
1660 resend_lost_keypresses();
1663 _input->set_pointer_in_window(translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam)));
1670 case WM_MBUTTONDOWN:
1671 if (_lost_keypresses) {
1672 resend_lost_keypresses();
1675 _input->set_pointer_in_window(translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam)));
1681 case WM_RBUTTONDOWN:
1682 if (_lost_keypresses) {
1683 resend_lost_keypresses();
1686 _input->set_pointer_in_window(translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam)));
1692 case WM_XBUTTONDOWN:
1694 if (_lost_keypresses) {
1695 resend_lost_keypresses();
1698 int whichButton = GET_XBUTTON_WPARAM(wparam);
1699 _input->set_pointer_in_window(translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam)));
1700 if (whichButton == XBUTTON1) {
1702 }
else if (whichButton == XBUTTON2) {
1709 if (_lost_keypresses) {
1710 resend_lost_keypresses();
1719 if (_lost_keypresses) {
1720 resend_lost_keypresses();
1729 if (_lost_keypresses) {
1730 resend_lost_keypresses();
1740 if (_lost_keypresses) {
1741 resend_lost_keypresses();
1746 int whichButton = GET_XBUTTON_WPARAM(wparam);
1747 if (whichButton == XBUTTON1) {
1749 }
else if (whichButton == XBUTTON2) {
1757 int delta = GET_WHEEL_DELTA_WPARAM(wparam);
1760 GetCursorPos(&point);
1761 ScreenToClient(hwnd, &point);
1762 double time = get_message_time();
1768 delta -= WHEEL_DELTA;
1774 delta += WHEEL_DELTA;
1781 case WM_MOUSEHWHEEL:
1783 int delta = GET_WHEEL_DELTA_WPARAM(wparam);
1786 GetCursorPos(&point);
1787 ScreenToClient(hwnd, &point);
1788 double time = get_message_time();
1794 delta -= WHEEL_DELTA;
1800 delta += WHEEL_DELTA;
1807 case WM_IME_SETCONTEXT:
1811 windisplay_cat.debug() <<
"hwnd = " << hwnd <<
" and GetFocus = " << GetFocus() << endl;
1812 _ime_hWnd = ImmGetDefaultIMEWnd(hwnd);
1813 if (::SendMessage(_ime_hWnd, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0))
1815 windisplay_cat.debug() <<
"SendMessage failed for " << _ime_hWnd << endl;
1817 windisplay_cat.debug() <<
"SendMessage Succeeded for " << _ime_hWnd << endl;
1819 windisplay_cat.debug() <<
"wparam is " << wparam <<
", lparam is " << lparam << endl;
1820 lparam &= ~ISC_SHOWUIALL;
1821 if (ImmIsUIMessage(_ime_hWnd, msg, wparam, lparam))
1822 windisplay_cat.debug() <<
"wparam is " << wparam <<
", lparam is " << lparam << endl;
1828 if (wparam == IMN_SETOPENSTATUS) {
1829 HIMC hIMC = ImmGetContext(hwnd);
1830 nassertr(hIMC != 0, 0);
1831 _ime_open = (ImmGetOpenStatus(hIMC) != 0);
1833 _ime_active =
false;
1837 COMPOSITIONFORM comf;
1839 ImmGetCompositionWindow(hIMC, &comf);
1840 ImmGetCandidateWindow(hIMC, 0, &canf);
1841 windisplay_cat.debug() <<
1842 "comf style " << comf.dwStyle <<
1843 " comf point: x" << comf.ptCurrentPos.x <<
",y " << comf.ptCurrentPos.y <<
1844 " comf rect: l " << comf.rcArea.left <<
",t " << comf.rcArea.top <<
",r " <<
1845 comf.rcArea.right <<
",b " << comf.rcArea.bottom << endl;
1846 windisplay_cat.debug() <<
1847 "canf style " << canf.dwStyle <<
1848 " canf point: x" << canf.ptCurrentPos.x <<
",y " << canf.ptCurrentPos.y <<
1849 " canf rect: l " << canf.rcArea.left <<
",t " << canf.rcArea.top <<
",r " <<
1850 canf.rcArea.right <<
",b " << canf.rcArea.bottom << endl;
1851 comf.dwStyle = CFS_POINT;
1852 comf.ptCurrentPos.x = 2000;
1853 comf.ptCurrentPos.y = 2000;
1855 canf.dwStyle = CFS_EXCLUDE;
1857 canf.ptCurrentPos.x = 0;
1858 canf.ptCurrentPos.y = 0;
1859 canf.rcArea.left = 0;
1860 canf.rcArea.top = 0;
1861 canf.rcArea.right = 640;
1862 canf.rcArea.bottom = 480;
1865 comf.rcArea.left = 200;
1866 comf.rcArea.top = 200;
1867 comf.rcArea.right = 0;
1868 comf.rcArea.bottom = 0;
1871 if (ImmSetCompositionWindow(hIMC, &comf))
1872 windisplay_cat.debug() <<
"set composition form: success\n";
1873 for (
int i=0; i<3; ++i) {
1874 if (ImmSetCandidateWindow(hIMC, &canf))
1875 windisplay_cat.debug() <<
"set candidate form: success\n";
1880 ImmReleaseContext(hwnd, hIMC);
1884 case WM_IME_STARTCOMPOSITION:
1885 support_overlay_window(
true);
1889 case WM_IME_ENDCOMPOSITION:
1890 support_overlay_window(
false);
1891 _ime_active =
false;
1895 _input->candidate(ws, 0, 0, 0);
1900 case WM_IME_COMPOSITION:
1912 HIMC hIMC = ImmGetContext(hwnd);
1913 nassertr(hIMC != 0, 0);
1915 DWORD result_size = 0;
1916 static const int ime_buffer_size = 256;
1917 static const int ime_buffer_size_bytes = ime_buffer_size /
sizeof(wchar_t);
1918 wchar_t ime_buffer[ime_buffer_size];
1919 size_t cursor_pos, delta_start;
1921 if (lparam & GCS_RESULTSTR) {
1922 result_size = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR,
1923 ime_buffer, ime_buffer_size_bytes);
1924 size_t num_chars = result_size /
sizeof(wchar_t);
1925 for (
size_t i = 0; i < num_chars; ++i) {
1926 _input->keystroke(ime_buffer[i]);
1930 if (lparam & GCS_COMPSTR) {
1931 result_size = ImmGetCompositionStringW(hIMC, GCS_CURSORPOS,
nullptr, 0);
1932 cursor_pos = result_size & 0xffff;
1934 result_size = ImmGetCompositionStringW(hIMC, GCS_DELTASTART,
nullptr, 0);
1935 delta_start = result_size & 0xffff;
1936 result_size = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, ime_buffer, ime_buffer_size);
1937 size_t num_chars = result_size /
sizeof(wchar_t);
1939 _input->candidate(wstring(ime_buffer, num_chars),
1940 std::min(cursor_pos, delta_start),
1941 std::max(cursor_pos, delta_start),
1944 ImmReleaseContext(hwnd, hIMC);
1960 _input->keystroke(wparam);
1965 if (_lost_keypresses) {
1966 resend_lost_keypresses();
1968 if (windisplay_cat.is_debug()) {
1969 windisplay_cat.debug()
1970 <<
"syskeydown: " << wparam <<
" (" << lookup_key(wparam) <<
")\n";
1976 GetCursorPos(&point);
1977 ScreenToClient(hwnd, &point);
1978 handle_keypress(lookup_key(wparam), point.x, point.y,
1979 get_message_time());
1981 if ((lparam & 0x40000000) == 0) {
1982 handle_raw_keypress(lookup_raw_key(lparam), get_message_time());
1993 if (wparam == VK_MENU) {
1994 if ((GetKeyState(VK_LMENU) & 0x8000) != 0 && ! _lalt_down) {
1995 handle_keypress(KeyboardButton::lalt(), point.x, point.y,
1996 get_message_time());
1999 if ((GetKeyState(VK_RMENU) & 0x8000) != 0 && ! _ralt_down) {
2000 handle_keypress(KeyboardButton::ralt(), point.x, point.y,
2001 get_message_time());
2005 if (wparam == VK_F10) {
2014 if (wparam == SC_KEYMENU) {
2026 if (_lost_keypresses) {
2027 resend_lost_keypresses();
2029 if (windisplay_cat.is_debug()) {
2030 windisplay_cat.debug()
2031 <<
"keydown: " << wparam <<
" (" << lookup_key(wparam) <<
")\n";
2036 if ((lparam & 0x40000000) == 0) {
2038 GetCursorPos(&point);
2039 ScreenToClient(hwnd, &point);
2040 handle_keypress(lookup_key(wparam), point.x, point.y,
2041 get_message_time());
2042 handle_raw_keypress(lookup_raw_key(lparam), get_message_time());
2048 if (wparam == VK_SHIFT) {
2049 if ((GetKeyState(VK_LSHIFT) & 0x8000) != 0 && ! _lshift_down) {
2050 handle_keypress(KeyboardButton::lshift(), point.x, point.y,
2051 get_message_time());
2052 _lshift_down =
true;
2054 if ((GetKeyState(VK_RSHIFT) & 0x8000) != 0 && ! _rshift_down) {
2055 handle_keypress(KeyboardButton::rshift(), point.x, point.y,
2056 get_message_time());
2057 _rshift_down =
true;
2059 }
else if(wparam == VK_CONTROL) {
2060 if ((GetKeyState(VK_LCONTROL) & 0x8000) != 0 && ! _lcontrol_down) {
2061 handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
2062 get_message_time());
2063 _lcontrol_down =
true;
2065 if ((GetKeyState(VK_RCONTROL) & 0x8000) != 0 && ! _rcontrol_down) {
2066 handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
2067 get_message_time());
2068 _rcontrol_down =
true;
2074 if ((wparam==
'V') && (GetKeyState(VK_CONTROL) < 0) &&
2075 !_input_devices.empty() && paste_emit_keystrokes) {
2079 if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(
nullptr)) {
2081 hglb = GetClipboardData(CF_TEXT);
2082 if (hglb!=
nullptr) {
2083 lptstr = (
char *) GlobalLock(hglb);
2084 if (lptstr !=
nullptr) {
2086 for (pChar = lptstr; *pChar; pChar++) {
2087 _input->keystroke((uchar)*pChar);
2099 GetCursorPos(&point);
2100 ScreenToClient(hwnd, &point);
2101 handle_keypress(lookup_key(wparam), point.x, point.y,
2102 get_message_time());
2115 if (wparam == VK_SHIFT) {
2116 if (((GetKeyState(VK_LSHIFT) & 0x8000) != 0) && ! _lshift_down ) {
2117 handle_keypress(KeyboardButton::lshift(), point.x, point.y,
2118 get_message_time());
2119 _lshift_down =
true;
2120 }
else if (((GetKeyState(VK_RSHIFT) & 0x8000) != 0) && ! _rshift_down ) {
2121 handle_keypress(KeyboardButton::rshift(), point.x, point.y,
2122 get_message_time());
2123 _rshift_down =
true;
2125 if ((GetKeyState(VK_LSHIFT) & 0x8000) != 0) {
2126 handle_keypress(KeyboardButton::lshift(), point.x, point.y,
2127 get_message_time());
2129 if ((GetKeyState(VK_RSHIFT) & 0x8000) != 0) {
2130 handle_keypress(KeyboardButton::rshift(), point.x, point.y,
2131 get_message_time());
2134 }
else if(wparam == VK_CONTROL) {
2135 if (((GetKeyState(VK_LCONTROL) & 0x8000) != 0) && ! _lcontrol_down ) {
2136 handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
2137 get_message_time());
2138 _lcontrol_down =
true;
2139 }
else if (((GetKeyState(VK_RCONTROL) & 0x8000) != 0) && ! _rcontrol_down ) {
2140 handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
2141 get_message_time());
2142 _rcontrol_down =
true;
2144 if ((GetKeyState(VK_LCONTROL) & 0x8000) != 0) {
2145 handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
2146 get_message_time());
2148 if ((GetKeyState(VK_RCONTROL) & 0x8000) != 0) {
2149 handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
2150 get_message_time());
2159 if (_lost_keypresses) {
2160 resend_lost_keypresses();
2162 if (windisplay_cat.is_debug()) {
2163 windisplay_cat.debug()
2164 <<
"keyup: " << wparam <<
" (" << lookup_key(wparam) <<
")\n";
2166 handle_keyrelease(lookup_key(wparam), get_message_time());
2167 handle_raw_keyrelease(lookup_raw_key(lparam), get_message_time());
2172 if (wparam == VK_SHIFT) {
2173 if ((GetKeyState(VK_LSHIFT) & 0x8000) == 0 && _lshift_down) {
2174 handle_keyrelease(KeyboardButton::lshift(), get_message_time());
2175 _lshift_down =
false;
2177 if ((GetKeyState(VK_RSHIFT) & 0x8000) == 0 && _rshift_down) {
2178 handle_keyrelease(KeyboardButton::rshift(), get_message_time());
2179 _rshift_down =
false;
2181 }
else if(wparam == VK_CONTROL) {
2182 if ((GetKeyState(VK_LCONTROL) & 0x8000) == 0 && _lcontrol_down) {
2183 handle_keyrelease(KeyboardButton::lcontrol(), get_message_time());
2184 _lcontrol_down =
false;
2186 if ((GetKeyState(VK_RCONTROL) & 0x8000) == 0 && _rcontrol_down) {
2187 handle_keyrelease(KeyboardButton::rcontrol(), get_message_time());
2188 _rcontrol_down =
false;
2190 }
else if(wparam == VK_MENU) {
2191 if ((GetKeyState(VK_LMENU) & 0x8000) == 0 && _lalt_down) {
2192 handle_keyrelease(KeyboardButton::lalt(), get_message_time());
2195 if ((GetKeyState(VK_RMENU) & 0x8000) == 0 && _ralt_down) {
2196 handle_keyrelease(KeyboardButton::ralt(), get_message_time());
2203 if (windisplay_cat.is_debug()) {
2204 windisplay_cat.debug()
2208 _input->focus_lost(get_message_time());
2210 system_changed_properties(properties);
2232 if (windisplay_cat.is_debug()) {
2233 windisplay_cat.debug()
2237 if (_lost_keypresses) {
2238 resend_lost_keypresses();
2242 system_changed_properties(properties);
2246 if (windisplay_cat.is_debug()) {
2247 windisplay_cat.debug()
2251 system_changed_properties(properties);
2255 if (windisplay_cat.is_debug()) {
2256 windisplay_cat.debug()
2260 system_changed_properties(properties);
2266 if (windisplay_cat.is_debug()) {
2267 windisplay_cat.debug() <<
"DPI changed to " << LOWORD(wparam);
2269 if (LOWORD(wparam) != HIWORD(wparam)) {
2270 windisplay_cat.debug(
false) <<
"x" << HIWORD(wparam) <<
"\n";
2272 windisplay_cat.debug(
false) <<
"\n";
2277 if (!_properties.get_fixed_size() && dpi_window_resize) {
2278 RECT &rect = *(LPRECT)lparam;
2279 SetWindowPos(_hWnd, HWND_TOP, rect.left, rect.top,
2280 rect.right - rect.left, rect.bottom - rect.top,
2281 SWP_NOZORDER | SWP_NOACTIVATE);
2286 _num_touches = LOWORD(wparam);
2287 if (_num_touches > MAX_TOUCHES) {
2288 _num_touches = MAX_TOUCHES;
2290 if (pGetTouchInputInfo != 0) {
2291 pGetTouchInputInfo((HTOUCHINPUT)lparam, _num_touches, _touches,
sizeof(TOUCHINPUT));
2292 pCloseTouchInputHandle((HTOUCHINPUT)lparam);
2298 for ( WinProcClasses::iterator it=_window_proc_classes.begin() ; it != _window_proc_classes.end(); it++ ){
2299 (*it)->wnd_proc(
this, hwnd, msg, wparam, lparam);
2302 return DefWindowProcW(hwnd, msg, wparam, lparam);
2313 WindowHandles::const_iterator wi;
2314 wi = _window_handles.find(hwnd);
2315 if (wi != _window_handles.end()) {
2317 return (*wi).second->window_proc(hwnd, msg, wparam, lparam);
2321 if (_creating_window !=
nullptr) {
2322 return _creating_window->window_proc(hwnd, msg, wparam, lparam);
2327 return DefWindowProcW(hwnd, msg, wparam, lparam);
2333void WinGraphicsWindow::
2337 if (!GetMessage(&msg,
nullptr, 0, 0)) {
2344 TranslateMessage(&msg);
2346 DispatchMessage(&msg);
2354void WinGraphicsWindow::
2355resend_lost_keypresses() {
2356 nassertv(_lost_keypresses);
2361 _lost_keypresses =
false;
2368void WinGraphicsWindow::
2370 bool hide_cursor =
false;
2371 if (to_window ==
nullptr) {
2374 if (_got_saved_params) {
2375 SystemParametersInfo(SPI_SETMOUSETRAILS, _saved_mouse_trails,
2377 SystemParametersInfo(SPI_SETCURSORSHADOW, 0,
2378 _saved_cursor_shadow ? (PVOID)1 :
nullptr, 0);
2379 SystemParametersInfo(SPI_SETMOUSEVANISH, 0,
2380 _saved_mouse_vanish ? (PVOID)1 :
nullptr, 0);
2381 _got_saved_params =
false;
2393 if (!_got_saved_params) {
2394 SystemParametersInfo(SPI_GETMOUSETRAILS, 0,
2395 &_saved_mouse_trails, 0);
2396 SystemParametersInfo(SPI_GETCURSORSHADOW, 0,
2397 &_saved_cursor_shadow, 0);
2398 SystemParametersInfo(SPI_GETMOUSEVANISH, 0,
2399 &_saved_mouse_vanish, 0);
2400 _got_saved_params =
true;
2402 SystemParametersInfo(SPI_SETMOUSETRAILS, 0, (PVOID)0, 0);
2403 SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)
false, 0);
2404 SystemParametersInfo(SPI_SETMOUSEVANISH, 0, (PVOID)
false, 0);
2407 SetCursor(to_window->_cursor);
2410 hide_or_show_cursor(hide_cursor);
2412 _cursor_window = to_window;
2420void WinGraphicsWindow::
2421hide_or_show_cursor(
bool hide_cursor) {
2423 if (!_cursor_hidden) {
2425 _cursor_hidden =
true;
2428 if (_cursor_hidden) {
2430 _cursor_hidden =
false;
2436#define MIN_REFRESH_RATE 60
2439#define ACCEPTABLE_REFRESH_RATE(RATE) ((RATE >= MIN_REFRESH_RATE) || (RATE==0) || (RATE==1))
2445bool WinGraphicsWindow::
2446find_acceptable_display_mode(DWORD dwWidth, DWORD dwHeight, DWORD bpp,
2451 ZeroMemory(&cur_dm,
sizeof(cur_dm));
2452 cur_dm.dmSize =
sizeof(cur_dm);
2453 EnumDisplaySettings(
nullptr, ENUM_CURRENT_SETTINGS, &cur_dm);
2456 int saved_modenum = -1;
2459 ZeroMemory(&dm,
sizeof(dm));
2460 dm.dmSize =
sizeof(dm);
2462 if (!EnumDisplaySettings(
nullptr, modenum, &dm)) {
2466 if ((dm.dmPelsWidth == dwWidth) && (dm.dmPelsHeight == dwHeight) &&
2467 (dm.dmBitsPerPel == bpp)) {
2470 if (dm.dmDisplayFrequency == cur_dm.dmDisplayFrequency) {
2472 }
else if (saved_modenum == -1) {
2473 saved_modenum = modenum;
2481 if (saved_modenum != -1) {
2482 ZeroMemory(&dm,
sizeof(dm));
2483 dm.dmSize =
sizeof(dm);
2485 if (EnumDisplaySettings(
nullptr, saved_modenum, &dm)) {
2497void WinGraphicsWindow::
2498show_error_message(DWORD message_id) {
2499 LPTSTR message_buffer;
2501 if (message_id == 0) {
2502 message_id = GetLastError();
2505 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
2506 nullptr, message_id,
2507 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2508 (LPTSTR)&message_buffer,
2510 MessageBox(GetDesktopWindow(), message_buffer, _T(errorbox_title), MB_OK);
2511 windisplay_cat.fatal() <<
"System error msg: " << message_buffer << endl;
2512 LocalFree(message_buffer);
2518void WinGraphicsWindow::
2519handle_keypress(
ButtonHandle key,
int x,
int y,
double time) {
2520 _input->set_pointer_in_window(x, y);
2521 if (key != ButtonHandle::none()) {
2522 _input->button_down(key, time);
2530void WinGraphicsWindow::
2532 if (key != ButtonHandle::none()) {
2533 _input->button_resume_down(key, time);
2540void WinGraphicsWindow::
2542 if (key != ButtonHandle::none()) {
2543 _input->button_up(key, time);
2550void WinGraphicsWindow::
2552 if (key != ButtonHandle::none()) {
2553 _input->raw_button_down(key, time);
2560void WinGraphicsWindow::
2562 if (key != ButtonHandle::none()) {
2563 _input->raw_button_up(key, time);
2572lookup_key(WPARAM wparam)
const {
2577 case VK_BACK:
return KeyboardButton::backspace();
2578 case VK_DELETE:
return KeyboardButton::del();
2579 case VK_ESCAPE:
return KeyboardButton::escape();
2580 case VK_SPACE:
return KeyboardButton::space();
2581 case VK_UP:
return KeyboardButton::up();
2582 case VK_DOWN:
return KeyboardButton::down();
2583 case VK_LEFT:
return KeyboardButton::left();
2584 case VK_RIGHT:
return KeyboardButton::right();
2591 case VK_TAB:
return KeyboardButton::tab();
2592 case VK_PRIOR:
return KeyboardButton::page_up();
2593 case VK_NEXT:
return KeyboardButton::page_down();
2594 case VK_HOME:
return KeyboardButton::home();
2595 case VK_END:
return KeyboardButton::end();
2596 case VK_F1:
return KeyboardButton::f1();
2597 case VK_F2:
return KeyboardButton::f2();
2598 case VK_F3:
return KeyboardButton::f3();
2599 case VK_F4:
return KeyboardButton::f4();
2600 case VK_F5:
return KeyboardButton::f5();
2601 case VK_F6:
return KeyboardButton::f6();
2602 case VK_F7:
return KeyboardButton::f7();
2603 case VK_F8:
return KeyboardButton::f8();
2604 case VK_F9:
return KeyboardButton::f9();
2605 case VK_F10:
return KeyboardButton::f10();
2606 case VK_F11:
return KeyboardButton::f11();
2607 case VK_F12:
return KeyboardButton::f12();
2608 case VK_INSERT:
return KeyboardButton::insert();
2609 case VK_CAPITAL:
return KeyboardButton::caps_lock();
2610 case VK_NUMLOCK:
return KeyboardButton::num_lock();
2611 case VK_SCROLL:
return KeyboardButton::scroll_lock();
2612 case VK_PAUSE:
return KeyboardButton::pause();
2613 case VK_SNAPSHOT:
return KeyboardButton::print_screen();
2615 case VK_SHIFT:
return KeyboardButton::shift();
2616 case VK_LSHIFT:
return KeyboardButton::lshift();
2617 case VK_RSHIFT:
return KeyboardButton::rshift();
2619 case VK_CONTROL:
return KeyboardButton::control();
2620 case VK_LCONTROL:
return KeyboardButton::lcontrol();
2621 case VK_RCONTROL:
return KeyboardButton::rcontrol();
2623 case VK_MENU:
return KeyboardButton::alt();
2624 case VK_LMENU:
return KeyboardButton::lalt();
2625 case VK_RMENU:
return KeyboardButton::ralt();
2627 case VK_LWIN:
return KeyboardButton::lmeta();
2628 case VK_RWIN:
return KeyboardButton::rmeta();
2629 case VK_APPS:
return KeyboardButton::menu();
2632 int key = MapVirtualKey(wparam, 2);
2633 if (isascii(key) && key != 0) {
2648 return ButtonHandle::none();
2656lookup_raw_key(LPARAM lparam)
const {
2657 unsigned char vsc = (lparam & 0xff0000) >> 16;
2659 if (lparam & 0x1000000) {
2662 case 28:
return KeyboardButton::enter();
2663 case 29:
return KeyboardButton::rcontrol();
2665 case 55:
return KeyboardButton::print_screen();
2666 case 56:
return KeyboardButton::ralt();
2667 case 69:
return KeyboardButton::num_lock();
2668 case 71:
return KeyboardButton::home();
2669 case 72:
return KeyboardButton::up();
2670 case 73:
return KeyboardButton::page_up();
2671 case 75:
return KeyboardButton::left();
2672 case 77:
return KeyboardButton::right();
2673 case 79:
return KeyboardButton::end();
2674 case 80:
return KeyboardButton::down();
2675 case 81:
return KeyboardButton::page_down();
2676 case 82:
return KeyboardButton::insert();
2677 case 83:
return KeyboardButton::del();
2678 case 91:
return KeyboardButton::lmeta();
2679 case 92:
return KeyboardButton::rmeta();
2680 case 93:
return KeyboardButton::menu();
2685 static ButtonHandle raw_map[] = {
2686 ButtonHandle::none(),
2687 KeyboardButton::escape(),
2700 KeyboardButton::backspace(),
2701 KeyboardButton::tab(),
2714 KeyboardButton::enter(),
2715 KeyboardButton::lcontrol(),
2728 KeyboardButton::lshift(),
2740 KeyboardButton::rshift(),
2742 KeyboardButton::lalt(),
2743 KeyboardButton::space(),
2744 KeyboardButton::caps_lock(),
2745 KeyboardButton::f1(),
2746 KeyboardButton::f2(),
2747 KeyboardButton::f3(),
2748 KeyboardButton::f4(),
2749 KeyboardButton::f5(),
2750 KeyboardButton::f6(),
2751 KeyboardButton::f7(),
2752 KeyboardButton::f8(),
2753 KeyboardButton::f9(),
2754 KeyboardButton::f10(),
2755 KeyboardButton::pause(),
2756 KeyboardButton::scroll_lock(),
2771 return raw_map[vsc];
2777 case 87:
return KeyboardButton::f11();
2778 case 88:
return KeyboardButton::f12();
2779 default:
return ButtonHandle::none();
2791get_keyboard_map()
const {
2792 ButtonMap *map =
new ButtonMap;
2796 unsigned short ex_vsc[] = {0x56, 0x57, 0x58,
2797 0x011c, 0x011d, 0x0135, 0x0137, 0x0138, 0x0145, 0x0147, 0x0148, 0x0149, 0x014b, 0x014d, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x015b, 0x015c, 0x015d};
2799 for (
int k = 1; k < 84 +
sizeof(ex_vsc) /
sizeof(short); ++k) {
2801 vsc = ex_vsc[k - 84];
2806 UINT lparam = vsc << 16;
2807 ButtonHandle raw_button = lookup_raw_key(lparam);
2808 if (raw_button == ButtonHandle::none()) {
2812 ButtonHandle button;
2814 button = KeyboardButton::pause();
2816 }
else if (vsc >= 0x47 && vsc <= 0x53) {
2818 button = raw_button;
2830 UINT vk = MapVirtualKeyA(vsc, MAPVK_VSC_TO_VK_EX);
2831 button = lookup_key(vk);
2837 int len = GetKeyNameTextW(lparam, text, 256);
2849void WinGraphicsWindow::
2850handle_raw_input(HRAWINPUT hraw) {
2857 if (GetRawInputData(hraw, RID_INPUT,
nullptr, &dwSize,
sizeof(RAWINPUTHEADER)) == -1) {
2861 lpb = (LPBYTE)alloca(
sizeof(LPBYTE) * dwSize);
2862 if (lpb ==
nullptr) {
2866 if (GetRawInputData(hraw, RID_INPUT, lpb, &dwSize,
sizeof(RAWINPUTHEADER)) != dwSize) {
2870 RAWINPUT *raw = (RAWINPUT *)lpb;
2871 if (raw->header.hDevice == 0) {
2875 for (
size_t i = 1; i < _input_devices.size(); ++i) {
2876 if (_input_device_handle[i] == raw->header.hDevice) {
2877 PT(GraphicsWindowInputDevice) input =
2878 DCAST(GraphicsWindowInputDevice, _input_devices[i]);
2880 int adjx = raw->data.mouse.lLastX;
2881 int adjy = raw->data.mouse.lLastY;
2883 if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) {
2884 input->set_pointer_in_window(adjx, adjy);
2886 input->pointer_moved(adjx, adjy);
2889 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) {
2892 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) {
2895 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) {
2898 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) {
2901 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) {
2904 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) {
2907 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) {
2910 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) {
2913 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) {
2916 if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) {
2926bool WinGraphicsWindow::
2927handle_mouse_motion(
int x,
int y) {
2928 _input->set_pointer_in_window(x, y);
2935void WinGraphicsWindow::
2936handle_mouse_exit() {
2938 _input->set_pointer_out_of_window();
2945HICON WinGraphicsWindow::
2946get_icon(
const Filename &filename) {
2948 IconFilenames::iterator fi = _icon_filenames.find(filename);
2949 if (fi != _icon_filenames.end()) {
2950 return (HICON)((*fi).second);
2957 Filename resolved = filename;
2964 windisplay_cat.warning()
2965 <<
"Could not find icon filename " << filename <<
"\n";
2969 fi = _icon_filenames.find(resolved);
2970 if (fi != _icon_filenames.end()) {
2971 _icon_filenames[filename] = (*fi).second;
2972 return (HICON)((*fi).second);
2977 HANDLE h = LoadImage(
nullptr, os.c_str(),
2978 IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);
2980 windisplay_cat.warning()
2981 <<
"windows icon filename '" << os <<
"' could not be loaded!!\n";
2984 _icon_filenames[filename] = h;
2985 _icon_filenames[resolved] = h;
2993HCURSOR WinGraphicsWindow::
2994get_cursor(
const Filename &filename) {
2996 if (filename.empty()) {
3001 IconFilenames::iterator fi = _cursor_filenames.find(filename);
3002 if (fi != _cursor_filenames.end()) {
3003 return (HCURSOR)((*fi).second);
3010 Filename resolved = filename;
3013 windisplay_cat.warning()
3014 <<
"Could not find cursor filename " << filename <<
"\n";
3017 fi = _cursor_filenames.find(resolved);
3018 if (fi != _cursor_filenames.end()) {
3019 _cursor_filenames[filename] = (*fi).second;
3020 return (HCURSOR)((*fi).second);
3025 HANDLE h = LoadImage(
nullptr, os.c_str(),
3026 IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
3028 windisplay_cat.warning()
3029 <<
"windows cursor filename '" << os <<
"' could not be loaded!!\n";
3030 show_error_message();
3033 _cursor_filenames[filename] = h;
3034 _cursor_filenames[resolved] = h;
3038static HCURSOR get_cursor(
const Filename &filename);
3044const WinGraphicsWindow::WindowClass &WinGraphicsWindow::
3046 WindowClass wcreg(props);
3047 std::wostringstream wclass_name;
3048 wclass_name << L
"WinGraphicsWindow" << _window_class_index;
3049 wcreg._name = wclass_name.str();
3051 std::pair<WindowClasses::iterator, bool> found = _window_classes.insert(wcreg);
3052 const WindowClass &wclass = (*found.first);
3054 if (!found.second) {
3060 _window_class_index++;
3064 HINSTANCE instance = GetModuleHandle(
nullptr);
3067 ZeroMemory(&wc,
sizeof(wc));
3068 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
3070 wc.hInstance = instance;
3072 wc.hIcon = wclass._icon;
3074 wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
3075 wc.lpszMenuName =
nullptr;
3076 wc.lpszClassName = wclass._name.c_str();
3078 if (!RegisterClassW(&wc)) {
3079 windisplay_cat.error()
3080 <<
"could not register window class " << wclass._name <<
"!" << endl;
3090WinGraphicsWindow::WinWindowHandle::
3102void WinGraphicsWindow::WinWindowHandle::
3111void WinGraphicsWindow::WinWindowHandle::
3112receive_windows_message(
unsigned int msg,
int wparam,
int lparam) {
3113 if (_window !=
nullptr) {
3114 _window->receive_windows_message(msg, wparam, lparam);
3120void PrintErrorMessage(DWORD msgID) {
3121 LPTSTR pMessageBuffer;
3123 if (msgID==PRINT_LAST_ERROR)
3124 msgID=GetLastError();
3126 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
3128 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
3129 (LPTSTR) &pMessageBuffer,
3131 MessageBox(GetDesktopWindow(),pMessageBuffer,_T(errorbox_title),MB_OK);
3132 windisplay_cat.fatal() <<
"System error msg: " << pMessageBuffer << endl;
3133 LocalFree( pMessageBuffer );
3137ClearToBlack(HWND hWnd,
const WindowProperties &props) {
3139 if (windisplay_cat.is_debug()) {
3140 windisplay_cat.debug()
3141 <<
"Skipping ClearToBlack, no origin specified yet.\n";
3146 if (windisplay_cat.is_debug()) {
3147 windisplay_cat.debug()
3148 <<
"ClearToBlack(" << hWnd <<
", " << props <<
")\n";
3151 HDC hDC=GetDC(hWnd);
3157 FillRect(hDC,&clrRect,(HBRUSH)GetStockObject(BLACK_BRUSH));
3158 ReleaseDC(hWnd,hDC);
3167 GetClientRect(hwnd, view_rect);
3170 ul.x = view_rect->left;
3171 ul.y = view_rect->top;
3172 lr.x = view_rect->right;
3173 lr.y = view_rect->bottom;
3175 ClientToScreen(hwnd, &ul);
3176 ClientToScreen(hwnd, &lr);
3178 view_rect->left = ul.x;
3179 view_rect->top = ul.y;
3180 view_rect->right = lr.x;
3181 view_rect->bottom = lr.y;
3190 nassertv(wnd_proc !=
nullptr);
3199 nassertv(wnd_proc !=
nullptr);
3208 _window_proc_classes.clear();
3225 return callbackData->get_msg() == WM_TOUCH;
3234 return _num_touches;
3243 nassertr(index >= 0 && index < MAX_TOUCHES,
TouchInfo());
3245 TOUCHINPUT ti = _touches[index];
3247 point.x = TOUCH_COORD_TO_PIXEL(ti.x);
3248 point.y = TOUCH_COORD_TO_PIXEL(ti.y);
3249 ScreenToClient(_hWnd, &point);
3254 ret.set_id(ti.dwID);
3255 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.
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.
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 ...