|
|
|
|
@ -107,8 +107,100 @@
|
|
|
|
|
#include <QPointer>
|
|
|
|
|
#include <QtCore/qnumeric.h>
|
|
|
|
|
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
#include <qt_windows.h>
|
|
|
|
|
#include <dwmapi.h>
|
|
|
|
|
#pragma comment(lib, "dwmapi.lib")
|
|
|
|
|
#pragma comment(lib, "gdi32.lib")
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
// 结果窗保留原生最小化小框,仅替换最小化期间的系统预览。
|
|
|
|
|
class nmResultDialog : public QDialog
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit nmResultDialog(QWidget* parent, Qt::WindowFlags flags)
|
|
|
|
|
: QDialog(parent, flags), m_previewGuard(new nmDialogPreviewGuard(this)),
|
|
|
|
|
m_nativeMinimized(false)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void hideAndRestoreGeometry()
|
|
|
|
|
{
|
|
|
|
|
// 先隐藏再恢复,避免关闭小框时在原位置短暂显示大窗。
|
|
|
|
|
if(!isMinimized()) return;
|
|
|
|
|
const QRect geometryBeforeMinimize = m_geometryBeforeMinimize;
|
|
|
|
|
const Qt::WindowStates restoredState = windowState() & ~Qt::WindowMinimized;
|
|
|
|
|
hide();
|
|
|
|
|
setWindowState(restoredState);
|
|
|
|
|
// 复用预览清理来重建隐藏句柄,否则 Qt 4 调整原生最小化窗口尺寸时会重新显示它。
|
|
|
|
|
m_previewGuard->resetHiddenWindow();
|
|
|
|
|
if(!(restoredState & Qt::WindowMaximized) && geometryBeforeMinimize.isValid())
|
|
|
|
|
setGeometry(geometryBeforeMinimize);
|
|
|
|
|
setWindowState(restoredState);
|
|
|
|
|
m_nativeMinimized = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
protected:
|
|
|
|
|
bool winEvent(MSG* message, long* result) override
|
|
|
|
|
{
|
|
|
|
|
// 主窗口恢复时仅显示原来的小框,避免系统默认处理将结果窗展开。
|
|
|
|
|
if(message->message == WM_SHOWWINDOW && message->wParam &&
|
|
|
|
|
message->lParam == SW_PARENTOPENING && IsIconic(message->hwnd)) {
|
|
|
|
|
ShowWindow(message->hwnd, SW_SHOWMINNOACTIVE);
|
|
|
|
|
*result = 0;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(message->message == WM_SIZE) {
|
|
|
|
|
// 恢复或最大化后交还实时预览;窗口句柄重建后也由尺寸消息重新设置。
|
|
|
|
|
const BOOL minimized = message->wParam == SIZE_MINIMIZED;
|
|
|
|
|
// Qt 此时尚未处理最小化尺寸消息,仍保留大窗的客户区位置和尺寸。
|
|
|
|
|
if(minimized && !m_nativeMinimized) m_geometryBeforeMinimize = geometry();
|
|
|
|
|
m_nativeMinimized = minimized;
|
|
|
|
|
DwmSetWindowAttribute(message->hwnd, DWMWA_FORCE_ICONIC_REPRESENTATION,
|
|
|
|
|
&minimized, sizeof(minimized));
|
|
|
|
|
DwmSetWindowAttribute(message->hwnd, DWMWA_HAS_ICONIC_BITMAP,
|
|
|
|
|
&minimized, sizeof(minimized));
|
|
|
|
|
DwmInvalidateIconicBitmaps(message->hwnd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if((message->message == WM_DWMSENDICONICTHUMBNAIL ||
|
|
|
|
|
message->message == WM_DWMSENDICONICLIVEPREVIEWBITMAP) &&
|
|
|
|
|
IsIconic(message->hwnd)) {
|
|
|
|
|
// 透明位图只作用于任务栏预览,不隐藏结果窗或替换其原生标题栏。
|
|
|
|
|
BITMAPINFO info = {0};
|
|
|
|
|
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
|
|
info.bmiHeader.biWidth = 1;
|
|
|
|
|
info.bmiHeader.biHeight = -1;
|
|
|
|
|
info.bmiHeader.biPlanes = 1;
|
|
|
|
|
info.bmiHeader.biBitCount = 32;
|
|
|
|
|
void* pixels = NULL;
|
|
|
|
|
HBITMAP bitmap = CreateDIBSection(NULL, &info, DIB_RGB_COLORS, &pixels, NULL, 0);
|
|
|
|
|
if(bitmap) {
|
|
|
|
|
*static_cast<DWORD*>(pixels) = 0;
|
|
|
|
|
const HRESULT status = message->message == WM_DWMSENDICONICTHUMBNAIL
|
|
|
|
|
? DwmSetIconicThumbnail(message->hwnd, bitmap, 0)
|
|
|
|
|
: DwmSetIconicLivePreviewBitmap(message->hwnd, bitmap, NULL, 0);
|
|
|
|
|
DeleteObject(bitmap);
|
|
|
|
|
if(SUCCEEDED(status)) {
|
|
|
|
|
*result = 0;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return QDialog::winEvent(message, result);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
nmDialogPreviewGuard* m_previewGuard;
|
|
|
|
|
QRect m_geometryBeforeMinimize;
|
|
|
|
|
bool m_nativeMinimized; // 主窗口恢复时可能重复通知最小化,不重复记录小框尺寸。
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 保留原来求解器单例的防重入语义:全局同一时间只允许一个DLL求解任务运行。
|
|
|
|
|
// QPointer会在QObject销毁后自动变空,避免保留已经释放的线程指针。
|
|
|
|
|
QPointer<nmCalculationDllPebiSolverTask> s_pRunningSolverTask;
|
|
|
|
|
@ -135,9 +227,8 @@ void clearResultCurveDataTables(iGuiPlot* plot)
|
|
|
|
|
void resetResultDialog(QDialog* window)
|
|
|
|
|
{
|
|
|
|
|
if(!window) return;
|
|
|
|
|
// 先恢复最小化状态再隐藏,避免隐藏后调整尺寸使系统重新显示空白窗口。
|
|
|
|
|
if(window->isMinimized())
|
|
|
|
|
window->setWindowState(window->windowState() & ~Qt::WindowMinimized);
|
|
|
|
|
// 最小化结果先在隐藏状态下恢复尺寸,再清理旧曲线。
|
|
|
|
|
static_cast<nmResultDialog*>(window)->hideAndRestoreGeometry();
|
|
|
|
|
window->hide();
|
|
|
|
|
foreach(iGuiPlot* plot, window->findChildren<iGuiPlot*>()) clearResultCurveDataTables(plot);
|
|
|
|
|
foreach(nmWxSensitivityShow* dialog, window->findChildren<nmWxSensitivityShow*>())
|
|
|
|
|
@ -1978,12 +2069,11 @@ void nmSubWndMain::onForecastDataChanged()
|
|
|
|
|
QDialog* nmSubWndMain::createResultDialog(const QString& name, const QString& title)
|
|
|
|
|
{
|
|
|
|
|
// 关闭只隐藏,窗口及绘图控件由所属分析统一销毁。
|
|
|
|
|
QDialog* dialog = new QDialog(m_pResultRefreshFitting.data(),
|
|
|
|
|
QDialog* dialog = new nmResultDialog(m_pResultRefreshFitting.data(),
|
|
|
|
|
Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
|
|
|
|
|
dialog->setObjectName(name);
|
|
|
|
|
dialog->setWindowTitle(title);
|
|
|
|
|
dialog->setAttribute(Qt::WA_DeleteOnClose, false);
|
|
|
|
|
new nmDialogPreviewGuard(dialog);
|
|
|
|
|
dialog->resize(900, 650);
|
|
|
|
|
QVBoxLayout* layout = new QVBoxLayout(dialog);
|
|
|
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
@ -2154,10 +2244,10 @@ void nmSubWndMain::onReadonlyCurveDoubleClicked(
|
|
|
|
|
|
|
|
|
|
bool nmSubWndMain::eventFilter(QObject* watched, QEvent* event)
|
|
|
|
|
{
|
|
|
|
|
// 最小化时先恢复窗口状态,再交给默认关闭流程隐藏,避免复用时丢失正常尺寸。
|
|
|
|
|
// 最小化结果在隐藏后恢复尺寸,关闭过程中不显示大窗。
|
|
|
|
|
QDialog* dialog = qobject_cast<QDialog*>(watched);
|
|
|
|
|
if(dialog && event->type() == QEvent::Close && dialog->isMinimized())
|
|
|
|
|
dialog->setWindowState(dialog->windowState() & ~Qt::WindowMinimized);
|
|
|
|
|
if(dialog && event->type() == QEvent::Close)
|
|
|
|
|
static_cast<nmResultDialog*>(dialog)->hideAndRestoreGeometry();
|
|
|
|
|
// 关闭结果对话框时同步关闭其曲线数据表、Show 和统计设置窗口。
|
|
|
|
|
if((event->type() == QEvent::Close || event->type() == QEvent::Hide) &&
|
|
|
|
|
qobject_cast<QDialog*>(watched)) {
|
|
|
|
|
|