2009-05-13 9 views
7

Stellen Sie sich vor, ich habe einen CDialog, der Steuerelemente dynamisch erstellt, wenn der Benutzer auf eine Schaltfläche klickt. Es könnte so sein:Wie werden Nachrichten von dynamisch erstellten Steuerelementen in einer MFC-App behandelt?

// 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_++); 
} 

Dann meine Frage wäre: Wie könnte ich Nachrichten von diesem Knopf behandeln? Ist es möglich, die MFC-Message-Map-Funktion zu verwenden?

Die Lösung sollte in vs6 und vs2005 funktionieren.

Vielen Dank!

Antwort

6

Dies sind die Lösungen, die ich bisher in der Reihenfolge ihrer Relevanz gefunden habe:

  1. Verwenden ON_COMMAND_RANGE wenn Sie den Bereich der Steuer IDs definieren können Sie behandeln möchten.

  2. Überlasten Sie CWnd::PreTranslateMessage() und tun Sie alles, was Sie wollen, mit den empfangenen Nachrichten. HINWEIS: Beachten Sie beim Umgang mit Schaltflächen, dass das Ereignis BN_CLICKED NICHT an PreTranslateMessage gesendet, sondern direkt an die Fensterprozedur gesendet wird.

  3. Überlasten Sie CWnd::WindowProc() und tun Sie alles, was Sie wollen mit den Nachrichten erhalten. Beachten Sie, dass dies der EINZIGE Weg ist, mit dem ich das BN_CLICKED-Ereignis behandelt habe.

Interessante Links:

Ich hoffe, das hilft ... danke Ihnen allen für Ihre Beiträge.

0

Ich glaube, dieser Artikel erklärt es ziemlich gut und hat Quellcode. Ich habe das nicht versucht, also kann ich nicht garantieren, dass es funktioniert, aber in der Zeit habe ich gedacht, dass es helfen könnte.

Article

+0

Ok, es ist wahrscheinlich gut PreTranslateMessage für diese Art von Sachen zu verwenden, aber ich halte an mich gefragt, ob es einen Weg gibt ist die mfc Nachricht Karte Anlage zu nutzen: S –

5

Eventhough Sie die genauen Werte der ID nicht wissen, wenn Sie den möglichen Bereich von IDs wissen dann das folgende Makro verwendet werden kann.

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


void MyDialog::OnButtonDynamic(UINT nID) 
{ 

} 

für ids im Bereich von 1000 arbeiten Dies wird - 5000.

+0

Ähm, danke für die Antwort, aber Wie könnte ich die Reichweite im Voraus wissen? –

0

Sie Details finden (+ viel mehr) auf modale Dialoge there.

+0

Ich denke, das ist nicht verwandt: S –

0

die Eingabe von ID des Handlers in Resouce.h einfügen dann den Eintrag in der Meldungszuordnung des Handlers einfügen wie ON_BN_CLICKED (IDC_BTNCREATE, OnBnClickedrunCreated) oder Sie können direkt die Integer-ID wie ON_BN_CLICKED verwenden (1200, OnBnClickedrunCreated). Wenn Sie die 2. Version verwenden, dann ist kein Eintrag in resource.h einzufügen. Geben Sie die Definition und die Deklaration des Handlers in der .h- und .cpp-Datei an. Du wirst deine Antwort bekommen.

2

Ich bin ein paar Jahre zu spät zu dieser Party, aber die Lösung dafür ist, die gleiche Steuerelement-ID zu jeder Schaltfläche zuweisen (keine Notwendigkeit, IDs in der Ressource zu reservieren.h und keine künstlichen Beschränkungen über die Höhe der Kontrollen, die) erstellt werden können, den Fenstergriff zu speichern und für diese Schaltfläche GetCurrentMessage() in der Prozedur zu verwenden:

// 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

Verwenden Sie diese Art und Weise: ON_CONTROL_RANGE (wNotifyCode, id1, id2, memberFxn). zum Beispiel:

ON_CONTROL_RANGE(EN_UPDATE, IDC_EDIT_START, IDC_EDIT_END, OnEnUpdateEditParams) 
Verwandte Themen