Modales Fenster (kein Dialog!) erstellen
-
Schönen guten Abend zusammen
,
Also, kommen wir gleich zur Sache: Ich wollte mir eine Funktion schreiben, mit der man ein modales Fenster erstellen kann; dieses soll sich also prinzipiell wie ein (modaler) Dialog verhalten.
Den Aufbau der Funktion, hatte ich mir wie folgt vorgestellt:- Registrierung einer Fensterklasse für dieses modale Fenster
- Erstellen des Fensters
- Blockierung des 'Programmflusses' bis der Benutzer das (modale) Fenster geschlossen hat
- Retournierung eines bestimmten Wertes, der sich nach den eingegebenen Daten (vom Benutzer) in diesem Fenster richtet (zum Beispiel IDYES bei der Funktion MessageBox bei einem Klick auf 'Ja')
Das Problem ist nun, dass das Blockieren des Programmflusses irgendwie nicht funktioniert (siehe Punkt 3).
Ich habe versucht dies mittels einer Message-Loop zu lösen, was aber irgendwie keinen Erfolg brachte: Entweder hat er die Funktion sofort verlassen oder mein gesamtes Programm hat sich aufgehängt (und selbst der Task-Manager hatte seine Mühe). Gibt es dabei also irgendetwas zu beachten ? Falls sich das nicht so pauschal beantworten lässt, kann ich -nach Bedarf- auch gerne Code posten (der aber wie gesagt nicht funktioniert
).
Hoffe, das war verständlich
.
Schonmal vielen Dank und schöne Grüße!
-
Parent Window disablen
-
Jupp klar, das hab ich auch gemacht -sorry, hätte ich noch erwähnen müssen- (EnableWindow) aber hat trotzdem nichts gebracht. Aber danke
... weitere Ideen ?
-
Hier doch mal mein Ansatz, der aber, wie gesagt, nicht funktioniert.
Zum Fehler:
Das Programm stürtzt zwar nicht ab (und das Fenster wird auch erfolgreich erstellt), aber die gesamte Anwendung lässt sich anschließend nicht mehr sauber beenden (der Task-Manager muss imme den 'Rest machen'). Das Programm macht aber wenigstens den Anschein, als würde es in der Funktion 'hängen bleiben' und diese erst wieder verlassen, wenn der Benutzer das Fenster geschlossen hat. Komischerweise geht der Aufruf von UnregisterClass auch schief. Ein weiteres Aufrufen der Funktion wird also bereits bei RegisterClassEx abgebrochen. Nochwas: Bei der Angabe von PM_NOREMOVE bei PeekMessage kann ich gleich den Netzstecker ziehen *g*.
Wenn ich die Nachrichtenschleife für GetMessage umbaue, bleibt er entweder hängen (2. Paremeter auf 'hWndRename') oder er verbleibt in der Schleife und verlässt diese erst dann, wenn das gesamte Programm geschlossen wird, also eine WM_QUIT eingeht. (also: GetMessage(&msg, NULL, 0, 0); 2. Parameter auf NULL).LRESULT CALLBACK RenameWndProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) { static SRenameWndInfo* pWndData; // Ist eine Struktur, die dem Fenster übermittelt wird, siehe unten switch(uiMessage) { case WM_CREATE: // Übermittelte Fensterdaten ermitteln: pWndData = static_cast<SRenameWndInfo*>(reinterpret_cast<LPCREATESTRUCT>(lParam)->lpCreateParams); if(pWndData == NULL) // <- Auf Gültigkeit prüfen { SendMessage(hWnd, WM_DESTROY, 0, 0); break; } // [...] // Parent-Fenster deaktivieren, da modales Fenster: EnableWindow(GetParent(hWnd), FALSE); break; case WM_CLOSE: pWndData->fFinished = true; case WM_DESTROY: // Parent-Fenster wieder aktivieren: EnableWindow(GetParent(hWnd), TRUE); DestroyWindow(hWnd); // <- Fenster abbauen break; default: return (DefWindowProc(hWnd, uiMessage, wParam, lParam)); } return (0L); } ERenameFileOptions CreateRenameFileWnd(HWND hWndParent, cString& strFileName, bool fNameMustChange, HINSTANCE hInst) { if(!IsWindow(hWndParent)) // <- Gültiges Parent-Fenster? return (RFO_ERROR); CCSTRG cszRenameWndClassName[] = ...; WNDCLASSEX WndClEx; // Hier wird 'WndClEx' initialisiert... if(!RegisterClassEx(&WndClEx)) // <- Fensterklasse registrieren return (RFO_ERROR); // [...] // Transfer- und Fensterdaten vorbereiten und übermitteln: CREATESTRUCT csInfo = { 0 }; SRenameWndInfo rwiData; rwiData.strCurrentName = strFileName; rwiData.eUserSelection = RFO_CANCEL; // <- Default-Wert rwiData.fFinished = false; csInfo.hInstance = hInst; csInfo.hwndParent = hWndParent; csInfo.lpszClass = cszRenameWndClassName; csInfo.lpszName = NULL; csInfo.style = WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_MINIMIZEBOX; csInfo.lpCreateParams = &rwiData; HWND hWndRename = CreateWindowEx // <- Fenster erstellen: (csInfo.dwExStyle, csInfo.lpszClass, csInfo.lpszName, csInfo.style, csInfo.x, csInfo.y, csInfo.cx, csInfo.cy, csInfo.hwndParent, csInfo.hMenu, csInfo.hInstance, &csInfo); if(hWndRename == NULL) return (RFO_ERROR); // Lokale Nachrichtenschleife für dieses Fenster: MSG msgLocal; while(!rwiData.fFinished) { while(PeekMessage(&msgLocal, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msgLocal); DispatchMessage(&msgLocal); } } MessageBox(0,"GaGaGaGaUhhh ;-)",0,0); // Registrierte Fensterklasse wieder abbauen: UnregisterClass(cszRenameWndClassName, hInst); return (rwiData.eUserSelection); } // ----------------------------------- // Die Struktur ist so definiert: struct SRenameWndInfo { ERenameFileOptions eUserSelection; cString strCurrentName; bool fFinished; }; // Die Sache mit GetMessage sähe dann so aus (was ja aber auch nicht funkioniert): while(GetMessage(&msgLocal, NULL, 0, 0)) { TranslateMessage(&msgLocal); DispatchMessage(&msgLocal); }
PS: cString (
std::string/std::wstring) und CSTRG (
char/wchar_t) sind einfach Zeichensatz unabhängige String-Definitionen.
Pff...mit fällt dazu irgendwie nicht mehr viel ein
...Hiiilllfe...
-
Prüf mal ob das Dialogfenster zerstört wurde ( oder noch existiert ! ) wenn "CreateRenameFileWnd ()" verlassen wird.
-
So es geht jetzt
, der hat -aus einem mir immer noch unbekannten Grund- die Struktur "SRenameWndInfo" nicht (richtig) übermittelt *hmpf* ... etwas misteriös, da ich das ja auch eigentlich geprüft hatte (
case WM_CREATE: // ... if(pWndData == NULL) // <- Auf Gültigkeit prüfen { SendMessage(hWnd, WM_DESTROY, 0, 0); break; } // ...
).
Nunja, jetzt auch egal... aber trotzdem DANKE (!) @merker, dass Du Dich damit beschäftigt hast(Und um Deine Frage noch zu beantworten, ja es existiert noch
).
Wenn jemand interessiert ist, kann ich den Code auch noch posten (hoffe das ist nicht zu wirrsch, da da nun auch schon andere Elemente drin stehen, die nichts mehr mit dem Problem zu tun haben).