Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?



  • Versteht überhaupt irgendwer die Frage? Bin mir nämlich nicht sicher ob ich sie verstehe. Schliesslich ist der normale Name der WNDCLASS das was man bei lpszClassName angegeben hat - mir wäre sonst auch kein weiterer Name bekannt.

    Ich glaube fast es ist gemeint warum man bei CreateWindow nicht den Identifier der C++ Klasse angeben kann die man irgendwo für irgend ein Fenstergedöns schreibt. Und das liegt einerseits daran dass die WinAPI nichts von C++ weiss. Und selbst wenn ginge es nicht, da C++ nicht die nötigen Reflection-Fähigkeiten hat.

    Oder vielleicht ist der Bezeichner gemeint den man für die WNDCLASS Variable verwendet. In dem Fall ist die Antwort allerdings die selbe.


  • Gesperrt

    @hustbaer Also das struct WNDCLASS "beinhaltet" auch noch WNDPROC lpfnWndProc. Dazu kommt dann glaube ich häufig die Frage, wie man einen function pointer to member function (Funktionpointer für Memberfunction) übergeben kann.

    Und als Antwort häufig, dass CreateWindow LPVOID lpParam "beinhaltet", wo z.B. this übergeben werden kann, usw.



  • @titan99_ Und wo "beinhaltet" das jetzt einen Zusammenhang mit dem was ich geschrieben habe?



  • @hustbaer Der Beitrag "beinhaltet" doch auch Text? 😕


  • Mod

    @Thorsten54 sagte in Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?:

    lpszClassName

    Also ich habe das so verstanden, warum man statt

        WNDCLASS wc = { };
    
        wc.lpfnWndProc   = WindowProc;
        wc.hInstance     = hInstance;
        wc.lpszClassName = "Mein_toller_Fenstername";
    
        RegisterClass(&wc);
    
        HWND hwnd = CreateWindow(wc.lpszClassName , ...)   // Oder direkt "Mein_toller_Fenstername"
    

    nicht

        WNDCLASS wc = { };
    
        wc.lpfnWndProc   = WindowProc;
        wc.hInstance     = hInstance;
        wc.lpszClassName = "Mein_toller_Fenstername";
    
        RegisterClass(&wc);
    
        HWND hwnd = CreateWindow(wc, ...)   // oder &wc 
    

    schreiben kann.

    Und da gibt es eigentlich keinen ersichtlichen, guten Grund, wieso das nicht so ist. Mit C++-Klassen hat das C-Struct WNDCLASS nichts zu tun, und bei RegisterClass macht man es schließlich auch so. Es dürfte wahrscheinlich sogar ineffizienter sein, denn hier muss irgendwo ein Stringvergleich gemacht werden, während im WNDCLASS-Objekt ein effizienterer interner Identifier stecken könnte.



  • @SeppJ sagte in Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?:

    CreateWindow

    Tu bitte den ersten Parameter da weg, du verwechselst CreateWindow() mit CreateWindowEx().



  • also das musterprogramm aus dem petzold sieht so aus:

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    	static TCHAR szAppName[] = TEXT("Aufgäbe 1"); //Name der Anwendung
    	HWND hwnd; //Handle aufs Fenster
    	MSG msg; //MSG Struktur
    	WNDCLASS wndclass; //Window Class Struktur, enthält die Window Class Attribute, die mit RegisterClass() registriert werden. Wurde durch WNDCLASSEX ersetzt und ist daher eigentlich veraltet.
    
    	wndclass.style = CS_HREDRAW | CS_VREDRAW; //Window Class Styles
    	wndclass.lpfnWndProc = WndProc; //Pointer auf die "Window-Prock"
    	wndclass.cbClsExtra = 0; //Anzahl der Extra-Bytes, die auf die Window Class folgend alloziiert werden sollen.
    	wndclass.cbWndExtra = 0; //Anzahl der Extra-Bytes, die auf die Window Instance folgend alloziiert werden sollen.
    	wndclass.hInstance = hInstance; //Handle auf die Instanz, die die Window-Prozedur für diese Window Class enthält.
    	wndclass.hIcon = LoadIcon(0, IDI_APPLICATION); //Handle auf das Class Icon, das in der Titelleiste und in der Taskleiste angezeigt werden soll
    	wndclass.hCursor = LoadCursor(0, IDC_HAND); //Handle auf den Cursor, aufgrund persönlicher Vorlieben des Programmierers ein Hand-Symbol 
    	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //Handle auf den Background Brush. Sorgt in diesem Fall für einen weißen Hintergrund.
    	wndclass.lpszMenuName = 0; //Festlegung eines Menüs. Hier kein Menü, daher 0
    	wndclass.lpszClassName = szAppName; //Name der Fensterklasse
    
    
    
    	if (!RegisterClass(&wndclass)) //Registriert die Window Class für nachfolgende Aufrufe von CreateWindow. Wurde durch RegisterClassEx ersetzt und ist daher eigentlich veraltet.
    	{
    		MessageBox(0, TEXT("Fehler!"), szAppName, MB_ICONERROR); //Gibt eine Nachricht aus, falls der Aufruf von RegisterClass() fehlschlagen sollte
    		return 0;
    	}
    
    	hwnd = CreateWindow(szAppName, TEXT("Aufgabe 1"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, 0); //Erstellt das Fenster. Wurde durch CreateWindowEx ersetzt und ist daher eigentlich veraltet. Sendet WM_CREATE an die Window-Prock
    
    	ShowWindow(hwnd, iCmdShow); //Setzt den spezifizierten Anzeigestatus des Fensters
    	UpdateWindow(hwnd); //Aktualisiert die "client area" des Fensters, indem es eine WM_PAINT-Nachricht sendet.
    
    	while (GetMessage(&msg, 0, 0, 0)) //Ruft die nächste Nachricht ab
    	{
    		TranslateMessage(&msg); //Nachrichten, die von der Tastatur erzeugt wurden, umwandeln
    		DispatchMessage(&msg); //Nachrichten an die Window-Prock senden bzw. die Window-Prock aufrufen
    	}
    
    	return msg.wParam;
    }
    

    da wird gar keine wndclass oder bestandteile davon übergeben.



  • @Wade1234 sagte in Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?:

    da wird gar keine wndclass oder bestandteile davon übergeben.

    Statt szAppName könnte genauso gut wndclass.lpszClassName oder der Rückgabewert von RegisterClass() an CreateWindow() übergeben werden.


  • Gesperrt

    @Thorsten54 sagte in Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?:

    ich frage mich warum eine WNDCLASS nicht einfach so über ihren "normalen" Namen, sondern mit ihrer Membervariable "lpszClassName" an zum Beispiel CreatWindow() übergeben wird.

    WNDCLASS bezeichnet den Typ eines Objekts. Einzelnen Instanzen davon kann man einen menschenlesbaren Namen "lpszClassName" geben. Anhand dieses Namens ist ein konkretes WNDCLASS-Objekt eindeutig identifizierbar.



  • An- und Pfirsich sollte die Frage (wie auch immer sie sein möge) inzwischen erschöpfend beantwortet sein.



  • @SeppJ sagte in Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?:

    @Thorsten54 sagte in Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?:

    lpszClassName

    Also ich habe das so verstanden, warum man statt
    ...
    schreiben kann.

    Aaah, ja, auf die Idee wäre ich nicht gekommen. Ja, das kann sein.

    Und da gibt es eigentlich keinen ersichtlichen, guten Grund, wieso das nicht so ist.

    Naja, doch, nämlich den dass es keinen Sinn macht die Klasse erst zu registrieren und dann beim CreateWindow erst wieder alle Daten mitzugeben. Und eine WNDCLASS struct als Parameter zu nehmen wo die Funktion sich dann aber nur den Class-Name anguckt wäre finde ich auch ziemlich unsinnig und verwirrend.

    Mit C++-Klassen hat das C-Struct WNDCLASS nichts zu tun

    Es gibt Frameworks wie MFC wo man C++ Klassen macht, für die das Framework dann intern eine WNDCLASS registriert.


  • Gesperrt

    @Swordfish sagte in Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?:

    RegisterClass() gibt ein ATOM zurück, das Du genausogut an CreateWindow() übergeben kannst. RTFM1).

    1. Read the fine MSDN!

    Direkt lässt sich das Atom nicht übergeben, es braucht dazu das Makro MAKEINTATOM.

    Zudem muss scheinbar trotzdem ein Bezeichner ausgedacht werden, da es mit nullptr scheinbar zu wenig funktioniert.

    Edit 1: So gut scheint msdn dazu nicht zu sein, da MAKEINTATOM bei RegisterClass unerwähnt bleibt.



  • @titan99_ sagte in Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?:

    Direkt lässt sich das Atom nicht übergeben, es braucht dazu das Makro MAKEINTATOM.

    Einfach casten.



  • @titan99_ sagte in Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?:

    Edit 1: So gut scheint msdn dazu nicht zu sein, da MAKEINTATOM bei RegisterClass unerwähnt bleibt.

    Wiso sollte das in der Hilfe bei RegisterClass stehen? Da wird es doch nicht benötigt.
    Wenn du den return value von RegisterClass an CreateWindow übergeben möchtest wird dieses Makro wohl benötigt. Und dann sollte es eher in der Hilfe zu CreateWindow stehen.


Anmelden zum Antworten