Funktionszeigerübergabe in Klasse



  • Hiho.

    Ich include zwar die <windows.h>, aber denke dennoch, dass es sich hier nicht um ein WinAPI, sondern vielmehr um ein allgemeines C++ Problem handelt, da es im Grunde genommen Funktionszeiger betrifft.

    Ich versuche in einer Klasse durch eine klasseneigene Methode die Referenz einer Funktion aus dem Hauptprogramm zu speichern.

    Später möchte ich mit der gespeicherten Funktion in der Klasse wie mit einer normalen weiterarbeiten könnnen.

    Ich hatte mal folgenden Ansatz versucht:

    #include <windows.h>
    
    class Klasse
    {
    	private:
    		BOOL CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
    
    	public:
    		Klasse();
    		~Klasse();
    
    		void setWndProc( BOOL CALLBACK ( HWND, UINT, WPARAM, LPARAM ) );
    };
    
    void Klasse::setWndProc( BOOL CALLBACK newWndProc( HWND, UINT, WPARAM, LPARAM ) )
    {
    	WndProc = newWndProc;
    };
    
    BOOL CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
    {
    	return false;
    };
    
    int main( void )
    {
    	Klasse MeineKlasse;
    
    	MeineKlasse.setWndProc( WindowProc );
    
    	return 0;
    };
    

    Leider bekomme ich anschließend folgende Fehlermeldung:

    Fehler 1 error C2659: "=": Funktion als linker Operand.

    Was ist zu tun?

    Gruß, paSe



  • private:
            BOOL CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
    

    ist kein Funktionszeiger, sondern eine Funktionsdeklaration.



  • Und Funktionszeiger sind mehr C als C++

    In c++ kann man das eleganter loesen: Nen Interface zum aufrufen der funktion mit den Parametern, dann genau so viele Spezialisierte Klassen wie man unterschiedliche Funktionen hat, die den aufruf genau an die funktion weiterleiten.
    Und das Austauschen der funktionalitaet dann dadurch realiseren, das man dem zeiger auf die Basisklasse unterschiedliche Implementationen unterschiebt.
    (Polymorphie !).
    Iss zwar ne Menge mehr schreibarbeit, wird sich im Laufzeitverhalten nur unmerklich auswirken, iss aber um welten flexibler und übersichtlicher/wartbarer ....

    Ciao ...



  • Tachyon schrieb:

    private:
            BOOL CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
    

    ist kein Funktionszeiger, sondern eine Funktionsdeklaration.

    Da hast du wohl recht.

    Danke für den kleinen Denkanstoß ...

    habe mir jetzt mal die WNDCLASS Struktur genauer angesehen, schließlich wird dort hinein die WndProc referenziert.

    Undzwar nach WNDPROC lpfnWndProc.

    Habe jetzt folgendes probiert:

    #include <windows.h> 
    
    class Klasse 
    { 
        private: 
            WNDPROC WndProc; 
    
        public: 
            Klasse(); 
            ~Klasse(); 
    
            void setWndProc( WNDPROC ); 
    }; 
    
    void Klasse::setWndProc( WNDPROC newWndProc ) 
    { 
        WndProc = newWndProc; 
    }; 
    
    BOOL CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) 
    { 
        return false; 
    }; 
    
    int main( void ) 
    { 
        Klasse MeineKlasse; 
    
        MeineKlasse.setWndProc( WindowProc ); 
    
        return 0; 
    };
    

    Läuft leider auch nicht. 😞

    EDIT:

    OK, habs hinbekommen.

    WNDPROC bezieht sich auf LRESULT CALLBACK für normale Windows.

    Für BOOL CALLBACK, also Dialogs benötigt man DLGPROC.

    Also ...

    #include <windows.h>
    
    class Klasse 
    { 
        private: 
    		DLGPROC DlgProc;
    
        public: 
            void setWndProc( DLGPROC );
    }; 
    
    void Klasse::setWndProc( DLGPROC newDlgProc ) 
    { 
        DlgProc = newDlgProc; 
    };
    
    BOOL CALLBACK DialogProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) 
    { 
        return false;
    }; 
    
    int main( void ) 
    { 
        Klasse MeineKlasse; 
    
        MeineKlasse.setWndProc( DialogProc );
    
        return 0; 
    };
    

    Danke für die Unterstützung.

    Ach und by the way...

    Klasse();
    ~Klasse();
    

    ohne Definition verursachen Linkerfehler.
    Nur, damit sich hier keiner beschwert. 😛

    Gruß, paSe


Anmelden zum Antworten