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"
45#define SWP_NOCOPYBITS 0
49HWND SDL_HelperWindow =
NULL;
50static WCHAR *SDL_HelperWindowClassName = TEXT(
"SDLHelperWindowInputCatcher");
51static WCHAR *SDL_HelperWindowName = TEXT(
"SDLHelperWindowInputMsgWindow");
52static 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;
98 style |= STYLE_RESIZABLE;
103 style |= WS_MINIMIZE;
123 AdjustWindowRectEx(&
rect, style, menu, 0);
139 style = GetWindowLong(hwnd, GWL_STYLE);
140 menu = (style & WS_CHILDWINDOW) ?
FALSE : (GetMenu(hwnd) !=
NULL);
157 top = HWND_NOTOPMOST;
180 data->parent = parent;
181 data->hdc = GetDC(hwnd);
182 data->hinstance = (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
183 data->created = created;
184 data->mouse_button_flags = 0;
185 data->videodata = videodata;
191 if (!SetProp(hwnd, TEXT(
"SDL_WindowData"),
data)) {
192 ReleaseDC(hwnd,
data->hdc);
199 data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
206 data->wndproc = (WNDPROC) GetWindowLong(hwnd, GWL_WNDPROC);
217 if (GetClientRect(hwnd, &
rect)) {
225 SetWindowPos(hwnd, HWND_NOTOPMOST,
x,
y,
w,
h, SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE);
236 if (ClientToScreen(hwnd, &point)) {
242 DWORD style = GetWindowLong(hwnd, GWL_STYLE);
243 if (style & WS_VISIBLE) {
246 window->flags &= ~SDL_WINDOW_SHOWN;
248 if (style & WS_POPUP) {
251 window->flags &= ~SDL_WINDOW_BORDERLESS;
253 if (style & WS_THICKFRAME) {
256 window->flags &= ~SDL_WINDOW_RESIZABLE;
259 if (style & WS_MAXIMIZE) {
264 window->flags &= ~SDL_WINDOW_MAXIMIZED;
267 if (style & WS_MINIMIZE) {
272 window->flags &= ~SDL_WINDOW_MINIMIZED;
275 if (GetFocus() == hwnd) {
281 GetClientRect(hwnd, &
rect);
282 ClientToScreen(hwnd, (LPPOINT) &
rect);
283 ClientToScreen(hwnd, (LPPOINT) &
rect + 1);
289 if (videodata->RegisterTouchWindow) {
304 HWND hwnd, parent =
NULL;
305 DWORD style = STYLE_BASIC;
310 parent = CreateWindow(
SDL_Appname, TEXT(
""), STYLE_BASIC, 0, 0, 32, 32,
NULL,
NULL,
SDL_Instance,
NULL);
313 style |= GetWindowStyle(
window);
330 DestroyWindow(parent);
336 SetWindowPos(hwnd,
NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
339 ShowWindow(hwnd, SW_SHOWMINNOACTIVE);
347#if SDL_VIDEO_OPENGL_ES2
353#if SDL_VIDEO_OPENGL_EGL
360 return SDL_SetError(
"Could not create GLES window surface (EGL support not configured)");
365#if SDL_VIDEO_OPENGL_WGL
371 return SDL_SetError(
"Could not create GL window (WGL support not configured)");
380 HWND hwnd = (HWND)
data;
386 titleLen = GetWindowTextLength(hwnd);
389 titleLen = GetWindowText(hwnd, title, titleLen + 1);
404#if SDL_VIDEO_OPENGL_WGL
419 if (!WIN_GL_SetPixelFormatFrom(
_this, otherWindow,
window)) {
435 SetWindowText(hwnd, title);
445 int icon_len, mask_len,
y;
450 mask_len = (icon->
h * (icon->
w + 7)/8);
451 icon_len = 40 + icon->
h * icon->
w *
sizeof(
Uint32) + mask_len;
481 SDL_memset(icon_bmp + icon_len - mask_len, 0xFF, mask_len);
483 hicon = CreateIconFromResource(icon_bmp, icon_len,
TRUE, 0x00030000);
489 SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
492 SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
498 WIN_SetWindowPositionInternal(
_this,
window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE);
504 WIN_SetWindowPositionInternal(
_this,
window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE);
511 RECT rcClient, rcWindow;
516 GetClientRect(hwnd, &rcClient);
517 GetWindowRect(hwnd, &rcWindow);
521 ptDiff.y = rcWindow.top;
522 ptDiff.x = rcWindow.left;
524 ScreenToClient(hwnd, &ptDiff);
526 rcWindow.top = ptDiff.y;
527 rcWindow.left = ptDiff.x;
531 ptDiff.y = rcWindow.bottom;
532 ptDiff.x = rcWindow.right;
534 ScreenToClient(hwnd, &ptDiff);
536 rcWindow.bottom = ptDiff.y;
537 rcWindow.right = ptDiff.x;
542 *
top = rcClient.top - rcWindow.top;
543 *
left = rcClient.left - rcWindow.left;
544 *
bottom = rcWindow.bottom - rcClient.bottom;
545 *
right = rcWindow.right - rcClient.right;
559 style = GetWindowLong(hwnd, GWL_EXSTYLE);
560 if (style & WS_EX_NOACTIVATE) {
561 nCmdShow = SW_SHOWNOACTIVATE;
563 ShowWindow(hwnd, nCmdShow);
570 ShowWindow(hwnd, SW_HIDE);
577 SetForegroundWindow(hwnd);
586 ShowWindow(hwnd, SW_MAXIMIZE);
594 ShowWindow(hwnd, SW_MINIMIZE);
604 style = GetWindowLong(hwnd, GWL_STYLE);
605 style &= ~STYLE_MASK;
606 style |= GetWindowStyle(
window);
609 SetWindowLong(hwnd, GWL_STYLE, style);
610 WIN_SetWindowPositionInternal(
_this,
window, SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE);
621 style = GetWindowLong(hwnd, GWL_STYLE);
622 style &= ~STYLE_MASK;
623 style |= GetWindowStyle(
window);
625 SetWindowLong(hwnd, GWL_STYLE, style);
634 ShowWindow(hwnd, SW_RESTORE);
652 top = HWND_NOTOPMOST;
655 style = GetWindowLong(hwnd, GWL_STYLE);
656 style &= ~STYLE_MASK;
657 style |= GetWindowStyle(
window);
670 if (style & WS_MAXIMIZE) {
672 style &= ~WS_MAXIMIZE;
683 if (
data->windowed_mode_was_maximized && !
data->in_window_deactivation) {
684 style |= WS_MAXIMIZE;
688 menu = (style & WS_CHILDWINDOW) ?
FALSE : (GetMenu(hwnd) !=
NULL);
691 SetWindowLong(hwnd, GWL_STYLE, style);
693 SetWindowPos(hwnd,
top,
x,
y,
w,
h, SWP_NOCOPYBITS | SWP_NOACTIVATE);
703 BOOL succeeded =
FALSE;
707 succeeded = SetDeviceGammaRamp(hdc, (LPVOID)ramp);
713 return succeeded ? 0 : -1;
722 BOOL succeeded =
FALSE;
726 succeeded = GetDeviceGammaRamp(hdc, (LPVOID)ramp);
732 return succeeded ? 0 : -1;
741 UINT
flags = SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE;
744 flags |= SWP_NOACTIVATE;
757 RemoveProp(
data->hwnd, TEXT(
"SDL_WindowData"));
759 DestroyWindow(
data->hwnd);
761 DestroyWindow(
data->parent);
767 SetWindowLongPtr(
data->hwnd, GWLP_WNDPROC,
768 (LONG_PTR)
data->wndproc);
770 SetWindowLong(
data->hwnd, GWL_WNDPROC,
771 (LONG_PTR)
data->wndproc);
795 info->
info.win.hinstance =
data->hinstance;
811SDL_HelperWindowCreate(
void)
813 HINSTANCE hInstance = GetModuleHandle(
NULL);
817 if (SDL_HelperWindow !=
NULL) {
823 wce.lpfnWndProc = DefWindowProc;
824 wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
825 wce.hInstance = hInstance;
828 SDL_HelperWindowClass = RegisterClass(&wce);
829 if (SDL_HelperWindowClass == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) {
830 return WIN_SetError(
"Unable to create Helper Window Class");
834 SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName,
835 SDL_HelperWindowName,
836 WS_OVERLAPPED, CW_USEDEFAULT,
837 CW_USEDEFAULT, CW_USEDEFAULT,
838 CW_USEDEFAULT, HWND_MESSAGE,
NULL,
840 if (SDL_HelperWindow ==
NULL) {
841 UnregisterClass(SDL_HelperWindowClassName, hInstance);
853SDL_HelperWindowDestroy(
void)
855 HINSTANCE hInstance = GetModuleHandle(
NULL);
858 if (SDL_HelperWindow !=
NULL) {
859 if (DestroyWindow(SDL_HelperWindow) == 0) {
863 SDL_HelperWindow =
NULL;
867 if (SDL_HelperWindowClass != 0) {
868 if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
872 SDL_HelperWindowClass = 0;
886 WIN_SetWindowPositionInternal(
_this,
window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE);
891 TRACKMOUSEEVENT trackMouseEvent;
893 trackMouseEvent.cbSize =
sizeof(TRACKMOUSEEVENT);
894 trackMouseEvent.dwFlags = TME_LEAVE;
895 trackMouseEvent.hwndTrack =
data->hwnd;
897 TrackMouseEvent(&trackMouseEvent);
909 if (
data->in_title_click ||
data->focus_click_pending) {
912 if (
data->skip_update_clipcursor) {
919 if (mouse->relative_mode && !mouse->relative_mode_warp) {
930 rect.bottom = cy + 1;
932 if (ClipCursor(&
rect)) {
936 if (GetClientRect(
data->hwnd, &
rect) && !IsRectEmpty(&
rect)) {
937 ClientToScreen(
data->hwnd, (LPPOINT) &
rect);
938 ClientToScreen(
data->hwnd, (LPPOINT) &
rect + 1);
939 if (ClipCursor(&
rect)) {
961 const LONG style = GetWindowLong(hwnd, GWL_EXSTYLE);
965 if (opacity == 1.0f) {
967 if (style & WS_EX_LAYERED) {
968 if (SetWindowLong(hwnd, GWL_EXSTYLE, style & ~WS_EX_LAYERED) == 0) {
973 const BYTE
alpha = (BYTE) ((
int) (opacity * 255.0f));
975 if ((style & WS_EX_LAYERED) == 0) {
976 if (SetWindowLong(hwnd, GWL_EXSTYLE, style | WS_EX_LAYERED) == 0) {
981 if (SetLayeredWindowAttributes(hwnd, 0,
alpha, LWA_ALPHA) == 0) {
#define SDL_assert(condition)
#define SDL_VIDEO_OPENGL_WGL
#define SDL_GetHintBoolean
#define SDL_OutOfMemory()
#define SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT
A variable that is the address of another SDL_Window* (as a hex string formatted with "%p").
#define SDL_small_alloc(type, count, pisstack)
#define SDL_small_free(ptr, isstack)
void SDL_SetKeyboardFocus(SDL_Window *window)
SDL_Mouse * SDL_GetMouse(void)
GLint GLint GLint GLint GLint GLint y
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLint GLint GLsizei width
GLint GLint GLint GLint GLint x
GLint GLint GLsizei GLsizei height
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLdouble GLdouble GLdouble GLdouble top
GLfloat GLfloat GLfloat alpha
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
@ SDL_PIXELFORMAT_ARGB8888
SDL_bool SDL_ShouldAllowTopmost(void)
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
#define SDL_MINOR_VERSION
#define SDL_MAJOR_VERSION
#define SDL_VERSIONNUM(X, Y, Z)
static SDL_VideoDevice * _this
@ SDL_WINDOW_ALWAYS_ON_TOP
@ SDL_WINDOW_SKIP_TASKBAR
@ SDL_WINDOW_INPUT_GRABBED
@ SDL_GL_CONTEXT_PROFILE_ES
#define WIN_UTF8ToString(S)
#define WIN_StringToUTF8(S)
int WIN_SetError(const char *prefix)
LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
void WIN_PumpEvents(_THIS)
int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
int WIN_GetWindowBordersSize(_THIS, SDL_Window *window, int *top, int *left, int *bottom, int *right)
void WIN_ShowWindow(_THIS, SDL_Window *window)
void WIN_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
int WIN_SetWindowOpacity(_THIS, SDL_Window *window, float opacity)
void WIN_RaiseWindow(_THIS, SDL_Window *window)
int WIN_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
void WIN_SetWindowPosition(_THIS, SDL_Window *window)
void WIN_HideWindow(_THIS, SDL_Window *window)
void WIN_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered)
void WIN_DestroyWindow(_THIS, SDL_Window *window)
int WIN_GetWindowGammaRamp(_THIS, SDL_Window *window, Uint16 *ramp)
void WIN_MinimizeWindow(_THIS, SDL_Window *window)
void WIN_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
void WIN_SetWindowTitle(_THIS, SDL_Window *window)
void WIN_MaximizeWindow(_THIS, SDL_Window *window)
void WIN_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept)
void WIN_RestoreWindow(_THIS, SDL_Window *window)
void WIN_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable)
void WIN_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
void WIN_OnWindowEnter(_THIS, SDL_Window *window)
int WIN_CreateWindow(_THIS, SDL_Window *window)
SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
void WIN_UpdateClipCursor(SDL_Window *window)
int WIN_SetWindowGammaRamp(_THIS, SDL_Window *window, const Uint16 *ramp)
void WIN_SetWindowSize(_THIS, SDL_Window *window)
EGLSurface EGLNativeWindowType * window
A rectangle, with the origin at the upper left (integer).
A collection of pixels used in software blitting.
union SDL_SysWMinfo::@17 info
struct SDL_VideoDevice::@262 gl_config
struct SDL_GLDriverData * gl_data
The type used to identify a window.