Windows -> Fenster in klasse erstellen
-
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
-
ci.
also brauche ich garkeine static wndproc mehr, wenn ich diesen Cast anwende??
das ist ja toll^^.
Cool.
-
hi, so jetzt gheht mir der hutt hoch, ich hab das in dissem forum schon mal erklärt wie es geht. mann diese asm bastellei schießt den voggel ab, die ist wahnwitzig.
du machst deine wndproc static na klar und machst in dein CreateWiddow den this pointer als parameter in LPARAM. da kannst du dann auf denn this pointer in deiner WndProc mit GetWindowLong oder wie die funkktion heißt, zugreifen.
-
ich programmier nicht mehr, sonst würde ich dirr den beispiel code schreiben, aber das kriggst du ja bestimmt jetzt auch allein hin
-
um reinbow zu unterstützen, eine WinProc hat in einer klasse nichts zu suchen, man kann sie reinnehmen, hat aber tatsächlich absolut keinen Sinn.
wenn man auf WM_CREATE verzichten kann, schreibt man per SetWindowLong(hwnd,GWL_USERDATA,(long)this) denn klassen Zeiger, in der WndProc ruft man diesen wieder ab und kann auf alle klassenmember zugreifen (public), die Basisklasse enthält eben Funktionen aka: OnPaint(..,..), OnCommand(..,..) bla bla, diese werden eben in dieser einzigen WndProc dann aufgerufen:
Basisklasse *klasse = (Basisklasse*)GetWindowLong(.....seine klamotten leitet man dann ab und Überschreibt die Funktionen
class FensterL : public Basisklasse {
..
..
};und macht dann halt seine Funktionen klar schief
FensterL::OnPaint(....
es gibt noch zicht andere, NORMALE, Möglichkeiten, ich selbst nutze eigen typedef´s für Funktionen, so schreib ich die wie ich und wo ich will und ordne es der entsprechenden Klasse zu, in der WndProc wird geprüft ob Funktion vorhanden, dann aufruf, so kann ich auch eine Funktion für mehrere Klassen verwenden, z.B. bei Buttons und kann darauf entsprechend einwirken.
Was ich sagen will, es gibt zicht saubere und workflow Freundliche Methoden, wo eben die WndProc nicht mit in der Klasse sitzt.
und der ASM Cast ist der schlag im Nacken, owei wer packt so was in die FAQ, mein aktuelles Projekt besitzt etwas über 1800 HANDLE´s und ziemlich komplizierte abläufe, wenn ich da das verwenden würde, dann gute nacht ^^