21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_WINDOWS
25 #include "../../core/windows/SDL_windows.h"
28 #include "../SDL_sysvideo.h"
29 #include "../SDL_pixels_c.h"
30 #include "../../events/SDL_keyboard_c.h"
31 #include "../../events/SDL_mouse_c.h"
44 #ifndef SWP_NOCOPYBITS
45 #define SWP_NOCOPYBITS 0
49 HWND SDL_HelperWindow =
NULL;
50 static WCHAR *SDL_HelperWindowClassName = TEXT(
"SDLHelperWindowInputCatcher");
51 static WCHAR *SDL_HelperWindowName = TEXT(
"SDLHelperWindowInputMsgWindow");
52 static ATOM SDL_HelperWindowClass = 0;
61 #define STYLE_BASIC (WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
62 #define STYLE_FULLSCREEN (WS_POPUP)
63 #define STYLE_BORDERLESS (WS_POPUP)
64 #define STYLE_BORDERLESS_WINDOWED (WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
65 #define STYLE_NORMAL (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
66 #define STYLE_RESIZABLE (WS_THICKFRAME | WS_MAXIMIZEBOX)
67 #define STYLE_MASK (STYLE_FULLSCREEN | STYLE_BORDERLESS | STYLE_NORMAL | STYLE_RESIZABLE)
75 style |= STYLE_FULLSCREEN;
88 style |= STYLE_BORDERLESS_WINDOWED;
90 style |= STYLE_BORDERLESS;
93 style |= STYLE_NORMAL;
102 style |= STYLE_RESIZABLE;
108 style |= WS_MINIMIZE;
128 AdjustWindowRectEx(&
rect, style, menu, 0);
144 style = GetWindowLong(hwnd, GWL_STYLE);
145 menu = (style & WS_CHILDWINDOW) ?
FALSE : (GetMenu(hwnd) !=
NULL);
162 top = HWND_NOTOPMOST;
185 data->parent = parent;
186 data->hdc = GetDC(hwnd);
187 data->hinstance = (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
188 data->created = created;
189 data->mouse_button_flags = 0;
190 data->videodata = videodata;
196 if (!SetProp(hwnd, TEXT(
"SDL_WindowData"),
data)) {
197 ReleaseDC(hwnd,
data->hdc);
204 data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
211 data->wndproc = (WNDPROC) GetWindowLong(hwnd, GWL_WNDPROC);
222 if (GetClientRect(hwnd, &
rect)) {
230 SetWindowPos(hwnd, HWND_NOTOPMOST,
x,
y,
w,
h, SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE);
241 if (ClientToScreen(hwnd, &point)) {
247 DWORD style = GetWindowLong(hwnd, GWL_STYLE);
248 if (style & WS_VISIBLE) {
253 if (style & WS_POPUP) {
258 if (style & WS_THICKFRAME) {
264 if (style & WS_MAXIMIZE) {
272 if (style & WS_MINIMIZE) {
280 if (GetFocus() == hwnd) {
286 GetClientRect(hwnd, &
rect);
287 ClientToScreen(hwnd, (LPPOINT) &
rect);
288 ClientToScreen(hwnd, (LPPOINT) &
rect + 1);
294 if (videodata->RegisterTouchWindow) {
309 HWND hwnd, parent =
NULL;
310 DWORD style = STYLE_BASIC;
315 parent = CreateWindow(
SDL_Appname, TEXT(
""), STYLE_BASIC, 0, 0, 32, 32,
NULL,
NULL,
SDL_Instance,
NULL);
318 style |= GetWindowStyle(
window);
335 DestroyWindow(parent);
341 SetWindowPos(hwnd,
NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
344 ShowWindow(hwnd, SW_SHOWMINNOACTIVE);
352 #if SDL_VIDEO_OPENGL_ES2
358 #if SDL_VIDEO_OPENGL_EGL
365 return SDL_SetError(
"Could not create GLES window surface (EGL support not configured)");
370 #if SDL_VIDEO_OPENGL_WGL
376 return SDL_SetError(
"Could not create GL window (WGL support not configured)");
385 HWND hwnd = (HWND)
data;
391 titleLen = GetWindowTextLength(hwnd);
394 titleLen = GetWindowText(hwnd, title, titleLen + 1);
409 #if SDL_VIDEO_OPENGL_WGL
424 if (!WIN_GL_SetPixelFormatFrom(
_this, otherWindow,
window)) {
440 SetWindowText(hwnd, title);
450 int icon_len, mask_len,
y;
455 mask_len = (icon->
h * (icon->
w + 7)/8);
456 icon_len = 40 + icon->
h * icon->
w *
sizeof(
Uint32) + mask_len;
486 SDL_memset(icon_bmp + icon_len - mask_len, 0xFF, mask_len);
488 hicon = CreateIconFromResource(icon_bmp, icon_len,
TRUE, 0x00030000);
494 SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
497 SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
503 WIN_SetWindowPositionInternal(
_this,
window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE);
509 WIN_SetWindowPositionInternal(
_this,
window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE);
516 RECT rcClient, rcWindow;
521 GetClientRect(hwnd, &rcClient);
522 GetWindowRect(hwnd, &rcWindow);
526 ptDiff.y = rcWindow.top;
527 ptDiff.x = rcWindow.left;
529 ScreenToClient(hwnd, &ptDiff);
531 rcWindow.top = ptDiff.y;
532 rcWindow.left = ptDiff.x;
536 ptDiff.y = rcWindow.bottom;
537 ptDiff.x = rcWindow.right;
539 ScreenToClient(hwnd, &ptDiff);
541 rcWindow.bottom = ptDiff.y;
542 rcWindow.right = ptDiff.x;
547 *
top = rcClient.top - rcWindow.top;
548 *
left = rcClient.left - rcWindow.left;
549 *
bottom = rcWindow.bottom - rcClient.bottom;
550 *
right = rcWindow.right - rcClient.right;
564 style = GetWindowLong(hwnd, GWL_EXSTYLE);
565 if (style & WS_EX_NOACTIVATE) {
566 nCmdShow = SW_SHOWNOACTIVATE;
568 ShowWindow(hwnd, nCmdShow);
575 ShowWindow(hwnd, SW_HIDE);
582 SetForegroundWindow(hwnd);
591 ShowWindow(hwnd, SW_MAXIMIZE);
599 ShowWindow(hwnd, SW_MINIMIZE);
609 style = GetWindowLong(hwnd, GWL_STYLE);
610 style &= ~STYLE_MASK;
611 style |= GetWindowStyle(
window);
614 SetWindowLong(hwnd, GWL_STYLE, style);
615 WIN_SetWindowPositionInternal(
_this,
window, SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE);
626 style = GetWindowLong(hwnd, GWL_STYLE);
627 style &= ~STYLE_MASK;
628 style |= GetWindowStyle(
window);
630 SetWindowLong(hwnd, GWL_STYLE, style);
639 ShowWindow(hwnd, SW_RESTORE);
657 top = HWND_NOTOPMOST;
660 style = GetWindowLong(hwnd, GWL_STYLE);
661 style &= ~STYLE_MASK;
662 style |= GetWindowStyle(
window);
675 if (style & WS_MAXIMIZE) {
677 style &= ~WS_MAXIMIZE;
688 if (
data->windowed_mode_was_maximized && !
data->in_window_deactivation) {
689 style |= WS_MAXIMIZE;
693 menu = (style & WS_CHILDWINDOW) ?
FALSE : (GetMenu(hwnd) !=
NULL);
696 SetWindowLong(hwnd, GWL_STYLE, style);
698 SetWindowPos(hwnd,
top,
x,
y,
w,
h, SWP_NOCOPYBITS | SWP_NOACTIVATE);
708 BOOL succeeded =
FALSE;
712 succeeded = SetDeviceGammaRamp(hdc, (LPVOID)ramp);
718 return succeeded ? 0 : -1;
727 BOOL succeeded =
FALSE;
731 succeeded = GetDeviceGammaRamp(hdc, (LPVOID)ramp);
737 return succeeded ? 0 : -1;
746 UINT
flags = SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE;
749 flags |= SWP_NOACTIVATE;
762 RemoveProp(
data->hwnd, TEXT(
"SDL_WindowData"));
764 DestroyWindow(
data->hwnd);
766 DestroyWindow(
data->parent);
772 SetWindowLongPtr(
data->hwnd, GWLP_WNDPROC,
773 (LONG_PTR)
data->wndproc);
775 SetWindowLong(
data->hwnd, GWL_WNDPROC,
776 (LONG_PTR)
data->wndproc);
800 info->
info.win.hinstance =
data->hinstance;
816 SDL_HelperWindowCreate(
void)
818 HINSTANCE hInstance = GetModuleHandle(
NULL);
822 if (SDL_HelperWindow !=
NULL) {
828 wce.lpfnWndProc = DefWindowProc;
829 wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
830 wce.hInstance = hInstance;
833 SDL_HelperWindowClass = RegisterClass(&wce);
834 if (SDL_HelperWindowClass == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) {
835 return WIN_SetError(
"Unable to create Helper Window Class");
839 SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName,
840 SDL_HelperWindowName,
841 WS_OVERLAPPED, CW_USEDEFAULT,
842 CW_USEDEFAULT, CW_USEDEFAULT,
843 CW_USEDEFAULT, HWND_MESSAGE,
NULL,
845 if (SDL_HelperWindow ==
NULL) {
846 UnregisterClass(SDL_HelperWindowClassName, hInstance);
858 SDL_HelperWindowDestroy(
void)
860 HINSTANCE hInstance = GetModuleHandle(
NULL);
863 if (SDL_HelperWindow !=
NULL) {
864 if (DestroyWindow(SDL_HelperWindow) == 0) {
868 SDL_HelperWindow =
NULL;
872 if (SDL_HelperWindowClass != 0) {
873 if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
877 SDL_HelperWindowClass = 0;
891 WIN_SetWindowPositionInternal(
_this,
window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE);
896 TRACKMOUSEEVENT trackMouseEvent;
898 trackMouseEvent.cbSize =
sizeof(TRACKMOUSEEVENT);
899 trackMouseEvent.dwFlags = TME_LEAVE;
900 trackMouseEvent.hwndTrack =
data->hwnd;
902 TrackMouseEvent(&trackMouseEvent);
912 RECT
rect, clipped_rect;
914 if (
data->in_title_click ||
data->focus_click_pending) {
917 if (
data->skip_update_clipcursor) {
921 if (!GetClipCursor(&clipped_rect)) {
927 if (mouse->relative_mode && !mouse->relative_mode_warp) {
928 if (GetWindowRect(
data->hwnd, &
rect)) {
938 rect.bottom = cy + 1;
941 if (ClipCursor(&
rect)) {
947 if (GetClientRect(
data->hwnd, &
rect) && !IsRectEmpty(&
rect)) {
948 ClientToScreen(
data->hwnd, (LPPOINT) &
rect);
949 ClientToScreen(
data->hwnd, (LPPOINT) &
rect + 1);
951 if (ClipCursor(&
rect)) {
957 }
else if (
SDL_memcmp(&clipped_rect, &
data->cursor_clipped_rect,
sizeof(clipped_rect)) == 0) {
974 const LONG style = GetWindowLong(hwnd, GWL_EXSTYLE);
978 if (opacity == 1.0
f) {
980 if (style & WS_EX_LAYERED) {
981 if (SetWindowLong(hwnd, GWL_EXSTYLE, style & ~WS_EX_LAYERED) == 0) {
986 const BYTE
alpha = (BYTE) ((
int) (opacity * 255.0f));
988 if ((style & WS_EX_LAYERED) == 0) {
989 if (SetWindowLong(hwnd, GWL_EXSTYLE, style | WS_EX_LAYERED) == 0) {
994 if (SetLayeredWindowAttributes(hwnd, 0,
alpha, LWA_ALPHA) == 0) {