]> git.tdb.fi Git - libs/gui.git/blob - source/graphics/windows/window.cpp
Clear resizing flag on Windows when resizing completes
[libs/gui.git] / source / graphics / windows / window.cpp
1 #include <windowsx.h>
2 #include <msp/core/application.h>
3 #include <msp/core/systemerror.h>
4 #include "window.h"
5 #include "window_private.h"
6
7 using namespace std;
8
9 namespace {
10
11 LRESULT CALLBACK wndproc_(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
12 {
13         if(msg==WM_CREATE)
14         {
15                 CREATESTRUCT *cs = reinterpret_cast<CREATESTRUCT *>(lparam);
16                 SetWindowLong(hwnd, 0, reinterpret_cast<LONG>(cs->lpCreateParams));
17         }
18         else
19         {
20                 Msp::Graphics::Window *wnd = reinterpret_cast<Msp::Graphics::Window *>(GetWindowLong(hwnd, 0));
21                 Msp::Graphics::Window::Event ev;
22                 ev.msg = msg;
23                 ev.wparam = wparam;
24                 ev.lparam = lparam;
25                 if(wnd && wnd->event(ev))
26                         return 0;
27         }
28
29         return DefWindowProc(hwnd, msg, wparam, lparam);
30 }
31
32 }
33
34 namespace Msp {
35 namespace Graphics {
36
37 void Window::platform_init()
38 {
39         static bool wndclass_created = false;
40
41         if(!wndclass_created)
42         {
43                 WNDCLASSEX wndcl;
44
45                 wndcl.cbSize = sizeof(WNDCLASSEX);
46                 wndcl.style = 0;
47                 wndcl.lpfnWndProc = &wndproc_;
48                 wndcl.cbClsExtra = 0;
49                 wndcl.cbWndExtra = sizeof(Window *);
50                 wndcl.hInstance = reinterpret_cast<HINSTANCE>(Application::get_data());
51                 wndcl.hIcon = 0;
52                 wndcl.hCursor = LoadCursor(0, IDC_ARROW);
53                 wndcl.hbrBackground = 0;
54                 wndcl.lpszMenuName = 0;
55                 wndcl.lpszClassName = "mspgui";
56                 wndcl.hIconSm = 0;
57
58                 if(!RegisterClassEx(&wndcl))
59                         throw system_error("RegisterClassEx");
60
61                 wndclass_created = true;
62         }
63
64         RECT rect;
65         SetRect(&rect, 0, 0, options.width, options.height);
66
67         int style = (options.fullscreen ? WS_POPUP : WS_OVERLAPPEDWINDOW);
68         if(!options.resizable)
69                 style &= ~WS_THICKFRAME;
70         int exstyle = (options.fullscreen ? WS_EX_APPWINDOW : WS_EX_OVERLAPPEDWINDOW);
71         AdjustWindowRectEx(&rect, style, false, exstyle);
72
73         priv->window = CreateWindowEx(exstyle,
74                 "mspgui",
75                 "Window",
76                 style,
77                 CW_USEDEFAULT, CW_USEDEFAULT,
78                 rect.right-rect.left, rect.bottom-rect.top,
79                 0,
80                 0,
81                 reinterpret_cast<HINSTANCE>(Application::get_data()),
82                 this);
83         if(!priv->window)
84                 throw system_error("CreateWindowEx");
85 }
86
87 void Window::platform_cleanup()
88 {
89         if(priv->window)
90                 CloseWindow(priv->window);
91 }
92
93 void Window::set_title(const string &title)
94 {
95         SetWindowText(priv->window, title.c_str());
96 }
97
98 void Window::platform_reconfigure(bool fullscreen_changed)
99 {
100         RECT rect;
101         SetRect(&rect, 0, 0, options.width, options.height);
102
103         int style = (options.fullscreen ? WS_POPUP : WS_OVERLAPPEDWINDOW);
104         if(!options.resizable)
105                 style &= ~WS_THICKFRAME;
106         int exstyle = (options.fullscreen ? WS_EX_APPWINDOW : WS_EX_OVERLAPPEDWINDOW);
107         AdjustWindowRectEx(&rect, style, false, exstyle);
108
109         if(fullscreen_changed)
110         {
111                 hide();
112                 SetWindowLong(priv->window, GWL_EXSTYLE, exstyle);
113                 SetWindowLong(priv->window, GWL_STYLE, style);
114                 show();
115         }
116
117         if(options.fullscreen)
118                 SetWindowPos(priv->window, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOZORDER);
119         else
120                 SetWindowPos(priv->window, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE|SWP_NOZORDER);
121 }
122
123 void Window::show_cursor(bool s)
124 {
125         ShowCursor(s);
126 }
127
128 void Window::warp_pointer(int, int)
129 {
130 }
131
132 void Window::platform_show()
133 {
134         ShowWindow(priv->window, SW_SHOWNORMAL);
135 }
136
137 void Window::platform_hide()
138 {
139         ShowWindow(priv->window, SW_HIDE);
140 }
141
142 bool Window::event(const Event &evnt)
143 {
144         switch(evnt.msg)
145         {
146         case WM_KEYDOWN:
147         case WM_KEYUP:
148         case WM_LBUTTONDOWN:
149         case WM_LBUTTONUP:
150         case WM_MBUTTONDOWN:
151         case WM_MBUTTONUP:
152         case WM_RBUTTONDOWN:
153         case WM_RBUTTONUP:
154         case WM_MOUSEWHEEL:
155         case WM_MOUSEMOVE:
156                 signal_input_event.emit(evnt);
157                 break;
158         case WM_SIZE:
159                 options.width = LOWORD(evnt.lparam);
160                 options.height = HIWORD(evnt.lparam);
161                 resizing = false;
162                 signal_resize.emit(options.width, options.height);
163                 break;
164         case WM_CLOSE:
165                 signal_close.emit();
166                 break;
167         default:
168                 return false;
169         }
170
171         return true;
172 }
173
174 } // namespace Graphics
175 } // namespace Msp