2009-05-13 8 views
7

Imagine que tengo un CDialog que crea controles dinámicamente cuando el usuario hace clic en un botón. Podría ser así:¿Cómo se manejan los mensajes de los controles creados dinámicamente en una aplicación MFC?

// We don't know which is the first id for the new buttons until runtime (!) 
MyDialog::MyDialog(/*whatever parameters needed*/, first_id) 
    : next_id_(first_id) 
{ /*...*/ } 

BOOL MyDialog::OnSomeButtonClicked() 
{ 
    CButton* new_button = new CButton; 
    new_button->Create("Caption", WS_CHILD | WS_VISIBLE, this->new_button_rect_, 
        this, this->next_id_++); 
} 

Entonces mi pregunta sería: ¿Cómo podría manejar los mensajes de este botón? ¿Es posible utilizar el recurso de mapa de mensajes MFC?

La solución debería funcionar tanto en vs6 como en vs2005.

¡Gracias!

Respuesta

6

Estas son las soluciones que he encontrado hasta ahora en orden de relevancia:

  1. Uso ON_COMMAND_RANGE si se puede definir el rango de los identificadores de control que desea manejar.

  2. Sobrecarga CWnd::PreTranslateMessage() y haz lo que quieras con los mensajes recibidos. NOTA: Cuando se trata de botones, tenga en cuenta que el evento BN_CLICKED NO se envía a PreTranslateMessage sino que se envía directamente al procedimiento de ventana.

  3. Sobrecarga CWnd::WindowProc() y haz lo que quieras con los mensajes recibidos. TEN EN CUENTA que cuando se trata de botones, esta es la ÚNICA MANERA que he encontrado para manejar el evento BN_CLICKED.

Enlaces de interés:

espero que esto ayude ... gracias a todos por sus contribuciones.

0

Creo que este artículo lo explica bastante bien y tiene un código fuente. No lo he intentado así que no puedo garantizar que funcione, pero en el momento en que pensé que podría ser útil.

Article

+0

El mal, es probablemente muy bien para usar PreTranslateMessage para este tipo de cosas, pero sigo preguntando si hay una manera de utilizar el mapa instalación mensaje de MFC: S –

5

Eventhough usted no sabe los valores exactos del ello, si se conoce el posible rango de ID a continuación, la siguiente macro se puede utilizar.

BEGIN_MESSAGE_MAP(MyDialog, CDialog) 
    ... 
    ... 
    ON_COMMAND_RANGE(1000, 5000, OnButtonDynamic) 
END_MESSAGE_MAP() 


void MyDialog::OnButtonDynamic(UINT nID) 
{ 

} 

Esto funcionará para los identificadores en el rango 1000 - 5000.

+0

Uhm, gracias por la respuesta, pero ¿cómo podría saber el rango por adelantado? –

0

Puede encontrar detalles (+ mucho más) en los cuadros de diálogo no modal there.

+0

Creo que esto no tiene relación alguna: S –

0

inserte la entrada de ID del controlador en Resouce.h A continuación, inserte la entrada en el mapa de mensajes del controlador como ON_BN_CLICKED (IDC_BTNCREATE, OnBnClickedrunCreated) o puede utilizar directamente el identificador de número entero como ON_BN_CLICKED (1200, OnBnClickedrunCreated) Si usa la segunda versión, entonces hay sin necesidad de insertar la entrada en resource.h. Dé definación y declaración del manejador en los archivos .h y .cpp. obtendrás tu respuesta.

2

Llego unos años tarde a esta fiesta, pero la solución a esto es asignar el mismo ID de control a cada botón (no es necesario 'reservar' la identificación en el recurso.h, y no hay restricciones artificiales en la cantidad de controles que se pueden crear), para salvar el identificador de ventana y utilizar GetCurrentMessage() en el controlador para ese botón:

// resource.h 
#define IDC_DYNAMIC_BUTTON 123 

// In message map 
ON_BN_CLICKED(IDC_DYNAMIC_BUTTON, OnDynamicButtonClicked) 

// Store the window handles when creating them in a member: 
std::map<HWND, SomeStruct> m_Buttons; 
... fill this map when creating the buttons, presumably in OnInitDialog() 

// Actual handler 
void MyDialog::OnDynamicButtonClicked() 
{ 
    const MSG* message = GetCurrentMessage(); 

    if (m_Buttons.find((HWND)message->lParam) != m_Buttons.end()) { 
     // Do something with m_Buttons[(HWND)message->lParam] 
    } 
} 
0

Uso de esta manera: ON_CONTROL_RANGE (wNotifyCode, id1, id2, memberFxn). por ejemplo:

ON_CONTROL_RANGE(EN_UPDATE, IDC_EDIT_START, IDC_EDIT_END, OnEnUpdateEditParams) 
Cuestiones relacionadas