Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?
-
Ich würde eher sagen, dass der Classname immer und überall verfügbar ist, sowohl bei selber registrierten Klassen als auch bei 3rd-Party-Klassen, die WndClass jedoch nicht. Gut, kann man sich natürlich über GetClassInfo/Ex besorgen, aber dafür braucht man eben auch - natürlich - den Classname.
-
@yahendrik sagte in Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?:
die WndClass jedoch nicht
Meinst Du mit WndClass den Rückgabewert von RegisterClass?
Edit: Nein, gemeint ist damit WNDCLASS. Lautet denn die Frage weshalb RegisterClass kein handle (So wie HWND bei CreateWindow) zurückgibt?
-
@titan99_ sagte in Warum wird eine WNDCLASS nicht mit ihren Namen,sondern mit einer Membervariable angesprochen?:
Nein, gemeint ist damit WNDCLASS. Lautet denn die Frage weshalb RegisterClass kein handle (So wie HWND bei CreateWindow) zurückgibt?
RegisterClass()
gibt einATOM
zurück, das Du genausogut anCreateWindow()
übergeben kannst. RTFM1).1) Read the fine MSDN!
-
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 beilpszClassName
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.
-
@hustbaer Also das struct
WNDCLASS
"beinhaltet" auch nochWNDPROC 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?
-
@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 beiRegisterClass
macht man es schließlich auch so. Es dürfte wahrscheinlich sogar ineffizienter sein, denn hier muss irgendwo ein Stringvergleich gemacht werden, während imWNDCLASS
-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()
mitCreateWindowEx()
.
-
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 gutwndclass.lpszClassName
oder der Rückgabewert vonRegisterClass()
anCreateWindow()
übergeben werden.
-
@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 eineWNDCLASS
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 tunEs gibt Frameworks wie MFC wo man C++ Klassen macht, für die das Framework dann intern eine
WNDCLASS
registriert.
-
@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).
- 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.