Verarbeitung der Nachrichten in der Message Map funzt nicht



  • Hallo,
    ich entwickle zur Zeit eine Oberfläche für eine Datenfernübertragungssoftware. Das ganze soll unabhänig von den Fachklassen und der Datenhaltung sein.Nun habe ich folgende Vorstellungen : Sämmtliche Steuerelemente werden zur Laufzeit dynamisch erstellt. Zu Beginn wählt der User das Datenaustausch format aus und klickt dann auf den Weiter Button.Anschließend muss der User den Pfad zu einer Excel Datei eingeben ( indem stecken die Daten, die übertragen werden soll). Nachdem er den Pfad + Dateinamen eingeben hat, klickt er wieder auf den nächsten Weiter-Button. Nun wählt er das Format aus zum Übertragen der Daten ( entweder werden die Daten auf Diskette geschrieben oder per FTP übers Internet übertragen ) und klickt dann auf Finished. Zum Ende erhält er eine Nachricht, das die Daten erfolgreich auf Diskett gespeichert wurden bzw übers Netz versendet wurden ....

    Soweit so gut 😉 Aber beim Aufbau der Öberfläche habe ich ein Paar Probleme.
    Ich hab mir mit dem MFC Wizard eine Dialogbasierende Anwendung mit dem Namen Autoproject( AutoprojectDlg ist ebenfalls von CDialog abgeleitet) erstellen lassen.

    Für den ersten Teil, wo der User das Datenaustauschformat auswählt habe ich mir eine eigene Klasse geeschrieben, die ich von CDialog abgeleitet habe :

    CLDT_DataExchange_Dlg :

    [cpp]
    #ifndef _LDT_DATAEXCHANGE_DLG
    #define _LDT_DATAEXCHANGE_DLG
    #include "stdafx.h"
    
    class CLDT_DataExchange_Dlg : public CDialog
    {
    public:
    	CLDT_DataExchange_Dlg(CWnd *CWndDialog);
        virtual ~CLDT_DataExchange_Dlg();
    public :
    
    	CButton* m_pRadioB_Auf_Arzt_LabArzt;
    	CButton* m_pRadioB_Auf_Arzt_LabGemein;
    	CButton* m_pRadioB_Auf_Arzt_SonstPraxis;
    	CButton* m_pRadioB_Bef_LabArzt_Arzt;
    	CButton* m_pRadioB_Bef_LabGemein_Arzt;
    	CButton* m_pRadioB_Bef_SonstPraxis_Arzt;
    	CButton* m_pPushB_LDT_DataExchange_Next;
    
    	void OnKlickedButton();
    public :
    
    	DECLARE_MESSAGE_MAP()
    
    };
    
    #endif
    

    [/cpp]

    Im Konstruktor von CLDT_Dataexchange_DLG erzeuge ich für den ersten Abschnitt die Steuerelemente :

    [cpp]
    CLDT_DataExchange_Dlg::CLDT_DataExchange_Dlg(CWnd *CWndDialog)
    {
    	m_pRadioB_Auf_Arzt_LabArzt= new CButton();
    	m_pRadioB_Auf_Arzt_LabArzt->Create("Auftragsübermittlung Arztpraxis => Laborfacharzt",WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON,
    		CRect(35,20,450,40),CWndDialog,IDC_AUF_ARZT_LABARZT);
    	m_pRadioB_Auf_Arzt_LabGemein = new CButton();
        m_pRadioB_Auf_Arzt_LabGemein->Create("Auftragsübermittlung Arztpraxis => Laborgemeinschaft",WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON,
    		CRect(35,50,450,70),CWndDialog,IDC_AUF_ARZT_LABGEMEIN);
    	m_pRadioB_Auf_Arzt_SonstPraxis = new CButton();
        m_pRadioB_Auf_Arzt_SonstPraxis->Create("Auftragsübermittlung Arztpraxis => Sonstige Einsendepraxis",WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON,
    		CRect(35,80,450,100),CWndDialog,IDC_AUF_ARZT_SONSTPRAXIS);
    	m_pRadioB_Bef_LabArzt_Arzt = new CButton();
        m_pRadioB_Bef_LabArzt_Arzt->Create("Befundübermittlung Laborfacharzt => Arztpraxis",WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON,
    		CRect(35,110,450,130),CWndDialog,IDC_BEF_LABARZT_ARZT);
    
    	m_pRadioB_Bef_LabGemein_Arzt = new CButton();
    	m_pRadioB_Bef_LabGemein_Arzt->Create("Befundübermittlung Laborgemeinschaft =>Arztpraxis",WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON,
    		CRect(35,140,450,160),CWndDialog,IDC_BEF_LABGEMEIN_ARZT);
        m_pRadioB_Bef_SonstPraxis_Arzt =new CButton();
    	m_pRadioB_Bef_SonstPraxis_Arzt->Create("Befundübermittlung Sonstige Einsendepraxis => Arztpraxis",WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON,
    		CRect(35,170,450,190),CWndDialog,IDC_BEF_SONSTPRAXIS_ARZT);
    	m_pPushB_LDT_DataExchange_Next = new CButton();
    	m_pPushB_LDT_DataExchange_Next->Create("Weiter",WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,
    		CRect(400,270,500,300),CWndDialog,IDC_LDT_DATAEXCHANGE_NEXT);
    }[/cpp]
    

    Damit das Erstellen der Buttons auch klappt, habe ich den Pointer des aktuelllen CWnd-Objektes des Hauptfensters Konstruktor der Klasse übergeben :

    [cpp]
    BOOL CAutoProjectDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// Hinzufügen des Menübefehls "Info..." zum Systemmenü.
    
    	// IDM_ABOUTBOX muss sich im Bereich der Systembefehle befinden.
    	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    	ASSERT(IDM_ABOUTBOX < 0xF000);
    
    	CMenu* pSysMenu = GetSystemMenu(FALSE);
    	if (pSysMenu != NULL)
    	{
    		CString strAboutMenu;
    		strAboutMenu.LoadString(IDS_ABOUTBOX);
    		if (!strAboutMenu.IsEmpty())
    		{
    			pSysMenu->AppendMenu(MF_SEPARATOR);
    			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    		}
    	}
    
    	// Symbol für dieses Dialogfeld festlegen. Wird automatisch erledigt
    	//  wenn das Hauptfenster der Anwendung kein Dialogfeld ist
    	SetIcon(m_hIcon, TRUE);			// Großes Symbol verwenden
    	SetIcon(m_hIcon, FALSE);		// Kleines Symbol verwenden
    
    	CLDT_DataExchange_Dlg *test=new CLDT_DataExchange_Dlg(this);
    	// TODO: Hier zusätzliche Initialisierung einfügen
    	return TRUE;  // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten
    }[/cpp]
    

    Die Steuerelemente werden korrekt erzeugt.Aber irgendwie klappt die Verarbeitung der Nachrichten in der eigenen Message Map nicht :

    [cpp]
    
    void CLDT_DataExchange_Dlg::OnKlickedButton()
    {
      m_pRadioB_Bef_LabGemein_Arzt->ShowWindow(SW_HIDE);
    
    }
    
    BEGIN_MESSAGE_MAP(CLDT_DataExchange_Dlg,CDialog)
    	ON_BN_CLICKED(IDC_LDT_DATAEXCHANGE_NEXT,OnKlickedButton)
    END_MESSAGE_MAP()
    
    [/cpp]
    

    Wenn ich auf den Pushbutton drücke, dann passiert einfach nichts. Eigentlich sollte doch eins der 6 Radiobuttons, die ich im Konstruktor erstellt habe, unsichtbar in der Anwendung werden.
    So, wie ich es gemacht habe mit dem ersten Abschnitt ( Selektierung des Datenaustauschformates ) wollte ich es auch mit den anderen Abschnitten machen.
    ( sprich ne eigene Klasse schreiben, die die Steuerlemente für die Eingabe der ExcelDatei, etc machen



  • Hast Du in "OnKlickedButton" schon einen Breakpint gesetzt? Kommt er da rein?



  • nein, er geht leider gar nicht in die Funktion rein 😞



  • Um nochmal eins klar zustellen ( vielleicht habe ich mich nicht ganz klar ausgedrückt ). Ich habe nur einen Dialog ( das Hauptfenster ). Bei der Klasse CLDT_DataExchange_DlG(welche von CDialog abgeleitet ist ) habe ich keinen modalen Dialog zusätzlich erstellt. Ich versuche nur mit einem Dialog ( dem Dialog, den der Wizard automatisch generiert hat ) zu arbeiten. Kann es sein, das es so nicht funktioniert, wie ich es vorhabe ?



  • du musst die Nachricht doch auch noch in deiner Headerdatei hinzufügen/bekanntmachen.
    Ich glaube das muss so heissen:

    afx_msg void OnKlickedButton();    //nicht bloss OnKlickedButton()
    

    Hoffe das funzt. 😉



  • Moin Paul,

    In der Headerdatei habe ich sie auch deklaruert, allerdings ohne dem Prefix "afx_msg" .

    Nun ja, ich habe es hinbekommen, das er in die Methode OnKlicked Button rein geht.
    Die Nachrichten des Hauptfensters werden in Implementierungsdatei von "AutoprojectDlg.cpp" verarbeitet, dort wird ja auch der Dialog erstellt.

    In die Nachrichtentabelle habe ich dann einfach folgendes eingetragen :

    [cpp]
    BEGIN_MESSAGE_MAP(CAutoProjectDlg, CDialog)
    	ON_WM_SYSCOMMAND()
    	ON_WM_CLOSE()
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	//}}AFX_MSG_MAP
    	ON_BN_CLICKED(IDC_LDT_DATAEXCHANGE_NEXT,CLDT_DataExchange_Dlg::OnBNClicked)
    END_MESSAGE_MAP()
    [/cpp]
    

    Na ja, eigentlich wollte ich,das die Nachrichten in der eigenen Klasse verarbeitet werden, die ich geschrieben habe. Das scheint wohl nicht zu funktionieren.

    Nochmal vielen Dank für die Hilfe und Tipps.

    Bodo



  • Das muss aber auch in der eigenen Klasse gehen. Was sagt denn der Compiler, wenn du afx_msg hinzugefügt hast?



  • Das Programm wird ohne Fehler und Warnungen übersetzt, jedoch werden die Nachrichten in der eigenen Klasse nicht bearbeitet. (Ich kann auf den Buton drücken und drücken - es passiert einfach nichts )Er geht geht gar nicht in die Methode OnBNClicked ( hab die Methode von OnKlicked Button in OnBNClicked umbenannt ). Die Verarbeitung klappt nur wenn ich folgendes schreibe :

    [cpp]
    BEGIN_MESSAGE_MAP(CAutoProjectDlg, CDialog)
    	ON_WM_SYSCOMMAND()
    	ON_WM_CLOSE()
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	//}}AFX_MSG_MAP
    	ON_BN_CLICKED(IDC_LDT_DATAEXCHANGE_NEXT,CLDT_DataExchange_Dlg::OnBNClicked)
    END_MESSAGE_MAP()
    [/cpp]
    

    Gruss Bodo



  • Paul_C. schrieb:

    Das muss aber auch in der eigenen Klasse gehen. Was sagt denn der Compiler, wenn du afx_msg hinzugefügt hast?

    afx_msg ist folgendes

    #define afx_msg
    

    🤡 Das ist ein "Leer-Define" und soll in der Klasse nur optisch verdeutlichen, dass diese Methode eine Nachricht verarbeitet.

    Wenn die Methode nicht ausgeführt wird, dann liegst daran, dass sie nicht an die Klasse weitergeleitet wird.
    Du kannst mal zu Testzwecken schauen, ob die in der PreTranslateMessage durchgeht.



  • *ups*. Wie peinlich. Dachte immer, das muss dahin, ohne nachzuschauen, was es genau ist. Werde mich bessern, versprochen. *ganzrotimsandeversink* 🤡



  • *hehe* Visual Assistent rulez, *gg* Maus drüber halten und du siehst was hinter dem #define steht^^



  • Jaja, ist ja schon gut. Ganz so doof bin ich nicht. :p

    MfG,
    Paul.

    😉



  • Pellaeon schrieb:

    Paul_C. schrieb:

    Das muss aber auch in der eigenen Klasse gehen. Was sagt denn der Compiler, wenn du afx_msg hinzugefügt hast?

    afx_msg ist folgendes

    #define afx_msg
    

    🤡 Das ist ein "Leer-Define" und soll in der Klasse nur optisch verdeutlichen, dass diese Methode eine Nachricht verarbeitet.

    Wenn die Methode nicht ausgeführt wird, dann liegst daran, dass sie nicht an die Klasse weitergeleitet wird.
    Du kannst mal zu Testzwecken schauen, ob die in der PreTranslateMessage durchgeht.

    Japp, wie es scheint, werden die Nachrichten nicht an die Klasse weitergeleitet sondern von der Nachrichtenqueue von AutoprojectDlg behandelt. Ich weiss auch nicht, wie ich testen kann, ob sie die PreTranslateMessage durchgeht. Wie muss ich es machen, das die eigene geschriebene Klasse die Nachrichtenbehandlung für das Hauptfenster übernimmt ? Vielleicht stell ich mich einfach zu blööd an ( was ich natürlich nicht hoffe bzw glaube ).Könntest du es büdde einwenig erläutern ?

    Gruss Bodo



  • Die PreTranslateMessage-Methode ist einfach dazu da, alle Nachrichten, welche die Klasse erhält, durchgehen zu können, bevor die Nachrichten dann "weiter verarbietet" werden. Die Methode überschreibt man sonst aber auch mit dem KLassenassistenten.

    Ich versteh noch nicht ganz, was du mit dem Dialog anfangen willst?
    Kannst dir ja auch noch einen DIalog mit dem Assistenten anlegen und testen, ob mit dem das dann funzt, was du dir vorstellst.



  • Wie gesagt, ich versuche nur mit einem Dialog zu arbeiten, dem Hauptdialog.

    Abschnitt 1 :
    Am Anfang muss der User den Datenaustauschformat vornehme ( Befundübermittlung Arzt => Laborfacharzt). Dieser erste Abschnitt wird durch die Klasse CLDT_Dataexchange_Dlg vorgenommen. Diese Klasse ist verantwortlich für den jeweiligen Datenaustauschformat. ( Das sind 6 Radiobuttons und ein einfach Pushbutton ).

    Abschnitt 2:

    Im nächsten Abschnitt muss eine Excel Datei eingelesen und noch eine weitere Datei eingelesem werden. Dazu muss der User in einem Editfeld den Pfad zur Excel Datei eingeben und auch den Pfad zur anderen Datei. Die Radiobuttons sind dann nicht mehr zu sehen, nur über einen Zurück Button kann er die Wahl wieder ändern. Außerdem soll es dann einen Weiter Button geben um zum nächsten Abschnitt zu kommen:

    Abschnitt 3:
    Dort ist kann er dann wählen, wie die Daten übertragen werden sollen. Als Option steht Export auf Diskette bzw Übertragung via DFÜ.

    Vom Abschnitt 1 gibt es einen Button, der zum Abschnitt 2 führt, bei Abschnitt2 gibt es zwei Buttons, der eine dient um zum ersten Abschnitt wieder zurück zukommen, der andere fürt zum Abschnitt 3

    Ich stelle es mir so vor, wie eine Art Installer, wo ich auch Vor und Zurück Buttons habe. Und dieses wollte ich nur mit dem Hauptdialog realisieren, für jeden einzelen Abschnitt wollte ich ne eine klasse realisieren die das Erzeugen der Steuerelemente übernimmtt sowie die Nachrichtenbehandlung der einzelen Steuerelemente.



  • Wenn du nur mit einem Dialog arbeitest dann hast du auch nur eine Dialog und dieser hat eben auch seine Klasse.
    Das du in einer anderen Steuerlemente erstellst hat damit nichts zu tun. Sie werden eben auf den Dialog gezeichnet.
    Wenn du es so machen willst wie du musst du Dialoge erstellen die als Child in einen Hauptdialog kommen.


Anmelden zum Antworten