Reaktion eines Dialogs

Cromon

Erfahrenes Mitglied
Hallo zusammen!

Ich habe ein kleines Problem mit einem Dialog, den ich über CreateDialogParam erstelle. Er legt ein äusserst merkwürdiges Verhalten an den Tag.

Folgende Situation:
Ich habe einen neuen Tab im "Eigenschaften"-Dialog eines gewissen Dateityps erstellt. Wenn man da auf einen Eintrag in einer Listbox doppelklickt soll ein neuer Dialog mit Infos zu diesem Eintrag erscheinen. Dazu verwende ich folgenden Code:
Code:
void ShowDialog(HWND parent, UINT uID, BOOL (CALLBACK* proc)(HWND, UINT, WPARAM, LPARAM), LPARAM lpCreate)
{
	HMODULE hMyMod = GetModuleHandle("ADTProperty.dll");
	if(!hMyMod)
		return;

	PropLParam* lp = (PropLParam*)GetWindowLong(parent, GWL_USERDATA);

	HWND hDlg = CreateDialogParam(hMyMod, MAKEINTRESOURCE(uID), parent, proc, lpCreate);
	SetWindowLong(hDlg, GWL_USERDATA, (LONG)lp);
	ShowWindow(hDlg, SW_SHOW);
	if(!hDlg)
		return;

	MSG msg;
	lp->lParam = true;
	while(lp->lParam)
	{
		while(PeekMessage(&msg, hDlg, 0, 0, PM_REMOVE))
		{
			if(!IsDialogMessage(hDlg, &msg))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
		Sleep(10);
	}
	DestroyWindow(hDlg);
}

In der DialogProc verwende ich folgenden Code:
Code:
BOOL CALLBACK ExtendedProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_INITDIALOG:
		{
			HWND hEdit = GetDlgItem(hwnd, 1007);
			SetWindowText(hEdit, (LPCSTR)lParam);
			SendMessage(hEdit, EM_SETSEL, 0, -1);
			return TRUE;
		}

	case WM_CLOSE:
		{
			PropLParam* lp = (PropLParam*)GetWindowLong(hwnd, GWL_USERDATA);
			lp->lParam = false;
			UpdateWindow(hwnd);
			return FALSE;
		}
	}
	return FALSE;
}

Dieser Dialog wird aus dem Thread des Eigenschaften-Tabs aus aufgerufen und blockiert diesen auch entsprechend. Nun, wo ist das Problem?

Der Dialog reagiert wahnsinng spät. Es ist recht schwer zu erklären. Ein Beispiel:
Der Dialog erscheint. Ich drücke auf das 'x' im Systemmenu und nichts passiert ausser dass das 'x' geklickt wird. Ich drücke nochmals, nichts passiert. Nochmals, das Fenster schliesst sich. Manchmal nach 2 Versuchen, manchmal im 2ten Versuch, manchmal noch viel später. Wenn ich einen Button anklicke in dem neuen Dialog und dann auf das 'x' gehe reagiert es sofort. Selektiere ich etwas im Textfeld geht es auch sofort. Sobald ich irgendeine Aktion im Dialog gemacht habe geht nacher alles.

Dieses Verhalten habe ich auch beim Rumschieben. Der Dialog erscheint, ich drücke in die Titelleiste und das Fenster springt irgendwo hin. Das ist wie beim 'x'. Manchmal springt es 2 bis 3 Mal hin und her, manchmal weniger. Danach funktioniert auch das problemlos.

Woran könnte das liegen?

Gruss
Cromon
 
Nicht direkt die Lösung, aber wieso zum Teufel programmierst du die Funktion DialogBox (modaler Dialog) nach und verwendest die nicht direkt?

Und wenn du da drin eine "kleinere" Message Pump hast, solltest du da tunlichst ALLE Nachrichten weiterverarbeiten, nicht nur die deines Dialoges. Und das Sleep da rausnehmen.

Ist dein Dialog auch im gleichen Thread wie sein Parent? Ich meine, dass das auch Probleme geben könnte, da HWNDs im allgemeinen Thread-bezogen arbeiten.
 
Mittlerweile verwende ich auch DialogBoxParam. Das Problem war da vorher nur, dass ich glaubte nur DialogBox existiere und da fehlt mir der lParam. Aber da es ja auch DialogBoxParam gibt hat sich das gelöst. Da gibt es das Problem nicht.

Gemäss MSDN dürfen für Dialoge bei denen Tastaturinput gewünscht ist nur Messages über TranslateMessage und DispatchMessage verarbeitet werden, bei welchen IsDialogMessage nicht true zurückgibt. So habe ich das da verstanden.

Das Sleep macht durchaus Sinn da ja PeekMessage nicht blockiert und daher bei freier Queue massiv CPU belastet würde. Und da es sich überhaupt nicht um eine zeitkritische Anwendung handelt sind die maximal 10 Millisekunden "Reaktionszeit" durchaus zu verkraften ;), dafür gibt man anderen Threads genügend Zeit um zu agieren.
 
Zurück