30 #include YFM_MinGW32_YCLib_Win32GUI
32 using namespace YSLib;
33 using namespace Drawing;
46 ResizeWindow(::HWND h_wnd,
SDst w,
SDst h)
48 if(
YB_UNLIKELY(!::SetWindowPos(h_wnd, {}, 0, 0, w, h,
49 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE
50 | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER)))
56 FetchWindowRect(::HWND h_wnd)
68 FetchSizeFromBounds(const ::RECT& rect)
70 YAssert(rect.right - rect.left >= 0 && rect.bottom - rect.top >= 0,
71 "Invalid boundary found.");
72 return {rect.right - rect.left, rect.bottom - rect.top};
76 FetchRectFromBounds(const ::RECT& rect)
78 return Rect(rect.left, rect.top, FetchSizeFromBounds(rect));
82 FetchWindowStyle(::HWND h_wnd)
84 return ::GetWindowLongW(h_wnd, GWL_STYLE);
88 AdjustWindowBounds(::RECT& rect, ::HWND h_wnd,
bool b_menu =
false)
90 if(
YB_UNLIKELY(!::AdjustWindowRect(&rect, FetchWindowStyle(h_wnd), b_menu)))
92 YAssert(rect.right - rect.left >= 0 && rect.bottom - rect.top >= 0,
93 "Invalid boundary found.");
97 SetWindowBounds(::HWND h_wnd,
int x,
int y,
int cx,
int cy)
99 if(
YB_UNLIKELY(!::SetWindowPos(h_wnd, {}, x, y, cx, cy,
100 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE
101 | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER)))
110 WindowReference::GetClientBounds()
const
112 return {GetClientLocation(), GetClientSize()};
115 WindowReference::GetClientLocation()
const
119 if(
YB_UNLIKELY(!::ClientToScreen(hWindow, &point)))
121 return {point.x, point.y};
124 WindowReference::GetClientSize()
const
130 return {rect.right, rect.bottom};
133 WindowReference::GetLocation()
const
135 const auto& rect(FetchWindowRect(hWindow));
137 return {rect.left, rect.top};
140 WindowReference::GetOpacity()
const
144 if(
YB_UNLIKELY(!GetLayeredWindowAttributes(hWindow, {}, &a, {})))
149 WindowReference::GetSize()
const
151 return FetchSizeFromBounds(FetchWindowRect(hWindow));
155 WindowReference::SetClientBounds(
const Rect&
r)
159 AdjustWindowBounds(rect, hWindow);
160 SetWindowBounds(hWindow, rect.left, rect.top, rect.right - rect.left,
161 rect.bottom - rect.top);
166 if(
YB_UNLIKELY(!SetLayeredWindowAttributes(hWindow, 0, a, LWA_ALPHA)))
170 WindowReference::SetText(
const wchar_t* str)
179 if(
YB_UNLIKELY(!::SendNotifyMessageW(hWindow, WM_CLOSE, 0, 0)))
186 if(
YB_UNLIKELY(!::InvalidateRect(hWindow, {},
false)))
191 WindowReference::Move(
const Point& pt)
193 if(
YB_UNLIKELY(!::SetWindowPos(hWindow, {}, pt.
X, pt.
Y, 0, 0,
194 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW
195 | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER)))
200 WindowReference::Resize(
const Size&
s)
206 WindowReference::ResizeClient(
const Size&
s)
210 AdjustWindowBounds(rect, hWindow);
211 ResizeWindow(hWindow, rect.right - rect.left, rect.bottom - rect.top);
217 return ::ShowWindowAsync(hWindow, SW_SHOWNORMAL) != 0;
223 const wchar_t* title, ::DWORD wstyle, ::DWORD wstyle_ex)
227 ::AdjustWindowRect(&rect, wstyle,
false);
228 return ::CreateWindowExW(wstyle_ex, class_name, title, wstyle,
229 CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left,
230 rect.bottom - rect.top, HWND_DESKTOP, {}, ::GetModuleHandleW({}), {});
234 ScreenBuffer::ScreenBuffer(
const Size&
s)
239 ::BITMAPINFO bmi{{
sizeof(::BITMAPINFOHEADER),
size.
Width,
243 return ::CreateDIBSection({}, &bmi, DIB_RGB_COLORS,
244 &
reinterpret_cast<void*&
>(
pBuffer), {}, 0);
276 std::transform(buf, buf + size.Width * size.Height, pBuffer,
277 [](
const PixelType& pixel){
278 const auto a(pixel.GetA());
280 return PixelType{MonoType(pixel.GetB() * a / 0xFF),
281 MonoType(pixel.GetG() * a / 0xFF),
282 MonoType(pixel.GetR() * a / 0xFF), a};
292 std::copy_n(p_buf, size.Width * size.Height, GetBufferPtr());
307 std::lock_guard<std::mutex> lck(mtx);
316 std::lock_guard<std::mutex> lck(mtx);
325 std::lock_guard<std::mutex> lck(mtx);
326 GSurface<> sf(h_wnd);
328 sf.Update(*
this, pt);
335 const auto h_old(::SelectObject(h_mem_dc, sbuf.GetNativeHandle()));
336 const auto&
s(sbuf.GetSize());
339 ::BitBlt(h_owner_dc, pt.X, pt.Y, s.
Width, s.
Height, h_mem_dc, 0, 0,
341 ::SelectObject(h_mem_dc, h_old);
348 const auto h_old(::SelectObject(h_mem_dc, sbuf.GetNativeHandle()));
349 auto rect(FetchWindowRect(h_wnd));
350 ::SIZE size{rect.right - rect.left, rect.bottom - rect.top};
351 ::POINT ptx{pt.X, pt.Y};
352 ::BLENDFUNCTION bfunc{AC_SRC_OVER, 0, a, AC_SRC_ALPHA};
355 if(
YB_UNLIKELY(!::UpdateLayeredWindow(h_wnd, h_owner_dc,
356 reinterpret_cast<::POINT*>(&rect), &size, h_mem_dc, &ptx, 0, &bfunc,
360 ::SelectObject(h_mem_dc, h_old);
363 ::SelectObject(h_mem_dc, h_old);
367 WindowClass::WindowClass(
const wchar_t* class_name, ::WNDPROC wnd_proc,
368 ::UINT style, ::HBRUSH h_bg)
369 : h_instance(::GetModuleHandleW({}))
373 const ::WNDCLASSW wnd_class{style, wnd_proc, 0, 0,
h_instance,
374 ::LoadIconW({}, IDI_APPLICATION), ::LoadCursorW({}, IDC_ARROW),
375 h_bg,
nullptr, class_name};
394 YAssert(::IsWindow(h),
"Invalid window handle found.");
395 YAssert(::GetWindowThreadProcessId(h, {}) == ::GetCurrentThreadId(),
396 "Window not created on current thread found.");
397 YAssert(::GetWindowLongPtrW(h, GWLP_USERDATA) == 0,
398 "Invalid user data of window found.");
406 throw LoggedEvent(
"Wrong windows class name found.");
409 ::LONG_PTR(
this)) == 0 && GetLastError() != 0))
412 | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOSENDCHANGING
413 | SWP_NOSIZE | SWP_NOZORDER)))
416 ::RAWINPUTDEVICE rid{0x01, 0x02, 0,
nullptr};
418 if(
YB_UNLIKELY(!::RegisterRawInputDevices(&rid, 1,
sizeof(rid))))
424 HostWindow::~HostWindow()
426 ::SetWindowLongPtrW(
hWindow, GWLP_USERDATA, ::LONG_PTR());
void swap(ScreenBuffer &) ynothrow
yconstexpr wchar_t WindowClassName[]
YF_API void PostQuitMessage(int nExitCode, Messaging::Priority p=0xF0)
以优先级 p 发起 Shell 终止请求,返回 nExitCode。
size_t arrlen(_type(&)[_vN])
计算指定数组类型对象的长度。
ScreenBuffer & operator=(ScreenBuffer &&)
pt void UpdatePremultiplied(ScreenBuffer &, NativeWindowHandle, YSLib::Drawing::AlphaType=0xFF, const YSLib::Drawing::Point &={}) ynothrow
YF_API void Invalidate(IWidget &, const Rect &)
无效化:使相对于部件的指定区域在直接和间接的窗口缓冲区中无效。
std::map<::UINT, YSLib::GEvent< void(::WPARAM,::LPARAM)> > MessageMap
窗口消息转发事件映射。
YSLib::Drawing::BitmapPtr pBuffer
std::uint16_t SDst
屏幕坐标距离。
YF_API void Show(IWidget &)
显示部件。
HostWindow(NativeWindowHandle)
NativeWindowHandle hWindow
YF_API NativeWindowHandle CreateNativeWindow(const wchar_t *, const YSLib::Drawing::Size &, const wchar_t *=L"",::DWORD=WS_POPUP,::DWORD=WS_EX_LTRREADING)
按指定窗口类名、客户区大小、标题文本、样式和附加样式创建本机顶层窗口。
void swap(any &x, any &y)
交换对象。
#define YB_UNLIKELY(expr)
分支预测提示。
ScreenBuffer(const YSLib::Drawing::Size &)
DefGetter(ynothrow, ScreenBuffer &, ScreenBufferRef,*this) using ScreenBuffer voi UpdateFrom)(YSLib::Drawing::BitmapPtr) ynothrow
#define ynothrow
YSLib 无异常抛出保证:若支持 noexcept 关键字, 指定特定的 noexcept 异常规范。
#define YF_Raise_Win32Exception(...)
按 ::GetLastError 的结果和指定参数抛出 Windows::Win32Exception 对象。
void UpdatePremultipliedTo(NativeWindowHandle, YSLib::Drawing::AlphaType=0xFF, const YSLib::Drawing::Point &={}) ynothrow
#define YAssertNonnull(_expr)
::ANativeWindow * NativeWindowHandle
void UpdateTo(NativeWindowHandle, const YSLib::Drawing::Point &={}) ynothrow
#define YTraceDe(...)
YCLib 默认调试跟踪。
#define YAssert(_expr, _msg)
hBitmap DefGetter(const ynothrow, const YSLib::Drawing::Size &, Size, size) void Premultiply(YSLib void Resize(const YSLib::Drawing::Size &)
从缓冲区更新并按 Alpha 预乘。
YSLib::Drawing::Size size