MFC-Programmierung ohne MFC-Anwendungsassistent



  • Hallo,

    kennt jemand von Euch ein Tutorial im Internet, in dem die Programmierung von MFC in Visual C++ 6 erklärt wird, wobei man nicht den Anwendungsassistenten benutzt? Bis jetzt habe ich sowas erst zweimal gesehen (www.cpp-tutor.de/mfc/mfc/kap3/lektion2.htm ff. und www.henkessoft.de/mfc_einsteigerbuch_kapitel5.htm). Das Problem hierbei ist nur, daß diese Tutorials mit Einzelfensteranwendungen und der Klasse CFrameWnd arbeiten, und ich hätte das ganze gern mit einer dialogfeldbasierten Anwendung (abgeleitete Klasse von CDialog).

    Alternativ wäre ich auch dankbar, wenn mir jemand sagen könnte, wo in meinem Quellcode der Fehler liegt. Das Zeug kompiliert zwar ohne Fehler und stürzt auch nicht ab, aber das Dialogfeld geht nicht auf.

    Anwendung.h:

    #ifndef ANWENDUNG_H
    #define ANWENDUNG_H
    
    #include <afxwin.h>
    
    class CAnwendungApp: public CWinApp
    {
    public:
    	virtual BOOL InitInstance ();
    	DECLARE_MESSAGE_MAP ()
    };
    
    #endif
    

    Anwendung.cpp:

    #include <afxwin.h>
    #include "Anwendung.h"
    #include "DialogDlg.h"
    
    CAnwendungApp appAnwendung;
    
    BOOL CAnwendungApp::InitInstance ()
    {
    	CDialogDlg dlgDialog;
    	m_pMainWnd=&dlgDialog;
    
    	dlgDialog.DoModal ();
    	/*Hier ist das Problem. Statt aufzugehen,
    	  passiert gar nichts und das Programm
    	  läuft einfach durch.*/
    
    	return FALSE;
    }
    
    BEGIN_MESSAGE_MAP (CAnwendungApp, CWinApp)
    	ON_COMMAND (ID_HELP, CWinApp::OnHelp)
    END_MESSAGE_MAP ()
    

    DialogDlg.h:

    #ifndef DIALOG_DLG_H
    #define DIALOG_DLG_H
    
    #include <afxwin.h>
    
    class CDialogDlg: public CDialog
    {
    public:
    	CDialogDlg (CWnd *pParent=NULL);
    	enum {IDD=1000};
    
    protected:
    	virtual void DoDataExchange (CDataExchange *pDX);
    	DECLARE_MESSAGE_MAP()
    };
    
    #endif
    

    DialogDlg.cpp:

    #include <afxwin.h>
    #include "DialogDlg.h"
    
    CDialogDlg::CDialogDlg (CWnd *pParent):
    	CDialog (CDialogDlg::IDD, pParent)
    {
    }
    
    void CDialogDlg::DoDataExchange (CDataExchange *pDX)
    {
    	CDialog::DoDataExchange (pDX);
    }
    
    BEGIN_MESSAGE_MAP (CDialogDlg, CDialog)
    END_MESSAGE_MAP ()
    

    Es wäre schön, wenn mir jemand helfen könnte.





  • ... und was steht im resourcefile ?

    ach ja.... "MFC from the ground up - Second Edition" <- genau das Buch das du suchst !



  • @....
    Das steht auch in dem oben von mir beschriebenen Buch drin. Da wird absolut kein Klassenassistent benutzt... War für mich sehr hilfreich zum verständnis 😃



  • An guenni81:
    Wird in dem Buch anhand vom Microsoft- oder vom Borland-Compiler gearbeitet? In einem Kommentar steht nämlich "dass die Umsetzung der Beispiele im Borland C++ Builder sehr kompliziert ist." Meint der jetzt nur, daß die Beispiele generell kompliziert sind oder daß eine Portierung von dem einen zum anderen Compiler kompliziert ist?

    An ....:

    ... und was steht im resourcefile ?

    Braucht man sowas überhaupt? Na gut, da, wo ich

    enum {IDD=1000};
    

    geschrieben hab, stand beim Anwendungsassistenten der Wert nochmal als Konstante in "resource.h". Aber da keine der beiden von mir genannten Tutorials sowas benutzten, hab ich die Datei auch erstmal weggelassen, in der Hoffnung, daß ich das später noch eleganter hinkriege. Aber jetzt muß ich erstmal rausfinden, wie dieses blöde Dialogfenster tatsächlich aufgeht.
    Zu Deinem Buch: Eigentlich hatte ich nicht vor, so an die 60 EUR auszugeben. Ich brauch ja auch keine komplett ausführliche Erklärung, sondern bloß hier und da mal ein paar Lösungsansätze.

    Hat vielleicht noch jemand eine Idee, wie mein Quellcode richtig lauten müßte? Wenn ja, brauche ich möglicherweise gar kein weiteres Buch/Tutorial, sondern kriege das relativ allein hin.



  • In dem Buch wird mit dem MS Kompilers gearbeitet...
    In der Resourcedatei ist festgelegt wie dein Dialog/Formview aussieht, wo welcher Button sitzt und wie dieser heißt, was für ein Style dieser hat, etc.

    Das von mir oben gespotete Buch kostet nur EUR 3,95
    also nicht die Welt und sehr lohnenswert...



  • Beispiel für MFC-Anwendung OHNE Wizard (VC6) <- Sollte funktionieren (konnte es nicht testen, da ich keine IDE z V habe) <- bitte testen !

    //************************************************
    // file : DIALOG.RC
    //
    //************************************************
    #include <afxres.h>
    #include "resource.h"
    
    //************************************************
    // Menü fürs Hauptfenster definieren
    //************************************************
    DialogMenu MENU
    {
        POPUP "&Dialog"
        {
             MENUITEM "B&eispiel Dialog", IDM_DIALOG
             MENUITEM "&Beenden", IDM_EXIT
        }
        MENUITEM "&Hilfe", IDM_HELP
    }
    
    //************************************************
    // Kurzwahltasten zuweisen
    //************************************************
    DialogMenu ACCELERATORS
    {
        VK_F1, IDM_HELP,   VIRTKEY
        VK_F2, IDM_DIALOG, VIRTKEY
        VK_F3, IDM_EXIT,   VIRTKEY
    }
    
    //************************************************
    // Beispieldialog mit einem Button definieren
    // Hier wird ein Dialog mit dem Namen 
    // "Beispiel Dialog" definiert, welcher seine
    // linke obere ecke an position 20,20 hat,
    // und eine grösse von 150 mal 35.
    // Mit STYLE wird der Typ des Dialogs festgelegt.
    // 
    // Hier einige der Standardstyles:
    // -------------------------------
    //
    // WS_BORDER............Rahmen wird gezeichnet
    // WS_CAPTION...........Titelleiste wird angezeigt
    // WS_HSCROLL...........Horizontale Scrollbar wird angezeigt
    // WS_VISIBLE...........Wenn der Dialog aktiviert wird -> anzeigen
    // WS_SYSMENU...........Systemmenü anzeigen
    //
    // In unserem "Beispiel Dialog" wird nun ein
    // Button mit dem Namen "Klick mich", an der Position 30,40
    // mit der Grösse 30 mal 15 angelegt.
    //************************************************
    BeispielDialog DIALOG 20,20,150,35
    CAPTION "Beispiel Dialog"
    STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
    {
        PUSHBUTTON "Klick mich", IDD_BUTTON, 30,40,30,15,
                      WS_CHILD | WS_VISIBLE | WS_TABSTOP
    }
    
    //************************************************
    //************************************************
    //************************************************
    
    //************************************************
    // file: resource.h
    //
    // definiert die IDs für die Steuerelemente
    // die vom Programm benötigt werden.
    //************************************************
    #define IDM_DIALOG  100
    #define IDM_EXIT    101
    #define IDM_HELP    102
    
    #define IDD_BUTTON  200
    
    //************************************************
    //************************************************
    //************************************************
    
    //************************************************
    // file: MainWin.h
    //
    // Headerfile für unser Hauptfenster
    //************************************************
    #ifndef _CMAINWIN_H_
    #define _CMAINWIN_H_
    
    class CMainWin : public CFrameWnd
    {
    public:
        CMainWin ();
        afx_msg void OnDialog();
        afx_msg void OnExit();
        afx_msg void OnHelp();
    
        DECLARE_MESSAGE_MAP()
    };
    
    #endif
    
    //************************************************
    //************************************************
    //************************************************
    
    //************************************************
    // file: MainWin.cpp
    //
    // Implementierung des Hauptfensters
    //************************************************
    #include <afxwin.h>
    #include "SampleDialog.h"
    #include "MainWin.h"
    #include "resource.h"
    
    //************************************************
    // mm
    //************************************************
    BEGIN_MESSAGE_MAP(CMainWin,CFrameWnd)
        ON_COMMAND(IDM_DIALOG, OnDialog)
        ON_COMMAND(IDM_EXIT, OnExit)
        ON_COMMAND(IDM_HELP, OnHelp)
    END_MESSAGE_MAP()
    
    //************************************************
    // Der Konstruktor erstellt unser Hauptfenster
    // und lädt die Kurzwahltastentabelle
    //************************************************
    CMainWin::CMainWin()
    {
        Create(NULL,"Dialogbox Beispiel",WS_OVERLAPPEDWINDOW,rectDefault,NULL,"Dialog Menu");
    
        if(!LoadAccelTable("DialogMenu"))
             MessageBox("Kann Accelerator-Tabelle nicht laden");
    }
    
    //************************************************
    // Eventhandler wenn Dialog ausgewählt wurde.
    // Zeigt den Dialog an.
    //************************************************
    void CMainWin::OnDialog()
    {
        CSampleDialog dlg("Beispiel Dialog", this);
        dlg.DoModal();
    }
    
    //************************************************
    // Eventhandler wenn Beenden ausgewählt wurde.
    // Beendet das Programm
    //************************************************
    void CMainWin::OnExit()
    {
        switch(MessageBox("Programm beenden ?","Beenden",MB_YESNOCANCEL | MB_ICONQUESTION))
        {
        case IDYES: SendMessage(WM_CLOSE);
                    break;
        }
    }
    
    //************************************************
    // Eventhandler wenn Hilfe ausgewählt wurde.
    // Zeigt eine MessageBox an.
    //************************************************
    void CMainWin::OnHelp()
    {
        MessageBox("Dialog Beispiel");
    }
    
    //************************************************
    //************************************************
    //************************************************
    
    //************************************************
    // file: App.h
    //
    // Headerfile für unsere Applikation
    //************************************************
    #ifndef _CAPP_H_
    #define _CAPP_H_
    
    class CApp : public CWinApp
    {
    public:
        BOOL InitInstance();
    };
    
    #endif
    
    //************************************************
    //************************************************
    //************************************************
    
    // file: App.cpp
    #include <afxwin.h>
    #include "MainWin.h"
    #include "App.h"
    
    BOOL CApp::InitInstance()
    {
        m_pMainWnd = new CMainWin();
        m_pMainWnd->ShowWindow(m_nCmdShow);
        m_pMainWnd->UpdateWindow();
        return TRUE;
    }
    
    CApp TheApp;
    
    //************************************************
    // file: SampleDialog.h
    //
    // Headerfile für den Beispieldialog
    //************************************************
    #ifndef _CSAMPLEDIALOG_H_
    #define _CSAMPLEDIALOG_H_
    
    class CSampleDialog : public CDialog
    {
    public:
        CSampleDialog(CString strTitle, CWnd* pParent);
        afx_msg void OnButton();
        DECLARE_MESSAGE_MAP()
    };
    
    #endif
    
    //************************************************
    //************************************************
    //************************************************
    
    //************************************************
    // file: SampleDialog.cpp
    //
    // Implementierung des SampleDialogs
    //************************************************
    #include <afxwin.h>
    #include "resource.h"
    #include "SampleDialog.h"
    
    //************************************************
    // mm
    //************************************************
    BEGIN_MESSAGE_MAP(CSampleDialog,CDialog)
        ON_COMMAND(IDD_BUTTON,OnButton)
    END_MESSAGE_MAP()
    
    //************************************************
    // Standardkonstruktor
    //************************************************
    CSampleDialog::CSampleDialog(CString strTitle, CWnd* pParent) : CDialog(strTitle,pParent)
    {
    }
    
    //************************************************
    // Eventhandler, wenn Button gedrückt wurde.
    // Zeigt MessageBox an
    //************************************************
    void CSampleDialog::OnButton()
    {
        MessageBox("Button wurde gedrückt !");
    }
    
    //************************************************
    //************************************************
    //************************************************
    


  • An Ernsti:
    Das Programm hat einen Fehler. Irgendwas von wegen unerwartetes Dateiende in der RC-Datei oder so. Aber wie auch immer, das Programm benutzt als Rahmengerüst ebenfalls ein von CFrameWnd abgeleitetes Fenster. Ich brauche aber eins, das komplett nur mit Dialogfeldern arbeitet. Das Fenster, das beim Start aufgeht, soll von CDialog abgeleitet sein.

    An Ernsti und guenni81:
    Ist es nicht möglich, komplett auf Ressourcendateien (Dateien vom Typ RC) zu verzichten? Immerhin muß es ja auch möglich sein, die Dialogfeldeigenschaften (Größe, Position etc.) zur Laufzeit anhand von Funktionen zu ändern, also sollte es doch auch gehen, diese Eigenschaften am Anfang durch Funktionen zu setzen. Wenn ich mit Ressourcen arbeiten wollte, bräuchte ich ja bloß den Quellcode eines vom Assistenten generierten Projektes etwas abändern. Aber ich möchte, wenn möglich, komplett nur mit Header- und CPP-Dateien programmieren.

    Ich habe in der MSDN-Library erfahren, daß man einem Dialogfeld die Eigenschaften mit einem gewissen Template zuweisen kann und das ganze dann nochmal extra erstellt. Ich habe daraufhin die InitInstance-Funktion folgendermaßen umgeschrieben:

    BOOL CAnwendungApp::InitInstance ()
    {
    	CDialogDlg dlgDialog;
    	m_pMainWnd=&dlgDialog;
    
    	DLGTEMPLATE tmpl;
    
    	tmpl.style=DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU;
    	tmpl.dwExtendedStyle=0;
    	tmpl.x=200;
    	tmpl.y=150;
    	tmpl.cx=400;
    	tmpl.cy=300;
    	tmpl.cdit=3;
    
    	dlgDialog.InitModalIndirect (&tmpl);
    	dlgDialog.DoModal ();
    
    	return FALSE;
    }
    

    (Die Werte für tmpl.style hab ich aus einem automatisch generierten Projekt.)
    Das Problem ist jetzt: An der Stelle, wo InitModalIndirect aufgerufen wird, stürzt das Programm ab.

    Also, meine Fragen stehen weiterhin:
    1. Wer kennt ein gutes Tutorial zu MFC ohne Assistent und ohne RC-Dateien?
    2. Wer kann mir sagen, wie ich in meinem obigen Programm das Dialogfeld auf den Bildschirm bringe?



  • An Ernsti:
    Das Programm hat einen Fehler. Irgendwas von wegen unerwartetes Dateiende in der RC-Datei oder so. Aber wie auch immer, das Programm benutzt als Rahmengerüst ebenfalls ein von CFrameWnd abgeleitetes Fenster. Ich brauche aber eins, das komplett nur mit Dialogfeldern arbeitet. Das Fenster, das beim Start aufgeht, soll von CDialog abgeleitet sein.

    An Ernsti und guenni81:
    Ist es nicht möglich, komplett auf Ressourcendateien (Dateien vom Typ RC) zu verzichten? Immerhin muß es ja auch möglich sein, die Dialogfeldeigenschaften (Größe, Position etc.) zur Laufzeit anhand von Funktionen zu ändern, also sollte es doch auch gehen, diese Eigenschaften am Anfang durch Funktionen zu setzen. Wenn ich mit Ressourcen arbeiten wollte, bräuchte ich ja bloß den Quellcode eines vom Assistenten generierten Projektes etwas abändern. Aber ich möchte, wenn möglich, komplett nur mit Header- und CPP-Dateien programmieren.

    Ich habe in der MSDN-Library erfahren, daß man einem Dialogfeld die Eigenschaften mit einem gewissen Template zuweisen kann und das ganze dann nochmal extra erstellt. Ich habe daraufhin die InitInstance-Funktion folgendermaßen umgeschrieben:

    BOOL CAnwendungApp::InitInstance ()
    {
    	CDialogDlg dlgDialog;
    	m_pMainWnd=&dlgDialog;
    
    	DLGTEMPLATE tmpl;
    
    	tmpl.style=DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU;
    	tmpl.dwExtendedStyle=0;
    	tmpl.x=200;
    	tmpl.y=150;
    	tmpl.cx=400;
    	tmpl.cy=300;
    	tmpl.cdit=3;
    
    	dlgDialog.InitModalIndirect (&tmpl);
    	dlgDialog.DoModal ();
    
    	return FALSE;
    }
    

    (Die Werte für tmpl.style hab ich aus einem automatisch generierten Projekt.)
    Das Problem ist jetzt: An der Stelle, wo InitModalIndirect aufgerufen wird, stürzt das Programm ab.

    Also, meine Fragen stehen weiterhin:
    1. Wer kennt ein gutes Tutorial zu MFC ohne Assistent und ohne RC-Dateien?
    2. Wer kann mir sagen, wie ich in meinem obigen Programm das Dialogfeld auf den Bildschirm bringe?


Anmelden zum Antworten