Files
EzUI/sources/BorderlessWindow.cpp

173 lines
4.2 KiB
C++
Raw Permalink Normal View History

2026-01-24 22:42:46 +08:00
#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();
}
}