/* ------- Dialog.h ------- */ #pragma once #ifndef DIALOG_H_ #define DIALOG_H_ #define WIN32_LEAN_AND_MEAN #include #include using namespace std; // All dialogs share this same procedure. This method actually // uses 'hWnd' to search for the correct member procedure and returns it. class Dialog; extern map g_DlgProcs; INT_PTR CALLBACK g_MainDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); class Dialog { private: int _id; HWND _handle, _parent; // Make non-copyable Dialog(const Dialog& other); Dialog& operator= (const Dialog&); // Dialog procedure INT_PTR CALLBACK cb_procedure(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); protected: Dialog(int id, HWND parent = HWND_DESKTOP); public: INT_PTR CALLBACK cb_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // Properties int ID(void); HWND Handle(void); HWND Parent(void); // Methods LRESULT Send(UINT msg, WPARAM wParam = 0, LPARAM lParam = 0); void Show(void); void Show(int nCmdShow); void Hide(void); void Destroy(void); // Events virtual bool ProcessMsg(UINT msg, WPARAM wParam, LPARAM lParam); virtual void OnClose(void); virtual void OnDestroy(void); virtual void OnInitialize(void); virtual void OnMenuCommand(bool isAccel, int id); virtual void OnCtrlCommand(int code, int id, HWND from); virtual void OnNotification(int code, int id, HWND from); }; #endif // DIALOG_H_ /* ------- Dialog.cpp -------- */ #include "Dialog.h" #include "Macros.h" // Just for Alert(string msg) messagebox macro map 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); }