"CreateDirectory(..)" blockiert ev. kurzzeitig Message Queue?
-
Hallo zusammen,
Mein Programm (native C++) zeigt ein seltsames Verhalten.
Beim ersten Programmstart, nach der Installation, erzeuge ich unter "ProgramData" ein Unterverzeichnis
mit ein paar weiteren Verzeichnissen darunter.Es wird bei jedem Start, egal ob es der erste oder ein weiterer ist, immer derselbe Code durchlaufen.
Nur ab dem zweiten Start gibt eben "CreateDirectory(..)" den Wert "ERROR_ALREADY_EXISTS" zurück.
Diese Aufrufe von "CreateDirectory(..)" erfolgen alle in der "InitInctance()",
vor fast allen anderen Anweisungen.
Ich bin auch sehr sicher, dass dadurch nirgends auf ein fehlendes Verzeichnis zugegriffen wird.Es ist nun so, dass wenn diese Verzeichnisse erstellt werden, die Anwendung das Fenster mit weissem
Hintergrund startet und in diesem dann auch 10 bis 15 Sekunden verbleibt.Ich habe auch probiert, einen nicht modalen Dialog mit einem Hinweis anzuzeigen.
Aber dessen Inhalt wird auch erst mit dem des Hauptfensters angezeigt.Kann mir bitte jemand dieses Verhalten erklären oder vielleicht sogar eine Lösung nennen?
Danke
Helmut
-
elmut19 schrieb:
Ich habe auch probiert, einen nicht modalen Dialog mit einem Hinweis anzuzeigen.
Aber dessen Inhalt wird auch erst mit dem des Hauptfensters angezeigt.UpdateWindow nach dem Erstellen und Anzeigen des Dialogs und vor dem Erstellen/Prüfen der Verzeichnisse aufrufen, das sorgt dafür, dass der Dialog sofort neu gezeichnet wird.
Ansonsten erfolgt das Zeichnen erst ganz normal mit Abarbeitung der Messagequeue.
Edit: 2. Teil etwas umformuliert.
-
Danke yahendrik!
Das wird schon gemacht, ebenfalls in der "InitInstance()"
Wenn die Pfade erzeugt werden, habe ich noch gar kein Fenster, das ich updaten kann.
Dieses wird erst mehrere 100 Zeilen später erzeugt. Die gewünschten Pfade existieren dann schon lange.
Und das geht dann so:CMainFrame* pFrame = new CMainFrame; m_pMainWnd = pFrame; m_pFrame = pFrame; pFrame->LoadFrame(IDR_MAINFRAME_MAIN, WS_OVERLAPPEDWINDOW /*| FWS_ADDTOTITLE*/, NULL,NULL); pFrame->ShowWindow(!bHintergrund); pFrame->UpdateWindow(); m_pFrame->ActivateFrame(AfxGetApp()->GetProfileInt(_T("WNDSTATUS"), _T("SHOWCMD"),SW_SHOW));
-
Bin einen Schritt weiter.
Es werden nach obigem Codeabschnitt die einzelnen Views dieser Anwendung initialisiert.
Nun habe ich nach dieser View-Initialisierung nochmal "UpdateWindow()" auf den Frame aufgerufen.
Jetzt wird ein Inhalt angezeigt.
Die Anwendung pausiert zwar jetzt immernoch, aber zumindest zeigt sie was an.
Vielleicht blockiert ja doch irgend ein Thread, der auf diese Verzeichnisse zugreift, den ich leider (noch) nicht finde.Da war der Hinweis auf das "UpdateWindow()" doch eine gute Idee.
-
Ich meinte eigentlich, dass du einen Dialog erstellen, diesen „updaten”, Initialisierungen durchführen und anschließend das Hauptfenster sichtbar machen könntest.
Von Photoshop bis Office macht das eigentlich jede Anwendung, während sie Initialisierungen durchführt.
Jetzt mal ganz schnell als Konsolenprogramm zusammengefrickelt:
#include <windows.h> #include <iostream> #pragma pack(push, 4) struct EmptyDlg { DWORD style; DWORD exStyle; WORD controls; short x; short y; short w; short h; WORD id; WORD windowClass; TCHAR title[256]; }; #pragma pack(pop) INT_PTR CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {return 0;} int main() { EmptyDlg dlg = {WS_POPUP | WS_VISIBLE}; dlg.w = dlg.h = 80; HWND myDlg = CreateDialogIndirect(nullptr, reinterpret_cast<LPCDLGTEMPLATE>(&dlg), GetConsoleWindow(), DlgProc); HWND txt = CreateWindow(TEXT("static"), TEXT("Initialisiere...."), WS_CHILD | WS_VISIBLE, 0, 20, 80, 20, myDlg, (HMENU)500, 0, nullptr); UpdateWindow(myDlg); Sleep(2000); // Verzeichnisse erstellen etc. DestroyWindow(myDlg); std::cout << "MainFrame nun erstellt bzw. sichtbar\n"; }
Ohne das UpdateWindow würde der Inhalt des Dialogs, in diesem Fall nur der Text, nicht gezeichnet werden.
-
Warum erstellst du Pfade die existieren? Prüfe ob sie existieren und erstelle nur die die nicht existieren.
Wenn du unbedingt schon vorher ein Hinweisfenster erstellen willst, nimm doch MessageBox(...). Das kann als erste Zeile in deinem Code stehen.