[C con Clase] DialogBox

Salvador Pozo salvapozo en gmail.com
Vie Jun 17 16:49:55 CEST 2016


El pasado 2016-06-16 17:50:25, Antonio Escalante escribió:
 
AE> Hola grupo,
AE> Necesito ayuda con la funcion DialogBox. La idea es llevarme el
AE> procedimiento de un dialogo a una funcion de una clase fuera del .cpp
AE> principal.
AE> Por ejemplo, dada una clase (claseEjemplo) la idea seria que al clickear
AE> una entrada del menu (ID_LANZA_DIALOGO) se lanzara el dialogo definido
AE> en el cpp de la clase aparte. Seria algo asi:
AE> (en el .cpp principal)
AE> case WM_COMMAND:
AE>    switch(LOWORD(wParam))
AE>       case ID_LANZA_DIALOGO:
AE>          DialogBox(GetModuleHandle(NULL),
AE> MAKEINTRESOURCE(IDD_DIALOGO_NEWUSER), hwnd, claseEjemplo.dialogo(HWND hwnd,
AE> UINT msg, WPARAM wParam, LPARAM lParam)
AE> De que tipo deberia ser el dialogo en prototipo DLGPROC? BOOL CALLBACK?. Lo
AE> que he leido en google no me ha aclarado nada.
AE> Alguien podria explicarmelo sin complicarlo mucho?. Muchas gracias.

Hola:

Entiendo que quieres, al menos en cierto modo, encapsular un cuadro de diálogo en una clase.
Hace tiempo estuve investigando sobre este tema. Al final tuve que acudir al código fuente de otros encapsulados, como MFC, y por lo que recuerdo, los procedimientos de ventana tienen que ser estáticos, es decir, todas las ventanas de la misma clase deben compartir el mismo procedimiento de ventana, y lo mismo se aplica a cuadros de diálogo.
Te pongo un ejemplo sencillo, espero que te aclare algunas cosas.

----8<------
#define ID_BOTON 100

class CCDialog {
public:
    CCDialog(HINSTANCE hInstance, char* recurso, HWND hwnd, LPARAM lParam);
    ~CCDialog();
private:
    // Procedimiento de diálogo estático:
    static BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);

};

// Constructor
CCDialog::CCDialog(HINSTANCE hInstance, char* recurso, HWND hwnd, LPARAM lParam) {
    DialogBoxParam(hInstance, recurso, hwnd, (DLGPROC)&DlgProc, lParam);
}

// Destructor
CCDialog::~CCDialog();

// Procedimiento de diálogo
BOOL CALLBACK CCDialog::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)                  /* manipulador del mensaje */
    {
        case WM_INITDIALOG:
            return TRUE;
        case WM_COMMAND:
            switch(LOWORD(wParam)) {
                case IDOK:
                    EndDialog(hDlg, FALSE);
                    break;
            }
            return TRUE;
    }
    return FALSE;
}
...

// Al crear el diálogo, se ejecuta automáticamente:
CCDialog *dialogo = new CCDialog(hInstance, "Dialogo", hwnd, 0);

----8<------

MFC declara además el procedimiento de diálogo como virtual, de modo que cuando se crean diálogos basados en CDialog, se puede redefinir el procedimiento de diálogo, y siempre se puede invocar al procedimiento padre.

Por supuesto, se pueden añadir funciones miembro para procesar mensajes concretos, como WM_INITDIALOG, que añadiría los controles e iniciaría miembros de la clase, y se pueden añadir datos miembro, de modo que el procedimiento de diálogo puede acceder a los correctos, usando el puntero this.

Desconozco si hay métodos alternativos, pero esto funciona.

Hasta pronto.


Más información sobre la lista de distribución Cconclase