3#include <Covellite/Os/Window.hpp>
7#include <alicorn/std/string.hpp>
8#include <alicorn/std/string-cast.hpp>
9#include <alicorn/platform/winapi-check.hpp>
10#include <alicorn/version.hpp>
11#include <Covellite/Events.hpp>
12#include <Covellite/App/IApplication.hpp>
13#include <Covellite/App/Settings.hpp>
14#include <Covellite/App/Events.hpp>
15#include <Covellite/Os/Events.hpp>
16#include <Covellite.App/Covellite.App/ClassName.windows.hpp>
26static HWND CreateWindow(
const wchar_t * _ClassName,
27 const alicorn::modules::settings::Section & _WindowSettings,
28 long & _MinWindowWidth,
long & _MinWindowHeight)
30 using Info_t = alicorn::system::version::Info;
31 using namespace ::alicorn::extension::std;
33 const auto ApplicationName =
34 string_cast<::std::wstring>(Info_t{}.GetValue(uT(
"ApplicationName")));
36 const auto ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
37 const auto ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
39 auto WindowFlags = WS_POPUP;
40 auto WindowFlagsEx = 0;
44 auto WindowWidth = ScreenWidth;
45 auto WindowHeight = ScreenHeight;
47 const auto IsFullScreen = _WindowSettings.Get<String>(uT(
"IsFullScreen"));
48 if (IsFullScreen == uT(
"false"))
50 WindowFlags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW;
51 WindowFlagsEx = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
53 const auto & SizeSection = _WindowSettings[uT(
"Size")];
55 const auto IsResized = _WindowSettings.Get<String>(uT(
"IsResized"));
56 if (IsResized == uT(
"false"))
58 WindowFlags ^= WS_THICKFRAME | WS_MAXIMIZEBOX;
62 const auto MinClientWidth = SizeSection.Get<
int>(uT(
"MinClientWidth"));
63 const auto MinClientHeight = SizeSection.Get<
int>(uT(
"MinClientHeight"));
65 RECT WindowRect = { 0, 0, MinClientWidth, MinClientHeight };
66 WINAPI_CHECK USING_MOCK ::AdjustWindowRectEx(&WindowRect,
67 WindowFlags, FALSE, WindowFlagsEx);
69 _MinWindowWidth = WindowRect.right - WindowRect.left;
70 _MinWindowHeight = WindowRect.bottom - WindowRect.top;
73 const auto ClientWidth = SizeSection.Get<
int>(uT(
"Width"));
74 const auto ClientHeight = SizeSection.Get<
int>(uT(
"Height"));
76 RECT WindowRect = { 0, 0, ClientWidth, ClientHeight };
77 WINAPI_CHECK USING_MOCK ::AdjustWindowRectEx(&WindowRect,
78 WindowFlags, FALSE, WindowFlagsEx);
80 const auto CalculatedWindowWidth = WindowRect.right - WindowRect.left;
81 WindowWidth = (CalculatedWindowWidth > ScreenWidth) ?
82 ScreenWidth : CalculatedWindowWidth;
84 const auto CalculatedWindowHeight = WindowRect.bottom - WindowRect.top;
85 WindowHeight = (CalculatedWindowHeight > ScreenHeight) ?
86 ScreenHeight : CalculatedWindowHeight;
88 X = (ScreenWidth - WindowWidth) / 2;
89 Y = (ScreenHeight - WindowHeight) / 2;
92 const auto hWnd = USING_MOCK ::CreateWindowEx(WindowFlagsEx,
93 _ClassName, ApplicationName.c_str(), WindowFlags,
94 X, Y, WindowWidth, WindowHeight,
nullptr,
nullptr,
95 GetModuleHandle(
nullptr),
nullptr);
96 WINAPI_CHECK (hWnd != NULL);
101# pragma warning(push)
102# pragma warning(disable: 6387)
103 USING_MOCK ::ShowWindow(hWnd, SW_SHOW);
109Window::Window(const ::covellite::app::IApplication & _Application) :
110 m_Events(_Application),
111 m_Handle(::covellite::os::CreateWindow(::covellite::app::ClassName,
112 ::covellite::app::
Settings_t::GetInstance()[uT(
"Window")],
113 m_MinWindowWidth, m_MinWindowHeight)),
114 m_LastTypeSizeMessage(SIZE_RESTORED)
116 USING_MOCK ::SetWindowLongPtrW(::covellite::any_cast<HWND>(m_Handle),
117 GWLP_USERDATA,
reinterpret_cast<LONG_PTR
>(&m_Events));
119 ActivateApplicationEvents();
120 ActivateResizeEvents();
121 ActivateMouseEvents();
125Window::~Window(
void)
noexcept
127 USING_MOCK ::DestroyWindow(::covellite::any_cast<HWND>(m_Handle));
130Rect Window::GetClientRect(
void)
const
132 RECT ClientRect = { 0 };
133 WINAPI_CHECK USING_MOCK ::GetClientRect(
134 ::covellite::any_cast<HWND>(m_Handle), &ClientRect);
136 ClientRect.right - ClientRect.left, ClientRect.bottom - ClientRect.top };
139void Window::ActivateApplicationEvents(
void)
141 using RawParams_t = ::std::pair<WPARAM, LPARAM>;
143 m_Events[(UINT)WM_CLOSE].Connect([=](
void)
145 m_Events[events::Application.Exit]();
148 m_Events[(UINT)WM_ACTIVATEAPP].Connect([=](
const RawParams_t & _Params)
150 if (_Params.first == TRUE)
152 m_Events[events::Window.Activate]();
154 else if (_Params.first == FALSE)
156 m_Events[events::Window.Deactivate]();
161void Window::ActivateResizeEvents(
void)
163 using RawParams_t = ::std::pair<WPARAM, LPARAM>;
165 m_Events[(UINT)WM_EXITSIZEMOVE].Connect([=](
void)
169 m_Events[events::Window.Resize]();
172 m_Events[(UINT)WM_SIZE].Connect([=](
const RawParams_t & _Params)
179 const auto Type = _Params.first;
181 if (Type == SIZE_MAXIMIZED ||
182 (Type == SIZE_RESTORED && m_LastTypeSizeMessage != SIZE_RESTORED))
184 m_Events[events::Window.Resize]();
187 if (Type == SIZE_MAXIMIZED ||
188 Type == SIZE_MINIMIZED ||
189 Type == SIZE_RESTORED)
191 m_LastTypeSizeMessage = Type;
195 m_Events[(UINT)WM_GETMINMAXINFO].Connect([=](
const RawParams_t & _Params)
197 auto *
const pInfo =
reinterpret_cast<MINMAXINFO *
>(_Params.second);
198 pInfo->ptMinTrackSize.x = m_MinWindowWidth;
199 pInfo->ptMinTrackSize.y = m_MinWindowHeight;
203void Window::ActivateMouseEvents(
void)
205 using RawParams_t = ::std::pair<WPARAM, LPARAM>;
206 using Position_t = events::Cursor_t::Position;
208 m_Events[(UINT)WM_MOUSEMOVE].Connect([&](
const RawParams_t & _Params)
210 const auto X = GET_X_LPARAM(_Params.second);
211 const auto Y = GET_Y_LPARAM(_Params.second);
212 m_Events[events::Cursor.Motion](Position_t{ X, Y });
215 m_Events[(UINT)WM_LBUTTONDOWN].Connect([=](
void)
217 m_Events[events::Cursor.Touch]();
220 m_Events[(UINT)WM_LBUTTONUP].Connect([=](
void)
222 m_Events[events::Cursor.Release]();
226void Window::ActivateKeyEvents(
void)
228 using RawParams_t = ::std::pair<WPARAM, LPARAM>;
230 m_Events[(UINT)WM_CHAR].Connect([=](
const RawParams_t & _Params)
232 auto KeyCode =
static_cast<int32_t
>(_Params.first);
236 if (KeyCode < VK_SPACE && KeyCode != VK_RETURN)
return;
240 if (KeyCode == VK_RETURN) KeyCode = 0x0A;
242 m_Events[events::Key.Pressed](KeyCode);
245 const auto pKeyMap = ::std::make_shared<::std::map<int32_t, bool>>();
247 m_Events[(UINT)WM_KEYDOWN].Connect([=](
const RawParams_t & _Params)
249 const auto KeyCode =
static_cast<int32_t
>(_Params.first);
251 if ((*pKeyMap)[KeyCode])
return;
253 (*pKeyMap)[KeyCode] =
true;
254 m_Events[events::Key.Down](KeyCode);
257 m_Events[(UINT)WM_KEYUP].Connect([=](
const RawParams_t & _Params)
259 const auto KeyCode =
static_cast<int32_t
>(_Params.first);
261 (*pKeyMap)[KeyCode] =
false;
262 m_Events[events::Key.Up](KeyCode);
265 m_Events[(UINT)WM_SYSKEYUP].Connect([=](
const RawParams_t & _Params)
267 if (_Params.first == VK_LEFT)
269 m_Events[events::Key.Back]();
271 else if (_Params.first == VK_SPACE)
273 m_Events[events::Key.Menu]();
::alicorn::extension::std::Singleton< const Section_t & > Settings_t
Класс входит в проект Covellite.App Класс доступа к настройкам фреймворка.
Definition Settings.hpp:37