Я продолжу и дам краткое изложение этого, как я могу использовать процедуру диалога, которая является членом класса? Я создаю класс-оболочку окна, но CreateDialogParam
нужна процедура глобального диалога, поэтому я попробовал этот обходной путь:
Я немного поискал по этой теме. Я создаю класс Dialog
, который я подклассифицирую, чтобы создать CMainWnd
, а затем создаю его экземпляр. В классе Dialog
у меня есть функция-член, определенная как INT_PTR CALLBACK Dialog::cb_proc(HWND,UINT,WPARAM,LPARAM)
. Теперь я знаю, что Windows должна иметь глобальную функцию в качестве процедуры обратного вызова.
Поэтому я сделал карту std::map<HWND,Dialog*> DlgProcs
, чтобы связать дескриптор окна диалогов с его указателем класса Dialog.
И INT_PTR CALLBACK DlgMainProc(HWND,UINT,WPARAM,LPARAM)
, чтобы я мог передать это CreateDialogParam()
. В теле DlgMainProc(...)
я ищу карту для использования параметра hWnd
, чтобы найти Dialog*
и вернуть его член cb_proc(..)
.
Моя проблема в том, что ни одно из сообщений не обрабатывается, потому что процедура-член в моем классе Dialog
никогда не вызывается. Несмотря на то, что когда я помещаю MessageBox()
в DlgMainProc
внутри инструкции if (DlgProcs.find(hWnd) != DlgProcs.end()) {
, окно сообщения отображается снова и снова, пока мне не придется прервать программу из Visual Studio 2008. Это говорит мне, что она находит hWnd
на моей карте. Странно то, что он также делает это, если я добавляю его в оператор else
после этого, что противоречиво говорит мне, что он НЕ находит hWnd
на карте.
Если я помещу окно сообщения в функцию-член cb_proc
, оно вообще не будет отображаться. Но при этом я никогда не получаю ошибок компилятора, компоновщика или времени выполнения. Когда я удаляю из него окно сообщений (чтобы не прерывать программу, это было просто для целей отладки), программа запускается, но сообщения не обрабатываются, кнопка X не закрывает программу, нажатия кнопок ничего не делают.
Вот код PasteBin: http://pastebin.com/GsGUBpZU Кстати, у меня нет проблем с подклассом этого, мой окно создается нормально, просто сообщения не обрабатываются, cb_proc
просто никогда не вызывается.
EDIT: Вот соответствующие части кода
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);
}
Кто-нибудь знает, почему он никогда не вызывается? Или, может быть, просто указать мне другой способ использования функции-члена в качестве DLGPROC?