Benutzerdefinierte Nachrichten Hilfeeeeeeeeeeeeeeeeeeeeeee
-
Hi,
hat von euch jemand eine Ahnung, wie ich aus einer von CWnd abgeleiteten Klasse eine Nachricht an ihr übergeordnetes Fenster schicken kann?
zum besseren Verständniss ein einfaches (wenn auch sinnloses) Beispiel:
ich leite eine Klasse (CMyEdit) von CEdit ab, jetzt hat das Edit Steuerelement
Ereignisse wie zum Beispiel EN_CHANGE, EN_SETFOCUS usw. auf die ich im übergeordneten Fenster (zb. Dialogfeld) reagieren kann.
Ich will nun ein Benutzerdefinierte Ereigniss aus der abgeleiteten Klasse raus
erzeugen, das genauso oder so ähnlich wie die oben genannten funktioniert,
zB. wenn der Benutzer ein X eingibt soll das Ereigniss EN_XPRESSED (is jetzt nur als Beispiel) auftreten und im übergeordneten Dialogfeld behandelt werden.wär euch für ne schnelle Antwort super dankbar!
(mach grad ne Technikerarbeit in VC++ 6.0 und die Zeit wird immer knapper)Grüße!!
-
SendMessage(), mit eigenen Nachrichten, etwa
#define MSG_XPRESSED 234
(wäre toll, wenn's sich nicht mit wm_close oder so überschneidet, was den wert angeht...)
-
hi brot, danke für die schnelle Antwort
das mit SendMessage hab ich grad ausprobiert, hat aber nich richtig gefunzt
also ich hab in meiner CMyEdit, deren Parent ein Dialog ist, die nachricht geschickt mit GetParent->PostMessage(MSG_IRGENDWAS, 0, 0);
und in meinem Dialogfeld in der überschriebenen PreTranslateMessage(..)
(weil ich nich weiss wie ich das mit der Messagemap hinkriegen soll)
auf eben diese Nachricht geprüft, aber kam leider nix an.für MSG_IRGENDWAS hab ich unzählige Werte zwischen 0 und 0xFFFF probiert, aber kam nix.
zum Spass hab ich mal die WM_CLOSE gesendet und die ist angekommen.
weisst Du vielleicht wo ich zu dem Thema etwas Beispielcode herbekommen kann?
Danke!
-
Wenn du die Nachricht in deiner Messagemap prüfen willst, dann musst du folgendes eintragen:
// Nachrichtendefinition #define MSG_IRGENDWAS WM_USER + 1
// MessageMap BEGIN_MESSAGE_MAP(CWndMousePos, CWnd) //{{AFX_MSG_MAP(CWndMousePos) ON_WM_PAINT() //}}AFX_MSG_MAP ON_MESSAGE(MSG_IRGENDWAS,OnFunktionIrgendwas) END_MESSAGE_MAP()
-
Danke! es funzt schonmal soweit mit der MessageMap, wundert mich nur daß das Teil nicht erst durch PreTranslateMessage() muss.
eine kleine Frage hab ich allerdings noch:
ein Control zB. Button hinterläst MessageMap einen Eintrag wie zB. ON_BN_KLICKED(<ControlID>, <Handler>
bei meiner Benutzerdefinierten siehts so au ON_MESSAGE(<MessageID, <Handler>)also beim Button sagt schon das verwendete Macro, um was es sich handelt und die ControlID woher es kommt.
bei meiner Nachricht wird aber nicht gefragt woher sie kommt
also wenn ich nun mehrere von meinen Editfeldern hab, die alle MSG_IRGENDNENACHRICHT schicken, wird für jedes der gleiche Handler aufgerufen.
geht das auch irgendwie so wie mit dem Button?
-
Ich würde einfach verschiedene Nachrichten definieren, dh. Button1 versender WM_USER + 1, Button2 WM_USER + 2 etc.
-
das macht irgendwie nicht so viel Sinn,
als Beispiel ich hab mehrere Buttons, alle vom Typ CMyButton, wenn jetzt jeder Button eine ander nachricht senden soll müsste ich für jeden eine extra Klasse schreiben (zB. CMyButton1, CMyButton2 usw.) und das ist wohl nicht der Sinn von OOP
zum definieren eines MessageHandlers gibt's auch noch das Macro
ON_CONTROL( wNotifyCode, id, memberFxn )nur mit dem pasiert scheinbar nicht's wenn die entsprechende Nachricht kommt,
möglicherweise muss ich da auch was anderes als SendMessage() verwenden??
-
ich habs jetzt etwas anders gemacht:
senden der Nachricht:
void CMyEdit::OnChange() { NMHDR hdr; hdr.code = MSG_CHANGE; hdr.hwndFrom = m_hWnd; hdr.idFrom = GetDlgCtrlID(); GetParent()->SendMessage(WM_NOTIFY, 0, (LPARAM)&hdr); }
Eintrag in der MessageMap:
ON_NOTIFY(MSG_CHANGE, IDC_EDIT1, OnChangeEdit1)
das ganze funzt auch super für das Beispiel mit dem Editfeld, nur leider ist das nicht mein Problem, sondern:
ich hab eine Klasse die vom CMSFlexGrid (Wrapperklasse für ActiveX Control, wiederun abgeleitet von CWnd) abgeleitet ist, und aus dieser soll nun einen Nachricht an das Dialogfeld geschickt werden in dem sich das FlexGrid befindet.
Obwohl ich alles genau so wie mit dem Editfeld gemacht hab, kommt die nachricht nicht an, hat irgendjemand ne Idee warum???
Dank euch schonmal!!!
PS: das mit WM_NOTIFY hab ich von: www.flounder.com/messaging.htm
-
sorry, hab euch grad 'n scheiss erzählt, die Nachricht kommt doch im Dialogfeld an (grad mit Spy++ getestet), nur der Handler wird nicht aufgerufen.
-
Hallo? hat niemand mehr ne Idee was hier faul sein könnte?
hab schon alles probiert und tausendmal meinen code angesehen.
wenn die Nachricht aus der FlexGrid Klasse kommt wird der Handler im Dialogfeld einfach nicht aufgerufen, obwohl mir Spy++ sagt das sie wohl im Dialog ankommt, mit dem Editfeld hat's doch auch geklappt.wenn mir jemand sagt wie ich hier Dateien hochladen kann, würd ich mal ein anschauliches Beispielprojekt machen und hier posten.
ich will ja nich drängen aber is ziemlich dringend, wie gesagt es geht hier um meine Technikerarbeit und die Zeit wird langsam knapp, also ich wär euch unendlich dankbar wenn ihr 'nen Tipp für mich hättet!
-
ich glaub ich komm dem problem langsam näher, ich hab jetzt mal die OnNotify() von meinem Dialogfeld überschrieben und vor dem Aufruf von OnNotify() der Basisklasse mal nen Haltepunkt gesetzt, und siehe da sie wird auch tasächlich aufgerufen, hab mich dann mal mit dem Debugger in die tiefen der MFC gestürzt :-), und dadurch rausgefunden, daß die Nachricht zuürck an das FlexGrid reflektiert wird.
Schön aber wie kann ich das jetzt verhindern?
-
Hallo,
ich bräuchte immernoch dringend hilfe mit meinem problem!
scheinbar ist das mit dem WM_NOTIFY nicht so einfach, oder schlichtweg unmöglich, vielleicht gibt's ja einen anderen weg das Parentfenster zu benachrichtigen???
ich beschreib euch grad nochmal um was es geht:
ich hab mir ein editierbares MSFlexgrid gebastelt, indem ich eine Klasse von CMSFlexGrid abgeleitet hab und darin alle Funktionalität untergebracht habe die zum editieren gebraucht wird, zB. erzeugen eines Editfelds welches dann über die zu editierende Zelle gelegt wird.
wenn das editieren einer Zelle abgeschlossen ist soll das Editfeld wieder versteckt werden und dessen Inhalt in die Zelle kopiert werden, funzt alles soweit.
Jetzt soll aber zusätzlich dem Parentfenster ermöglicht werden den Text zu formatieren bevor er in der Zelle landet, das hab ich mir so vorgestellt, daß ich dem Parent eine Nachricht schicke, der ich einen Pointer auf den zu formatierenden String und die Spalten Nr. mitgebe, das Parentf. kann dann mit dem String machen was es will und wenn die Nachrichtenbehandlung zurückkehrt wird der String in die Tabelle geschrieben.
das Problem ist, daß ich wiederverwendbaren Code schreiben muss, daher wäre es schlecht wenn ich am Parent was rumpfuschen müsste.
gibt's da eine saubere lösung??
kann ich vieleicht einen event senden, so wie es ein ActiveX Control tut anstatt einer Windowsnachricht??