Dynamische Buttons sollten auf Mausklick reagieren, nun reagiert "alles"... :)
-
Hallo zusammen,
im Programm sollen einige Buttons variablen Inhalts generiert werden, die ich allein aufgrund der relativ hohen Anzahl nicht über Ressourcen verwalten möchte, sondern dynamisch in einem Array.
Der Codeausschnitt, der die Buttons generiert:
while ( f.ReadString ( szText ) == TRUE ) { if ( szText [ 0 ] == '[' ) { ++BlockIndex; Ueberschrift [ BlockIndex ] = szText; BlockZeilenIndex = 0; UeberschriftString = ""; for ( int j = 1; j <= szText.GetLength() - 3; j++ ) UeberschriftString += szText [ j ]; button [ BlockIndex ] = new DynamischerButton; button [ BlockIndex ] -> Create ( UeberschriftString, WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | BS_PUSHLIKE, CRect ( 865 + ( BlockIndex / 22 ) * 180, 44 + (BlockIndex % 22 ) * 25, 1030 + ( BlockIndex / 22 ) * 180, 44 + ( BlockIndex % 22 ) * 25 + 24 ), this, 4546 ); } else { Beschriftung [ BlockIndex ] [ BlockZeilenIndex++ ] = szText; } // else zu: if ( szText [ 0 ] == '[' ) } // while ( f.ReadString ( szText ) == TRUE )
Die Klasse DynamischerButton ist folgendermaßen definiert:
class DynamischerButton : public CButton { public: void OnLButtonDown ( UINT nFlags, CPoint point ); protected: DECLARE_MESSAGE_MAP() };
(Der Klasse Dynamischer-Button wollte ich halt noch einen int mitgeben, der die eigene Nummer als ID speichert und dadurch entsprechend reagieren.)
Die Message-Map schaut so aus:
BEGIN_MESSAGE_MAP(DynamischerButton, CButton) ON_WM_LBUTTONDOWN ( UINT nFlags, CPoint point ) END_MESSAGE_MAP()
Und die Methode, die die Verarbeitung der Nachricht "linker Mausknopf gedrückt" übernimmt, so:
void DynamischerButton::OnLButtonDown ( UINT nFlags, CPoint point ) { MessageBox ( "Mausklick" ); CButton::OnLButtonDown ( nFlags, point ); }
Funktioniert soweit - Die Buttons werden dynamisch aufgebaut.
Klick ich, bevor die Buttons aufgebaut worden sind, im Fenster herum, passiert nichts Außergewöhnliches. Sind die Buttons jedoch dynamisch aufgebaut worden und hab ich erstmal irgendeinen von den Buttons angeklickt, kann ich ab dann im Dialogfenster hinklicken, wo ich will und krieg immer die MessageBox mit Inhalt "Mausklick". Man kann die Anwendung schon nicht mal mehr per Mausklick aufs "x" rechts oben schließen - auch da MessageBox.
Beabsichtig wäre natürlich gewesen, dass die Methode DynamischerButton::OnLButtonDown (...) nur beim Klicken der Buttons aufgerufen wird.
Scheinbar übernimmt aber das ganze Dialogfenster diese Methode, wenn erstmal ein Button angeklickt wurde...
Was ist da schiefgelaufen?
Gruß Maik
-
Du solltest eventuell VOR der Weiterverarbeitung nachschauen, WO überhaupt geklickt wurde (point gegen GetWindowRect vergleichen).
Ansonsten wäre es imho eine bessere Idee, wenn du zentral in deinem Dialog einen ON_CONTROL_RANGE() auf eine "Verteilerfunktion" setzt, die dann den richtigen Button anspricht:
//im Dialog: std::map<UINT,CDynButton> m_Buttons; ON_CONTROL_RANGE(BN_CLICKED,minID,maxID,OnDButton) void OnDButton(UNIT id) { std::map<UINT,CDynButton>::iterator pos=m_Buttons.find(id); if( pos!=m_Buttons.end() ) pos->second.OnButton(); }
(jetzt mußt du nur noch dafür sorgen, daß jeder deiner Buttons eine ID zwischen minID und maxID erhält)
-
CStoll schrieb:
Du solltest eventuell VOR der Weiterverarbeitung nachschauen, WO überhaupt geklickt wurde (point gegen GetWindowRect vergleichen).
Das verstehe ich nicht recht... Da doch nur diese Buttons diese Ereignis-Methode definieren, sollte diese Methode doch (meiner MFC-Anfängervorstellung nach) auch nur dann aufgerufen werden können, wenn diese Buttons geklickt werden, womit ich es eigentlich als klar ansehen würde, dass nur auf einen dieser Buttons geklickt worden sein kann? Wo ist der Denkfehler?
Wie kommt es nun konkret dazu, dass eine Ereignis-Methode, die ja eigentlich nur ganz best. Komponenten zugewiesen wird, urplötzlich für den ganzen Container, mit allem, was da drin rumlungert, greift?
-
JSI_Maik schrieb:
Wo ist der Denkfehler?
Daß die Buttons eben nicht nur ihren eigenen Bereich überwachen - die ankommenden Nachrichten werden nach einem bestimmten Schema durch alle Message-Maps deines Programms durchgeleitet, bis sie von irgendwem aufgefangen werden.
(und ein ON_WM_LBUTTONDOWN-Handler kümmert sich um alle Mausklicks innerhalb deiner Anwendung)