Windows -> Fenster in klasse erstellen



  • Hi @ All.

    Ich bin der Meinung, dass man Dialog für Dialog in einzelne Klassen auslagern sollte. Man sieht immer wieder im Netz tuts, wo das in der WinMain gemacht wird. Oft will man ja aber mehr als ein Dialogfeld haben. Deshalb halte ich das für übersichtlicher.

    nun habe ich erstmal versucht, die WindowClass zu registrieren, jedoch macht er mir dort schon probs.

    Header:

    #pragma once
    
    class CSkullWindow
    {
    public:
    	CSkullWindow(HINSTANCE hInst);
    	~CSkullWindow(void);
    	LRESULT CALLBACK WndProc(UINT Message, WPARAM wParam, LPARAM lParam);
    
    	HINSTANCE	hInstance;
    	HWND		hWnd;
    	WNDCLASSEX	wClass;
    };
    

    Class:

    #include <windows.h>
    #include "SkullWindow.h"
    
    CSkullWindow::CSkullWindow(HINSTANCE hInst)
    {
    	hInstance = hInst;
    	MSG msg;
    
    	wClass.cbSize			= sizeof(WNDCLASSEX);
    	wClass.style			= CS_HREDRAW | CS_VREDRAW;
    	wClass.lpfnWndProc		= CSkullWindow::WndProc;
    	wClass.cbClsExtra		= 0;
    	wClass.cbWndExtra		= 0;
    	wClass.hInstance		= hInstance;
    	wClass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
    	wClass.hCursor			= LoadCursor(NULL, IDC_ARROW);
    	wClass.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
    	wClass.lpszMenuName		= NULL;
    	wClass.lpszClassName	= "Skull Window";
    	wClass.hIconSm			= wClass.hIcon;
    
    	if (!RegisterClassEx(&wClass))
    	{
    		CSkullWindow::~CSkullWindow();
    	}
    }
    
    CSkullWindow::~CSkullWindow(void)
    {
    }
    
    LRESULT CALLBACK CSkullWindow::WndProc(UINT Message, WPARAM wParam, LPARAM lParam)
    {
    	switch (Message)
    	{
    	case WM_CREATE:
    		return 0;
    	case WM_PAINT:
    		return 0;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	default:
    		return DefWindowProc(hWnd,Message,wParam,lParam);
    	}
    }
    

    Danke leute! ich weiß wirklich nicht, woran das liegen könnte.
    achja, ich hab das hWnd bei der WinProc weggelassen, aber ich hab das doch schon global in der klasse, oder ist das falsch???

    danke.



  • ich sehe gar keinen aufruf von createwindow() ^^
    und ich glaube die WndProc() muss static sein.



  • nein, also create window mache ich später. ich wollte das mal testen und das geht nicht. aber wie mache ich das static? und habe ich dann noch Zugriff auf klassenmenber? denn darum geht's ja!

    danke.



  • Script-Styler schrieb:

    nein, also create window mache ich später. ich wollte das mal testen und das geht nicht. aber wie mache ich das static?

    Mit

    static
    

    du Troll?!
    Und wie wäre es wenn du mal die Forensuche benutzt, das Thema gabs schon 300 mal...



  • yo. habe ich getan.

    ich habe nun eine static und eine dynamische WndProc.

    aber nun weiß ich nicht weiter - der Zusammenhang ... lpCreateParams in der static WndProc und so weiter...

    könnte jemand mir bitte sagen, was an diesem Code falsch ist???

    vielen dank schon mal im Vorraus..:)

    #pragma once
    
    class CSkullWindow
    {
    public:
    	CSkullWindow(HINSTANCE hInst);
    	~CSkullWindow(void);
    
    	// The default window procedure with access to all class variables
    	LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
    
    	// The static window procedure will call the not-static one
    	static LRESULT CALLBACK WndProcStatic(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
    
    	HINSTANCE	hInstance;
    	HWND		hWnd;
    	WNDCLASSEX	wClass;
    };
    // -------------------------------------------------------------- //
    #include <windows.h>
    #include "SkullWindow.h"
    
    CSkullWindow::CSkullWindow(HINSTANCE hInst)
    {
    	hInstance = hInst;
    	MSG msg;
    
    	FillMemory (&wClass,sizeof(WNDCLASSEX),0);
    	wClass.cbSize			= sizeof(WNDCLASSEX);
    	wClass.style			= CS_HREDRAW | CS_VREDRAW;
    	wClass.lpfnWndProc		= WndProc;
    	wClass.cbClsExtra		= 0;
    	wClass.cbWndExtra		= 0;
    	wClass.hInstance		= hInstance;
    	wClass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
    	wClass.hCursor			= LoadCursor(NULL, IDC_ARROW);
    	wClass.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
    	wClass.lpszMenuName		= NULL;
    	wClass.lpszClassName	= "Skull Window";
    	wClass.hIconSm			= wClass.hIcon;
    
    	if (!RegisterClassEx(&wClass))
    	{
    		CSkullWindow::~CSkullWindow();
    	}
    }
    
    CSkullWindow::~CSkullWindow(void)
    {
    }
    
    LRESULT CALLBACK CSkullWindow::WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    	switch (Message)
    	{
    	case WM_CREATE:
    		return 0;
    	case WM_PAINT:
    		return 0;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	default:
    		return DefWindowProc(hWnd,Message,wParam,lParam);
    	}
    }
    
    LRESULT CALLBACK CSkullWindow::WndProcStatic(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    	if (Message == WM_CREATE)
    	{
    		SetWindowLong(hwnd,GWL_USERDATA,(LONG)((LPCREATESTRUCT)lParam) -> lpCreateParams);
    	}
    	CSkullWindow *pThis = (CSkullWindow *) GetWindowLong(hwnd,GWL_USERDATA);
    
    	if (pThis == 0)
    	{
    		return DefWindowProc(hwnd,Message,wParam,lParam);
    	}
    	else
    	{
    		return pThis -> WndProc(hwnd,Message,wParam,lParam);
    	}
    }
    

    THX THX!



  • könnte jemand mir bitte sagen, was an diesem Code falsch ist???

    nur wenn du mir sagst, welche fehlermeldungen kommen, oder was falsch läuft 🙂



  • ChrisJ schrieb:

    könnte jemand mir bitte sagen, was an diesem Code falsch ist???

    nur wenn du mir sagst, welche fehlermeldungen kommen, oder was falsch läuft 🙂

    yo, kann ich gerne tun!

    Output schrieb:

    ------ Erstellen gestartet: Projekt: SkullPop, Konfiguration: Debug Win32 ------
    Kompilieren...
    SkullWindow.cpp
    .\SkullWindow.cpp(12) : error C3867: "CSkullWindow::WndProc": Dem Funktionsaufruf fehlt die Argumentliste. Verwenden Sie "&CSkullWindow::WndProc", um einen Zeiger auf den Member zu erstellen.
    .\SkullWindow.cpp(12) : error C2440: '=': 'LRESULT (__stdcall CSkullWindow::* )(HWND,UINT,WPARAM,LPARAM)' kann nicht in 'WNDPROC' konvertiert werden
    Es gibt keinen Kontext, in dem diese Konvertierung möglich ist
    Main.cpp
    Code wird generiert...
    Das Buildprotokoll wurde unter "file://g:\C++\Projects\SkullPop\Debug\BuildLog.htm" gespeichert.
    SkullPop - 2 Fehler, 0 Warnung(en)
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========



  • ...
    // wClass.lpfnWndProc = WndProc; 
     wClass.lpfnWndProc = WndProcStatic; 
    ...
    

    🙂



  • verdammt!...



  • cool.
    aber irgendwie will die Message nicht von WndProcStatic nach WndProc überspringen.
    irgendwie hab ich was falsch gemacht.

    #include <windows.h>
    #include "SkullWindow.h"
    
    CSkullWindow::CSkullWindow(HINSTANCE hInst)
    {
    	hInstance = hInst;
    	MSG msg;
    
    	FillMemory (&wClass,sizeof(WNDCLASSEX),0);
    	wClass.cbSize			= sizeof(WNDCLASSEX);
    	wClass.style			= CS_HREDRAW | CS_VREDRAW;
    	wClass.lpfnWndProc		= WndProcStatic;
    	wClass.cbClsExtra		= 0;
    	wClass.cbWndExtra		= 0;
    	wClass.hInstance		= hInstance;
    	wClass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
    	wClass.hCursor			= LoadCursor(NULL, IDC_ARROW);
    	wClass.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
    	wClass.lpszMenuName		= NULL;
    	wClass.lpszClassName	= "Skull Window";
    	wClass.hIconSm			= wClass.hIcon;
    
    	if (!RegisterClassEx(&wClass))
    	{
    		CSkullWindow::~CSkullWindow();
    	}
    
    	hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
    			"Skull Window",
    			"Skull Window",
    			WS_OVERLAPPEDWINDOW,
    			CW_USEDEFAULT,
    			CW_USEDEFAULT,
    			CW_USEDEFAULT,
    			CW_USEDEFAULT,
    			NULL,
    			NULL,
    			hInstance,
    			NULL);
    
    	ShowWindow(hWnd,1);
    	UpdateWindow(hWnd);
    
    	while (GetMessage(&msg,NULL,0,0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    }
    
    CSkullWindow::~CSkullWindow(void)
    {
    }
    
    LRESULT CALLBACK CSkullWindow::WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    	switch (Message)
    	{
    	case WM_CREATE:
    		return 0;
    	case WM_PAINT:
    		return 0;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	default:
    		return DefWindowProc(hWnd,Message,wParam,lParam);
    	}
    }
    
    LRESULT CALLBACK CSkullWindow::WndProcStatic(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    	if (Message == WM_CREATE)
    	{
    		SetWindowLong(hwnd,GWL_USERDATA,(LONG)((LPCREATESTRUCT)lParam) -> lpCreateParams);
    	}
    	CSkullWindow *pThis = (CSkullWindow *) GetWindowLong(hwnd,GWL_USERDATA);
    
    	if (pThis == 0)
    	{
    		return DefWindowProc(hwnd,Message,wParam,lParam);
    	}
    	else
    	{
    		return pThis -> WndProc(hwnd,Message,wParam,lParam);
    	}
    }
    

    danke helft mir!



  • Einmal ein Copy & Paste - Hinweis :

    ...
      CW_USEDEFAULT, 
      NULL, 
      NULL, 
      hInstance, 
    //  NULL); 
      this); 
    ...
    

    Überleg danach mal, ob es eine der Guten Ideen ist, wenn sich die GetMessage-Schleife im Konstruktor befindet.
    🙂



  • danke!

    ich glaube nich gute idee.
    aber wie soll ich das denn machen???
    danke.



  • if (!RegisterClassEx(&wClass))
        {
            CSkullWindow::~CSkullWindow();
        }
    

    Was soll das denn werden 🙄 ?





  • Zitat aus dem FAQ-Artikel. Der Cast des Jahres :

    LRESULT CALLBACK BaseWindow::WndProc(UINT message,WPARAM w,LPARAM l) 
    {
    ...
    }
    
    BaseWindow::BaseWindow(char* ApplicationName,HINSTANCE hInst) 
    {
    ...
     long (__stdcall *f2)             (HWND,UINT,WPARAM,LPARAM); 
     long (__stdcall BaseWindow:: *f1)(UINT,WPARAM,LPARAM); 
    ...
     f1 = WndProc; 
     __asm{ 
        mov eax,f1; 
        mov f2,eax 
     } 
    ...
     wndclass.lpfnWndProc = f2; 
     wndclass.style       = CS_VREDRAW|CS_HREDRAW; 
    ...
    }
    

    😞



  • lool, das ist ja angsteinflößend 😃 ...glaub das sollte man mal überarbeiten... .



  • was soll denn der "cast des Jahre" denn bewirken???
    etwa eine Winproc zu static machen???

    danke.



  • Der "Cast des Jahres" gehört zur "Robinson-Klasse". Der bewirkt nur, dass Du mögliche Programmfehler alleine suchen musst.
    🙂



  • man o metter solche threats gibts wohl jedes jahr oder wie?????ich weiss noch gleiche threat gabbs damals schon wo webfritzi noch hier war und es war lange diskussion, such doch einnfach mal mensch.



  • Nein nicht suchen, ich kann nicht mehr vor lachen, bitte bitte weitermachen, ich schrei mich hier weg ohne ende 😃 😃 😃

    Aber um mal dein C++ auf zu frischen, jeder Memberfunktion einer Klasse wird zu erst der Klassenzeiger mit gegeben (this), somit lautet eben deine Proc:
    (this, HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    aber windows ruft eben die Proc auf und erwartet da halt nur:
    (HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)

    du verstehen 😉


Log in to reply