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?

Antworten auf die Frage(3)

Ihre Antwort auf die Frage