/* ------- Dialog.h ------- */
#pragma once
#ifndef DIALOG_H_
#define DIALOG_H_
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <map>
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<HWND,Dialog*> 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<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);
}