CDialog::Create failing.
-
I have code that is called from the main window's showEvent:
void DeepSkyStacker::showEvent(QShowEvent* event) { if (!event->spontaneous()) { if (!initialised) { initialised = true; onInitialise(); } } // Invoke base class showEvent() return Inherited::showEvent(event); }
The onInitialise() code used to read like this:
void DeepSkyStacker::onInitialise() { ZFUNCTRACE_RUNTIME(); // // Force setting of blackPointToZero as initially false // Workspace{}.setValue("RawDDP/BlackPointTo0", false); // // Set the Docking Area Corner Configuration so that the // Explorer Bar takes the full left side docking area // setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); ZTRACE_RUNTIME("Creating Explorer Bar (Left Panel)"); explorerBar = new ExplorerBar(this); addDockWidget(Qt::LeftDockWidgetArea, explorerBar); ZTRACE_RUNTIME("Creating pictureList"); pictureList = new DSS::PictureList(this); addDockWidget(Qt::BottomDockWidgetArea, pictureList); ZTRACE_RUNTIME("Creating stackedWidget"); stackedWidget = new QStackedWidget(this); stackedWidget->setObjectName("stackedWidget"); setCentralWidget(stackedWidget); ZTRACE_RUNTIME("Creating Stacking Panel"); stackingDlg = new DSS::StackingDlg(this, pictureList); stackingDlg->setObjectName("stackingDlg"); ZTRACE_RUNTIME("Adding Stacking Panel to stackedWidget"); stackedWidget->addWidget(stackingDlg); winHost = new QWinHost(stackedWidget); winHost->setObjectName("winHost"); stackedWidget->addWidget(winHost); ZTRACE_RUNTIME("Creating Processing Panel"); auto result = processingDlg->Create(IDD_PROCESSING); if (FALSE == result) { int lastErr = GetLastError(); ZTRACE_RUNTIME("lastErr = %d", lastErr); } processingDlg->setParent(winHost); // Provide a Qt object to be parent for any Qt Widgets this creates HWND hwnd{ processingDlg->GetSafeHwnd() }; Q_ASSERT(NULL != hwnd); winHost->setWindow(hwnd); : : // // Set initial size of the bottom dock widget (pictureList) // resizeDocks({ pictureList }, { 150 }, Qt::Vertical); ZTRACE_RUNTIME("Restoring Window State and Position"); QSettings settings; settings.beginGroup("MainWindow"); auto geometry{ settings.value("geometry", QByteArray()).toByteArray() }; auto windowState{ settings.value("windowState", QByteArray()).toByteArray() }; #ifndef NDEBUG if (geometry.length()) { ZTRACE_RUNTIME("Hex dump of geometry:"); ZTrace::dumpHex(geometry.constData(), geometry.length()); } if (windowState.length()) { ZTRACE_RUNTIME("Hex dump of windowState:"); ZTrace::dumpHex(windowState.constData(), windowState.length()); } #endif if (settings.value("maximised").toBool()) { showMaximized(); setGeometry(screen()->availableGeometry()); } else restoreGeometry(geometry); restoreState(windowState); settings.endGroup();
That worked except the size of the dock widgets wasn't restored properly. In response to another topic https://forum.qt.io/topic/151253/preserving-restoring-qdockwidget-size, @Axel-Spoerl suggested I move the code for the creation and sizing of the dock widgets to the ctor which I did.
So the revised code in onInitialise() now reads:
void DeepSkyStacker::onInitialise() { ZFUNCTRACE_RUNTIME(); // // Force setting of blackPointToZero as initially false // Workspace{}.setValue("RawDDP/BlackPointTo0", false); ZTRACE_RUNTIME("Creating stackedWidget"); stackedWidget = new QStackedWidget(this); stackedWidget->setObjectName("stackedWidget"); setCentralWidget(stackedWidget); ZTRACE_RUNTIME("Creating Stacking Panel"); stackingDlg = new DSS::StackingDlg(this, pictureList); stackingDlg->setObjectName("stackingDlg"); ZTRACE_RUNTIME("Adding Stacking Panel to stackedWidget"); stackedWidget->addWidget(stackingDlg); winHost = new QWinHost(stackedWidget); winHost->setObjectName("winHost"); stackedWidget->addWidget(winHost); ZTRACE_RUNTIME("Creating Processing Panel"); auto result = processingDlg->Create(IDD_PROCESSING); if (FALSE == result) { int lastErr = GetLastError(); ZTRACE_RUNTIME("lastErr = %d", lastErr); } processingDlg->setParent(winHost); // Provide a Qt object to be parent for any Qt Widgets this creates HWND hwnd{ processingDlg->GetSafeHwnd() }; Q_ASSERT(NULL != hwnd); winHost->setWindow(hwnd);
The call to processingDlg->Create() now fails with result of 0 (FALSE) and GetLastError returns 0!
Debugging into the MFC code finally lead me to the call:
hWnd = ::CreateDialogIndirect(hInst, lpDialogTemplate, pParentWnd != NULL ? pParentWnd != NULL ? pParentWnd->GetSafeHwnd() : NULL, AfxDlgProc); #ifdef _DEBUG dwError = ::GetLastError(); #endif
in dlgcore.cpp at line 373 which was returning a NULL HWND with dwError being set to 0x57E (ERROR_TLW_WITH_WSCHILD). And indeed the rc file does say:
IDD_PROCESSING DIALOGEX 0, 0, 438, 332 STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN CONTROL "",IDC_PICTURE,"Static",SS_BLACKFRAME | SS_SUNKEN,6,28,427,148 LTEXT "Histo",IDC_ORIGINAL_HISTOGRAM,177,186,256,140,SS_SUNKEN LTEXT "Settings",IDC_SETTINGS,6,189,167,137,NOT WS_VISIBLE,WS_EX_STATICEDGE LTEXT "",IDC_INFO,6,6,427,16,0,WS_EX_TRANSPARENT CONTROL "",IDC_PROCESSING_PROGRESS,"msctls_progress32",PBS_SMOOTH,6,176,427,4 END
Why did it work before though???
-
Changing the dialogue definition changing WS_CHILD to WS_POPUP appears to fix it.
IDD_PROCESSING DIALOGEX 0, 0, 438, 332 STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_POPUP FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN CONTROL "",IDC_PICTURE,"Static",SS_BLACKFRAME | SS_SUNKEN,6,28,427,148 LTEXT "Histo",IDC_ORIGINAL_HISTOGRAM,177,186,256,140,SS_SUNKEN LTEXT "Settings",IDC_SETTINGS,6,189,167,137,NOT WS_VISIBLE,WS_EX_STATICEDGE LTEXT "",IDC_INFO,6,6,427,16,0,WS_EX_TRANSPARENT CONTROL "",IDC_PROCESSING_PROGRESS,"msctls_progress32",PBS_SMOOTH,6,176,427,4 END
David
-