Verwenden Sie das Klassenmitglied als WNDPROC / DLGPROC mit oder ohne global
Ich werde fortfahren und eine Zusammenfassung dazu geben. Wie kann ich eine Dialogprozedur verwenden, die Mitglied einer Klasse ist? Ich erstelle eine Window Wrapper Klasse, aberCreateDialogParam
benötigt eine globale Dialogprozedur, daher habe ich diese Problemumgehung ausprobiert:
Ich habe ein bisschen nach diesem Thema gesucht. Ich mache eineDialog
Klasse, die ich untergeordnet bin, um eine zu machenCMainWnd
und dann instanziieren. In demDialog
Klasse Ich habe eine Mitgliedsfunktion definiert alsINT_PTR CALLBACK Dialog::cb_proc(HWND,UINT,WPARAM,LPARAM)
. Jetzt weiß ich, dass Windows eine globale Funktion als Rückrufprozedur haben muss.
Also habe ich einen gemachtstd::map<HWND,Dialog*> DlgProcs
map, um das Handle des Dialogfensters mit seinem Dialogklassenzeiger zu verknüpfen.
Und einINT_PTR CALLBACK DlgMainProc(HWND,UINT,WPARAM,LPARAM)
so konnte ich das weitergebenCreateDialogParam()
. Im Körper vonDlgMainProc(...)
Ich suche die Karte mit demhWnd
Parameter, um die zu findenDialog*
und zurück seincb_proc(..)
Mitglied.
Mein Problem ist, dass keine der Nachrichten verarbeitet wird, da die Member-Prozedur in meinemDialog
Klasse wird nie gerufen. Auch wenn ich alsMessageBox()
imDlgMainProc
in einemif (DlgProcs.find(hWnd) != DlgProcs.end()) {
Anweisung wird die Messagebox immer und immer wieder angezeigt, bis ich das Programm von Visual Studio 2008 abbrechen musshWnd
in meiner Karte. Das seltsame daran ist, dass es das auch macht, wenn ich es in den Ordner legeelse
Aussage danach, die mir widersprüchlich sagt, dass es NICHT das Finden isthWnd
in der Karte.
Wenn ich eine Messagebox in dascb_proc
Mitgliedsfunktion wird überhaupt nicht angezeigt. Dabei erhalte ich jedoch keine Compiler-, Linker- oder Laufzeitfehler. Wenn ich die Messagebox daraus entferne (um das Programm nicht abbrechen zu müssen, sondern nur zu Debugging-Zwecken), wird das Programm ausgeführt, aber es werden keine Nachrichten verarbeitet, die X-Taste schließt das Programm nicht, Tastenklicks tun nichts.
Hier ist der PasteBin-Code:http://pastebin.com/GsGUBpZU Übrigens, ich habe kein Problem damit, dies zu unterordnen. Mein Fenster ist in Ordnung, es werden nur keine Nachrichten verarbeitet.cb_proc
wird einfach nie angerufen.
BEARBEITEN: Hier sind die relevanten Teile des Codes
map<HWND,Dialog*> g_DlgProcs;
INT_PTR CALLBACK g_MainDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (g_DlgProcs.find(hWnd) != g_DlgProcs.end()) {
Alert("blah"); // Gets executed repeatedly
return g_DlgProcs[hWnd]->cb_proc(hWnd, msg, wParam, lParam);
} else {
Alert("blah"); // Removing the above alert, this gets
// executed repeatedly, erm, as well.. O.o strange
return FALSE;
}
}
Dialog::Dialog(int id, HWND parent /* = HWND_DESKTOP */) {
_id = id;
_parent = parent;
// Tried this before CreateDialogParam
g_DlgProcs.insert(make_pair(_handle, this));
_handle = CreateDialogParam(
(HINSTANCE)GetModuleHandle(NULL),
MAKEINTRESOURCE(id), _parent,
(DLGPROC)g_MainDlgProc, NULL
);
// Then tried it after CreateDialogParam
g_DlgProcs.insert(make_pair(_handle, this));
}
INT_PTR CALLBACK Dialog::cb_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
Alert("blah"); // Never gets executed
bool handled = true;
switch (msg)
{
case WM_INITDIALOG:
OnInitialize();
break;
case WM_COMMAND:
if (HIWORD(wParam) == 0 || HIWORD(wParam) == 1) {
OnMenuCommand((HIWORD(wParam) == 1), (int)LOWORD(wParam));
} else {
OnCtrlCommand((int)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam);
}
break;
case WM_NOTIFY:
{
LPNMHDR head = (LPNMHDR)lParam;
OnNotification(head->code, head->idFrom, head->hwndFrom);
}
break;
case WM_CLOSE:
OnClose(); // DestroyWindow(_handle)
break;
case WM_DESTROY:
OnDestroy(); // PostQuitMessage(0)
default:
handled = ProcessMsg(msg, wParam, lParam);
}
// Convert bool to Windows BOOL enum
return ((handled == true) ? TRUE : FALSE);
}
Weiß jemand, warum es nie aufgerufen wird? Oder führe mich einfach zu einer anderen Möglichkeit, eine Mitgliedsfunktion als DLGPROC zu verwenden?