Utilice el miembro de la clase como WNDPROC / DLGPROC con o sin global
Continuaré y daré un resumen de esto, ¿cómo puedo usar un procedimiento de diálogo que es miembro de una clase? Estoy creando una clase de envoltura de ventana, peroCreateDialogParam
necesita un procedimiento de diálogo global, así que intenté esta solución:
He hecho un poco de búsqueda sobre este tema. Estoy haciendo unDialog
clase que estoy subclasificando para hacer unaCMainWnd
y luego instanciar eso. En elDialog
clase tengo una función miembro definida comoINT_PTR CALLBACK Dialog::cb_proc(HWND,UINT,WPARAM,LPARAM)
. Ahora, sé que Windows debe tener una función global como un procedimiento de devolución de llamada.
Así que hice unstd::map<HWND,Dialog*> DlgProcs
map para asociar el identificador de la ventana de diálogos con su puntero de clase Dialog.
Y unINT_PTR CALLBACK DlgMainProc(HWND,UINT,WPARAM,LPARAM)
para que pudiera pasar eso aCreateDialogParam()
. En el cuerpo deDlgMainProc(...)
Busco el mapa para usar elhWnd
parámetro para encontrar elDialog*
y devolver sucb_proc(..)
miembro.
Mi problema es que ninguno de los mensajes se procesa, esto se debe a que el procedimiento de miembro en miDialog
La clase nunca es llamada. Aunque cuando pongo unMessageBox()
enDlgMainProc
dentro de unaif (DlgProcs.find(hWnd) != DlgProcs.end()) {
En ese momento, se muestra el cuadro de mensaje una y otra vez hasta que tengo que abortar el programa de Visual Studio 2008. Lo que me dice que está encontrando elhWnd
en mi mapa Lo raro es que también hace esto si lo pongo en elelse
declaración después de eso, lo que contradictoriamente me dice que NO está encontrando elhWnd
en el mapa
Si pongo un mensaje en el buzóncb_proc
Función miembro que no se muestra en absoluto. Pero durante esto nunca obtengo ningún error de compilación, vinculador o tiempo de ejecución. Cuando elimino el cuadro de mensaje (para no tener que abortar el programa, fue solo para fines de depuración) el programa se ejecuta pero no se procesan los mensajes, el botón X no cierra el programa, los clics de los botones no hacen nada.
Aquí está el código PasteBin:http://pastebin.com/GsGUBpZU Por cierto, no tengo ningún problema en subclasificar esto, mi ventana está bien creada, simplemente no se procesan mensajes,cb_proc
simplemente nunca se llama.
EDITAR: Aquí están las partes relevantes del código.
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);
}
¿Alguien sabe por qué nunca se llama? ¿O tal vez simplemente me guíe a otra forma de usar una función miembro como un DLGPROC?