#include "BorderlessWindow.h" namespace ezui { BorderlessWindow::BorderlessWindow(int width, int height, HWND owner, DWORD dwStyle, DWORD dwExStyle) : Window(width, height, owner, dwStyle | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_POPUP, dwExStyle) { //无边框 auto style = ::GetWindowLong(Hwnd(), GWL_STYLE); style |= WS_THICKFRAME; ::SetWindowLong(Hwnd(), GWL_STYLE, style); m_shadowBox = new ShadowBox(width, height, Hwnd()); UpdateShadowBox(); } BorderlessWindow::~BorderlessWindow() { CloseShadowBox(); } ShadowBox* BorderlessWindow::GetShadowBox() { return m_shadowBox; } void BorderlessWindow::SetShadow(int padding) { m_shadowWeight = padding; UpdateShadowBox(); } void BorderlessWindow::OnDpiChange(float systemScale, const Rect& newRect) { if (m_shadowBox) {//对窗口阴影进行新DPI适配 if (this->m_shadowScale != systemScale) { this->m_shadowWeight *= systemScale / m_shadowScale; this->m_shadowScale = systemScale; UpdateShadowBox(); } } //对边框进行新DPI适配 float newScale = systemScale / GetPublicData()->Scale; __super::OnDpiChange(systemScale, newRect); } void BorderlessWindow::SetResizable(bool resize) { this->m_bResize = resize; } bool BorderlessWindow::IsResizable() { return this->m_bResize; } HWND BorderlessWindow::GetShadowHwnd() { if (m_shadowBox) { return m_shadowBox->Hwnd(); } return NULL; } void BorderlessWindow::UpdateShadowBox() { if (m_shadowBox && ::IsWindow(m_shadowBox->Hwnd())) { auto* mainLayout = this->GetLayout(); int shadowWeight = m_shadowWeight; m_shadowBox->Update(shadowWeight * this->GetScale(), (mainLayout ? mainLayout->GetBorderTopLeftRadius() : 0)); } } void BorderlessWindow::CloseShadowBox() { if (m_shadowBox) { delete m_shadowBox; m_shadowBox = NULL; } } LRESULT BorderlessWindow::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_NCCALCSIZE: { if (wParam == TRUE) { return 0; } break; } case WM_NCPAINT: { return 0; } case WM_NCACTIVATE: { return (wParam == FALSE ? TRUE : FALSE); } case WM_WINDOWPOSCHANGED: { WINDOWPOS* pPos = (WINDOWPOS*)lParam; //在窗口显示/隐藏的时候更新阴影窗口 if ((pPos->flags & SWP_SHOWWINDOW) || (pPos->flags & SWP_HIDEWINDOW)) { this->UpdateShadowBox(); } // Z-order 发生变化 if ((pPos->flags & SWP_NOZORDER) == 0) { this->UpdateShadowBox(); } break; } case WM_ACTIVATE: { auto state = LOWORD(wParam); if (state == WA_ACTIVE || state == WA_CLICKACTIVE) { // 窗口激活 } else if (state == WA_INACTIVE) { // 窗口失活 } this->UpdateShadowBox(); break; } case WM_SHOWWINDOW: { //窗口的可见状态标志被设置(此时窗口还未真正生效) if (wParam == TRUE) { //SHOW WINDOWS } else { //HIDE WINDOWS } break; } case WM_NCHITTEST: { //非全屏状态下/非最大化状态下/当调整大小的标志为true 的情况下才允许调整大小; if (!IsFullScreen() && !IsMaximized() && this->IsResizable()) { RECT rc; ::GetWindowRect(Hwnd(), &rc); POINT pt{ GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam) }; int x = 4;// if (pt.x < rc.left + x) { if (pt.y < rc.top + x)return HTTOPLEFT;// if (pt.y >= rc.bottom - x)return HTBOTTOMLEFT;// return HTLEFT;// } if (pt.x >= rc.right - x)// { if (pt.y < rc.top + x)return HTTOPRIGHT;// if (pt.y >= rc.bottom - x)return HTBOTTOMRIGHT;// return HTRIGHT;// } if (pt.y < rc.top + x)return HTTOP;// if (pt.y >= rc.bottom - x)return HTBOTTOM;// return HTCLIENT;// } break; } case WM_KILLFOCUS: { HWND wnd = (HWND)wParam; if (this->GetShadowBox() && wnd != this->GetShadowBox()->Hwnd()) { this->OnKillFocus(wnd); } else if (this->GetShadowBox() == NULL) { this->OnKillFocus(wnd); } return 0; } default: break; } return __super::WndProc(uMsg, wParam, lParam); } void BorderlessWindow::OnMove(const Point& location) { __super::OnMove(location); UpdateShadowBox(); } void BorderlessWindow::OnSize(const Size& sz) { __super::OnSize(sz);//避免先显示阴影再显示窗口的问题 UpdateShadowBox(); } }