Globale Klassen verhindern - wie?
-
Hallihallo,
ich erinnere mich, dass mir gesagt wurde man solle globale Klassen und Variablen möglichst vermeiden. Ich will dies gern tun, nur komme ich nicht dahinter.
Problem: (Pseudo)
#include <windows.h> #include "klasse.h" klasse instanz; LRESULT CALLBACK WndMain(blabla) { instanz.var += 1; // ... return DefWindowProc(blabla); } int WINAPI WinMain(blabla) { instanz.var = 0; HWND hWnd = CreateWindow(WndMain); if (instanz.var) MessageBox("instanz.var == 1"); return 0; }
Natürlich alles extrem abgekürzt, aber ich denke das Problem ist klar.
Ganz einfache Frage:
Wie funktioniert dieses Beispiel ohne eine globale Instanz von klasse? (Antwort gern wieder als Pseudo-Code)Danke.
lg Max
-
Suchfunktion / FAQ
-
#include <windows.h> #include "klasse.h" klasse instanz; LRESULT CALLBACK WndMain(blabla) { if(CREATE) instanzzeiger = (CREATESTRUCT)lParam->lpCreateParams instanzzeiger->var = 1 // ... return DefWindowProc(blabla); } int WINAPI WinMain(blabla) { instanz.var = 0; HWND hWnd = CreateWindow(WndMain, instanz); if (instanz.var) MessageBox("instanz.var == 1"); return 0; }
-
Hm okay, d.h. dann aber, dass Zeile 4 (klasse instanz;) dann in WinMain() ganz nach oben kommt, richtig?
lg Max
-
ja
-
OK, nette Sache das, aber funktioniert das auch mit mehreren Klassen?
Wenn ja, wie?
lg Max
-
Mach halt einen Singleton aus der Klasse.
MfG
-
Und was soll das bringen?
ALLES irgendwie in Klassen quetschen, auch wenn das Problem und die Struktur garnicht dafür geignet ist?
Das ist irgendwie zur Unsitte geworden in letzter Zeit.
-
Hmm... also irgendwie blick ich das noch nicht mit dem CREATESTRUCT.
#include <windows.h> #include "klasse.h" void RegisterMainClass(HINSTANCE hInstance,WNDPROC WndProc); // Register "MAIN" LRESULT CALLBACK WndMain(HWND hWNd,UINT msg,WPARAM wParam,LPARAM lParam) { static klasse* instanz = 0; if (instanz == 0) instanz = ((LPCREATESTRUCT)lParam)->lpCreateParams; if (msg == WM_CREATE) instanz->var += 1; // ... return false; } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { RegisterMainClass(hInstance,WndMain); // Register "MAIN" klasse instanz; instanz.var = 0; LPVOID lpParam = &instanz; HWND hWnd = CreateWindow("MAIN","Test",WS_OVERLAPPEDWINDOW,0,0,0,0,NULL,NULL,hInstance,lpParam); if (instanz.var) MessageBox(NULL,"Jippiee","Keine globale Klasse mehr!",MB_OK); }
Meine Jippiee-Box kann ich leider noch nicht sehen ...
Was ist da falsch?
lg Max
-
Einfach alles. Wie wärs wenn du mal die Suchfunktion bemühst, du Depp? Die liefert für LPCREATESTRUCT ganz hervorragende Ergebnisse
-
Schön schön, ich finde über all ((LPCREATESTRUCT)lParam)->hInstance, aber niemanden der mit dem lpParam einen Zeiger überträgt.
Vielleicht bin grad zu blöd, dann gib mir bitte einen der Einträge die Du meinst.
lg Max
-
Oh man, lern programmieren. Bin ich hier im Kindergarten gelandet, oder wie? Das ist so fundamental, da...ach was reg ich mich überhaupt noch auf. Ich hab schon lange resigniert, das Niveau hier ist unterirdisch.
So, hier:
static klasse *instanz; if(WM_CREATE == msg) { instanz = ((LPCREATESTRUCT)lParam)->lpCreateParams; instanz->var += 1; }
-
Okay, ich hätte darauf achten sollen, dass das Ganze mit der WM_CREATE-Nachricht gesendet wird.
Was das Nicht-Kennen dieser Eigenarart damit zu tun haben soll, dass man des Programmierens nicht fähig ist, ist mir allerdings schleierhaft.Ein Problem bleibt allerdings:
Beim Subclassing erhält AFAIK die ausführende WNDPROC keine WM_CREATE-Nachricht mehr, d.h. (klasse*)LPCREATESTRUCT(lParam)->lpCreateParams wird nie mein kleines Zeigerlein sein und es kommt zu Heap-Fehlern.
Was mach ich nun?
WM_CREATE mit SendMessage() nachträglich drüberbügeln?
Scheint mir rustikal...lg Max
-
MaDsTyLe schrieb:
Beim Subclassing erhält AFAIK die ausführende WNDPROC keine WM_CREATE-Nachricht mehr, d.h. (klasse*)LPCREATESTRUCT(lParam)->lpCreateParams wird nie mein kleines Zeigerlein sein und es kommt zu Heap-Fehlern.
WM_CREATE wird nur bei der Erstellung eines Fensters verschickt. Subclassing ist nur für existierende Fenstern möglich, daher kann eine Subclassing-Fensterprozedur nie eine WM_CREATE zugeschickt bekommen.
MaDsTyLe schrieb:
WM_CREATE mit SendMessage() nachträglich drüberbügeln?
Scheint mir rustikal...Vergiss das am besten ganz schnell wieder.
-
Das geht doch mit GetWindowLong/SetWindowLong, sodass man mehrere instanzen habe kann oder?
-
Jap, so hab ich das Subclassing ja realisiert.
Nur wie schaff ich jetzt meinen Zeiger in meine Subclassing-WNDPROC?
Wenn das noch klappt, ist alles Wölkchen.
lg Max
-
Muss jetzt keine optimale Lösung sein, aber schau dir mal "SetProp" an.
-
Brauchst du Gläser?
grgrerr schrieb:
Das geht mit GetWindowLong/SetWindowLong
-
So habs jetzt gepeilt
Danke grgrerr, wusste nicht, dass man mit SetWondowLong() auch per GWL_USERDATA die lpCreateParams vom LPCREATESTRUCT übergeben kann. Dachte SetWindowLong() wäre nur zum Subclassen.
@Dipl.Inf.Student:
Auch Dir Danke, Du hast auch geholfen, aber bitte fang endlich an Deine Mitmenschen mal etwas freundlicher zu behandeln. Im Moment schadest Du Dir nur selber.
Toleranz ist das A und O, erst recht in Deutschland wo sie so lange fehlte.
Was ich hier mache ist nur der Versuch Dir zu helfen, weil Du offensichtlich bedürftig bist.Liebe Grüße, Max
-
Was ich nicht leiden kann, sind unregistrierte Dipl.Inf.Studenten., die meinen, alles, was nicht ihren Wissensstand hat, ist einer höflichen
Behandlung nicht wert und die Nettikette gelten für sie nicht.