Windows Api FileDialog öffnet wann er lustig ist

Olaf Lehmann

Mitglied
Hallo erstmal,
ich versuche mich erstmalig an Windows Programmierung ohne MFC. Ich benutze VisualStudio2008 und hab Windows Vista.
Alles in allem ging alles besser als gedacht (glaubte Windowsprogrammierung ohne MFC wäre viel komplizierter), aber eine größere Schwierigkeit hab ich doch:
Ich nutze den OpenFileDialog, genauer gesagt

Code:
GetOpenFileName( &ofn );

Vorläufig soll der FileDialog beim Klicken auf den Menüpunkt Hilfe/Info... aufgerufen werden.
Nun öffnet sich manchmal der Dialog, manchmal aber nicht. Und das selbst wenn ich den Programmcode nicht ändere. Erst dachte ich, dass vielleicht die Nachricht

Code:
IDM_ABOUT:

nicht ankommt, der weitere Code von IDM_ABOUT (ein Listenfeld wird erzeugt) wird aber ausgeführt. Das verwirrt mich ziemlich.

Ich kämpfe ungefähr seit einer Woche damit. Ich habe herausgefunden, dass verschiedene Änderungen Auswirkungen auf die Erfolgswahrscheinlichkeit haben.
1. Die Erfolgswahrscheinlichkeit steigt etwas, wenn ich vor "Starten ohne Debugging" "Neu erstellen" ausführe.
2. Früher hatte ich das Listenfeld bereits in

Code:
BOOL InitInstance(HINSTANCE hInstance,
int nCmdShow)

erzeugt. Dabei war die Erfolgswahrscheinlichkeit VIEL geringer.
3. Wenn ich ein zweites

Code:
GetDC()

erzeuge (mit einem Zeichenkontext klappt es seit dem späteren Erzeugen des Listenfelds meistens), sinkt die Erfolgswahrscheinlichkeit fast auf 0 (aber nicht ganz).

Der erste Zeichenvorgang mittels GetDC() wird nach dem einfachen Klicken auf einen Wert im Listenfeld ausgelöst. Dabei wird eine Funktion ausgelöst, in welcher sich
Code:
GetDC()
...
Code:
ReleaseDC()
befindet.

Das zweite Zeichenvorgang (der meistens nicht ausgeführt werden kann, da keine Daten zur Verfügung stehen, da ich keine Datei auswählen kann - der aber falls die FileBox doch erscheint ebenfalls funktioniert)wird oder soll ausgelöst werden durch WM_KEYDOWN einer Taste.
Es bleibt sich gleich ob ich das Erzeugen des Zeichenkontextes

Code:
hdc = GetDC(hWnd);
HBRUSH hBrush;
hBrush = CreateSolidBrush(RGB(240,240,240));
HBRUSH hOldBrush;
hOldBrush = (HBRUSH) SelectObject(hdc,hBrush);

direkt hinter
Code:
case: WM_KEYDOWN

oder

erst weiter unten unter

Code:
case: 86

setze. Am Ende gebe ich natürlich mit

Code:
SelectObject(hdc,hOldBrush); //Pinsel freigeben
DeleteObject(hBrush);
ReleaseDC(hWnd, hdc);

den Zeichenkontext wieder frei.


Für mich ist halt schwer nachzuvollziehen wieso die FileBox selbst bei unverändertem Code manchmal öffnet und manchmal nicht.:confused:

Bin für jeden Hinweis dankbar.
MfG Olaf
 
Zuletzt bearbeitet:

cwriter

Erfahrenes Mitglied
Hi

Ich benutze VisualStudio2008 und hab Windows Vista.
Das ist alles recht alt. An sich macht das nichts, aber wir können so nichts reproduzieren, was auf die Umgebung zurückzuführen ist.

Erst dachte ich, dass vielleicht die Nachricht
IDM_ABOUT:

nicht ankommt, der weitere Code von IDM_ABOUT (ein Listenfeld wird erzeugt) wird aber ausgeführt. Das verwirrt mich ziemlich.
Die Nachrichten kommen eigentlich immer an (ausser, du hast sie geblockt).

1. Die Erfolgswahrscheinlichkeit steigt etwas, wenn ich vor "Starten ohne Debugging" "Neu erstellen" ausführe.
Ich bezweifle das. Zumindest würde ich es nicht als erste Priorität prüfen.

2. Früher hatte ich das Listenfeld bereits in
BOOL InitInstance(HINSTANCE hInstance,
int nCmdShow)
{...

erzeugt. Dabei war die Erfolgswahrscheinlichkeit VIEL geringer.
Ohne Code ist das sehr schwer zu analysieren.

Für mich ist halt schwer nachzuvollziehen wieso die FileBox selbst bei unverändertem Code manchmal öffnet und manchmal nicht.:confused:
Nun, Computer sind eigentlich deterministisch. Der mit Abstand häufigste Grund für nicht-deterministisches Verhalten sind Over- oder Underflows bei Arrays, dann kommen NULL-Pointer bzw. Use-After-Free.

Es kann auch sein, dass das doppelte getDC() den Fehler verursacht.

Kurze Frage: Verwendest du mehrere Threads? Das ist äusserst heikel und getDC() und ReleaseDC() müssen im selben, bestenfalls dem Hauptthread ausgeführt werden.

Gibt es Unterschiede zwischen Debug- und Releasemode?
Gibt VS Warnungen an?
(Falls es das damals schon gab: Was sagt die Codeanalyse?)

In den Kommentaren wird empfohlen, CoInitializeEx aufrufen. Ich weiss nicht, inwiefern das bei dir auch zutrifft...
https://msdn.microsoft.com/de-de/library/windows/desktop/ms646927(v=vs.85).aspx

Gruss
cwriter
 
Zuletzt bearbeitet:

Olaf Lehmann

Mitglied
Hab eben wies scheint den Fehler gefunden.
Ich hatte den OPENFILENAME Code aus irgendeinen Forumthread kopiert und nicht aufgepasst.
Code:
HWND hwndFile;
//Initialize OPENFILENAMEZeroMemory(&ofn,
sizeof(ofn));
ofn.lStructSize =
sizeof(ofn);
ofn.hwndOwner = hwndFile;

In der letzten Zeile steckt der Wurm. Dort muss wohl mein Hauptfensterhandle stehen. Mein Hauptfenster heisst aber hWnd. Nachdem ich das umgeändert habe (und HWND hwndFile auskommentiert habe) klappts.

Merkwürdig bleibt dennoch, dass es trotzdem manchmal ging.

Danke vielmals!
Olaf