Magpie/tools/WindowCase/WindowBase.h
Xu ae0c914c5c
修复有时误报源窗口无响应 (#1252)
* fix: 尝试修复错误检测源窗口挂起

* fix: 修复消息弹窗 bug
2025-08-14 22:36:28 +08:00

84 lines
1.7 KiB
C++

#pragma once
template <typename T>
class WindowBaseT {
public:
WindowBaseT() noexcept = default;
WindowBaseT(const WindowBaseT&) = delete;
WindowBaseT(WindowBaseT&&) noexcept = default;
HWND Handle() const noexcept {
return _hWnd;
}
operator bool() const noexcept {
return _hWnd;
}
void Destroy() const noexcept {
if (_hWnd) {
DestroyWindow(_hWnd);
}
}
protected:
// 确保无法通过基类指针删除这个对象
~WindowBaseT() noexcept {
Destroy();
}
static LRESULT CALLBACK _WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (msg == WM_NCCREATE) {
WindowBaseT* that = (WindowBaseT*)(((CREATESTRUCT*)lParam)->lpCreateParams);
assert(that && !that->_hWnd);
that->_hWnd = hWnd;
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)that);
} else if (T* that = (T*)GetWindowLongPtr(hWnd, GWLP_USERDATA)) {
return that->_MessageHandler(msg, wParam, lParam);
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
LRESULT _MessageHandler(UINT msg, WPARAM wParam, LPARAM lParam) noexcept {
switch (msg) {
case WM_CREATE:
{
_dpiScale = GetDpiForWindow(Handle()) / double(USER_DEFAULT_SCREEN_DPI);
return 0;
}
case WM_DPICHANGED:
{
_dpiScale = HIWORD(wParam) / double(USER_DEFAULT_SCREEN_DPI);
RECT* newRect = (RECT*)lParam;
SetWindowPos(
Handle(),
NULL,
newRect->left,
newRect->top,
newRect->right - newRect->left,
newRect->bottom - newRect->top,
SWP_NOZORDER | SWP_NOACTIVATE
);
return 0;
}
case WM_DESTROY:
{
_hWnd = NULL;
return 0;
}
}
return DefWindowProc(_hWnd, msg, wParam, lParam);
}
double DpiScale() const noexcept {
return _dpiScale;
}
private:
HWND _hWnd = NULL;
double _dpiScale = 1.0;
};