Refine dialog lifecycle cleanup

This commit is contained in:
Codex
2026-04-09 04:45:05 +08:00
parent 97710db9e3
commit 241a564095
2 changed files with 42 additions and 79 deletions
+41 -74
View File
@@ -163,80 +163,63 @@ void Dialog::Show()
show = true; show = true;
dirty = true; dirty = true;
needsInitialization = true; needsInitialization = true;
close = false;
shouldClose = false;
hWnd.dialogOpen = true;// 通知窗口有对话框打开 hWnd.dialogOpen = true;// 通知窗口有对话框打开
if (modal) if (modal)
{ {
// 模态对话框需要阻塞当前线程直到对话框关闭 // 模态对话框需要阻塞当前线程直到对话框关闭
if (modal) // 记录当前窗口客户区尺寸,供轮询对比
RECT rc0;
GetClientRect(hWnd.getHwnd(), &rc0);
int lastW = rc0.right - rc0.left;
int lastH = rc0.bottom - rc0.top;
while (show)
{ {
// 记录当前窗口客户区尺寸,供轮询对比 // ① 轮询窗口尺寸(不依赖 WM_SIZE)
RECT rc0; RECT rc;
GetClientRect(hWnd.getHwnd(), &rc0); GetClientRect(hWnd.getHwnd(), &rc);
int lastW = rc0.right - rc0.left; const int cw = rc.right - rc.left;
int lastH = rc0.bottom - rc0.top; const int ch = rc.bottom - rc.top;
while (show && !close) if (cw != lastW || ch != lastH)
{ {
// ① 轮询窗口尺寸(不依赖 WM_SIZE) lastW = cw;
RECT rc; lastH = ch;
GetClientRect(hWnd.getHwnd(), &rc); SX_LOGD("Resize") <<SX_T("模态对话框检测到窗口大小变化:(", "Modal dialog detected window size change: (") << cw << "x" << ch << ")";
const int cw = rc.right - rc.left;
const int ch = rc.bottom - rc.top;
if (cw != lastW || ch != lastH) // 通知父窗口:有新尺寸 → 标记 needResizeDirty
{ hWnd.scheduleResizeFromModal(cw, ch);
lastW = cw;
lastH = ch;
SX_LOGD("Resize") <<SX_T("模态对话框检测到窗口大小变化:(", "Modal dialog detected window size change: (") << cw << "x" << ch << ")";
// 通知父窗口:有新尺寸 → 标记 needResizeDirty // 立即统一收口:父窗重绘 背景+普通控件(不会画到这只模态)
hWnd.scheduleResizeFromModal(cw, ch); hWnd.pumpResizeIfNeeded();
// 立即统一收口:父窗重绘 背景+普通控件(不会画到这只模态) // 这只模态只重新居中,不参与拉伸;背景快照需要在新位置重抓。
hWnd.pumpResizeIfNeeded(); recenterInHostWindow();
// 这只模态只重新居中,不参与拉伸;背景快照需要在新位置重抓。
recenterInHostWindow();
}
// ② 处理这只对话框的鼠标/键盘(沿用原来 EX_MOUSE | EX_KEY
ExMessage msg;
if (peekmessage(&msg, EX_MOUSE | EX_KEY))
{
handleEvent(msg);
if (shouldClose)
{
Close();
break;
}
}
// ③ 最后一笔:只画这只模态,保证永远在最上层
if (dirty)
{
BeginBatchDraw();
this->draw(); // 注意:不要 requestRepaint(parent),只画自己
EndBatchDraw();
dirty = false;
}
Sleep(10);
} }
if (pendingCleanup && !isCleaning) // ② 处理这只对话框的鼠标/键盘(沿用原来 EX_MOUSE | EX_KEY
performDelayedCleanup(); ExMessage msg;
} if (peekmessage(&msg, EX_MOUSE | EX_KEY))
else {
{ handleEvent(msg);
// 非模态仍由主循环托管 if (!show)
dirty = true; break;
}
// ③ 最后一笔:只画这只模态,保证永远在最上层
if (dirty)
{
BeginBatchDraw();
this->draw(); // 注意:不要 requestRepaint(parent),只画自己
EndBatchDraw();
dirty = false;
}
Sleep(10);
} }
// 模态对话框关闭后执行清理
if (pendingCleanup && !isCleaning) if (pendingCleanup && !isCleaning)
performDelayedCleanup(); performDelayedCleanup();
} }
@@ -250,7 +233,6 @@ void Dialog::Close()
if (!show) return; if (!show) return;
show = false; show = false;
close = true;
dirty = true; dirty = true;
pendingCleanup = true; // 只标记需要清理,不立即执行 pendingCleanup = true; // 只标记需要清理,不立即执行
@@ -259,20 +241,6 @@ void Dialog::Close()
resultCallback(this->result); resultCallback(this->result);
} }
void Dialog::setInitialization(bool init)
{
if (init)
{
// 窗口缩放后的重建不能再回贴旧快照;父窗口接下来会做一次完整重绘。
invalidateBackgroundSnapshot();
invalidateLayout(true);
}
else
{
needsInitialization = false;
}
}
void Dialog::recenterInHostWindow() void Dialog::recenterInHostWindow()
{ {
if (!show) if (!show)
@@ -713,7 +681,6 @@ void Dialog::performDelayedCleanup()
needsInitialization = true; needsInitialization = true;
pendingCleanup = false; pendingCleanup = false;
isCleaning = false; isCleaning = false;
shouldClose = false;
} }
void Dialog::SetResultCallback(std::function<void(StellarX::MessageBoxResult)> cb) void Dialog::SetResultCallback(std::function<void(StellarX::MessageBoxResult)> cb)
+1 -5
View File
@@ -45,8 +45,7 @@ class Dialog : public Canvas
std::string message; //提示信息 std::string message; //提示信息
std::vector<std::string> lines; //消息内容按行分割 std::vector<std::string> lines; //消息内容按行分割
bool needsInitialization = true; //是否需要初始化 bool needsInitialization = true; // 是否需要根据当前内容重新初始化布局和内部按钮
bool close = false; //是否关闭
bool modal = true; //是否模态 bool modal = true; //是否模态
COLORREF backgroundColor = RGB(240, 240, 240); //背景颜色 COLORREF backgroundColor = RGB(240, 240, 240); //背景颜色
@@ -60,7 +59,6 @@ class Dialog : public Canvas
StellarX::MessageBoxResult result = StellarX::MessageBoxResult::Cancel; // 对话框结果 StellarX::MessageBoxResult result = StellarX::MessageBoxResult::Cancel; // 对话框结果
bool shouldClose = false; //是否应该关闭
bool isCleaning = false; //是否正在清理 bool isCleaning = false; //是否正在清理
bool pendingCleanup = false; //延迟清理 bool pendingCleanup = false; //延迟清理
public: public:
@@ -103,8 +101,6 @@ public:
void Show(); void Show();
// 关闭对话框 // 关闭对话框
void Close(); void Close();
//初始化
void setInitialization(bool init); // 历史接口:当前语义更接近“请求重新布局/重建”
// 宿主窗口变化时仅重新居中,不拉伸 Dialog 自身 // 宿主窗口变化时仅重新居中,不拉伸 Dialog 自身
void recenterInHostWindow(); void recenterInHostWindow();