34 using namespace Drawing;
41 std::chrono::nanoseconds host_sleep(
u64(1000000000 / g_max_free_fps));
55 WndProc(::HWND h_wnd, ::UINT msg, ::WPARAM w_param, ::LPARAM l_param)
58 const auto p(reinterpret_cast<Window*>(::GetWindowLongPtrW(h_wnd,
84 return ::DefWindowProcW(h_wnd, msg, w_param, l_param);
94 RenderWindow::OnPaint()
96 GSurface<WindowRegionDeviceContext> sf(GetNativeHandle());
98 renderer.get().UpdateToSurface(sf);
102 WindowThread::~WindowThread()
104 YAssert(
bool(p_wnd),
"Null pointer found.");
114 catch(std::invalid_argument&)
119 WindowThread::ThreadLoop(NativeWindowHandle h_wnd)
121 p_wnd.reset(
new Window(h_wnd));
125 WindowThread::ThreadLoop(unique_ptr<Window> p)
127 p_wnd = std::move(p);
132 WindowThread::WindowLoop(
Window& wnd)
135 auto& env(wnd.GetHost());
137 env.EnterWindowThread();
140 Environment::HostLoop();
142 env.LeaveWindowThread();
148 HostRenderer::SetSize(
const Size& s)
150 BufferedRenderer::SetSize(s);
158 rbuf.UpdateFrom(buf);
159 if(
const auto p_wnd = GetWindowPtr())
160 rbuf.UpdateTo(p_wnd->GetNativeHandle());
164 Environment::Environment()
165 : wnd_map(), wmap_mtx()
168 , h_instance(::GetModuleHandleW(
nullptr))
170 , wnd_thrd_count(), ExitOnAllWindowThreadCompleted()
174 const ::WNDCLASS wnd_class{CS_DBLCLKS,
175 WndProc, 0, 0, h_instance, ::LoadIconW(
nullptr, IDI_APPLICATION),
176 ::LoadCursorW(
nullptr, IDC_ARROW), ::HBRUSH(COLOR_MENU + 1),
177 nullptr, WindowClassName};
179 if(!::RegisterClassW(&wnd_class))
180 throw LoggedEvent(
"Windows registration failed.");
186 Environment::~Environment()
196 # if YCL_MULTITHREAD == 1
198 ::UnregisterClassW(WindowClassName, h_instance);
205 Environment::GetForegroundWindow() const
ynothrow
208 return FindWindow(::GetForegroundWindow());
214 Environment::AddMappedItem(NativeWindowHandle
h,
Window* p)
216 std::unique_lock<std::mutex> lck(wmap_mtx);
219 wnd_map.insert(make_pair(h, p));
223 Environment::FindWindow(NativeWindowHandle h)
const ynothrow
225 std::unique_lock<std::mutex> lck(wmap_mtx);
226 const auto i(wnd_map.find(h));
228 return i == wnd_map.end() ?
nullptr : i->second;
232 Environment::HostLoop()
238 ::MSG msg{
nullptr, 0, 0, 0, 0, {0, 0}};
240 if(::PeekMessageW(&msg,
nullptr, 0, 0, PM_REMOVE) != 0)
242 if(msg.message == WM_QUIT)
246 ::TranslateMessage(&msg);
247 ::DispatchMessageW(&msg);
262 # if YCL_MULTITHREAD == 1
264 Environment::LeaveWindowThread()
266 if(--wnd_thrd_count == 0 && ExitOnAllWindowThreadCompleted)
272 Environment::RemoveMappedItem(NativeWindowHandle h)
ynothrow
274 std::unique_lock<std::mutex> lck(wmap_mtx);
275 const auto i(wnd_map.find(h));
277 if(i != wnd_map.end())
282 Environment::UpdateRenderWindows()
284 std::unique_lock<std::mutex> lck(wmap_mtx);
286 for(
const auto& pr : wnd_map)
287 if(
auto p_wnd = dynamic_cast<RenderWindow*>(pr.second))
289 auto& rd(p_wnd->GetRenderer());
290 auto& wgt(rd.GetWidgetRef());
292 if(rd.Validate(wgt, wgt,
294 rd.Update(rd.GetContext().GetBufferPtr());