Verhindern von Globalen Variablen.
-
Hi Leute,
ich hab folgendes Problem:
Ich erzeuge ein Fenster und Zeichne in dem Fenster etwas das Abhängig von den
Variablen x_1, x_2, ... usw. ist.
Diese Variablen sind global und werden von außen über die Funktion setValue gesetzt.
Wie kriege ich die Variablen "lokal", so dass es immer noch funktioniert?Wenn ich nähmlich in einem Framework das Programm mehrmals aufrufe und jeweils andere Werte übergebe, dann zeigt er trotzdem in jeder Instanz des Programms dasselbe an, als ob ich jeder Instanz die selben Werte gegeben hätte, hab ich aber nicht.
Hat jemand ne Idee?
Hier etwas code
int x_1, x_2 ...; setValue(int x, ...) { x_1 = x; ... } StartWinMain() { ... } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { ... }
-
Der Code ist wenig hilfreich.
Grundsätzlich: Variablen, die Du in einer Funktion berechnen willst, muß Du an die Funktion übergeben. Damit sind sie aber nicht "private". Es sein denn, sie sind global (außerhalb von WinMain) definiert, dann hast Du immer darauf Zugriff.Lokale Variablen kannst Du in der Funktion selbst Definieren, hast aber von außerhalb keinen Zugriff. Wenn ein lokale Variable definierst, die denselben Namen hat wie eine andere globale, wird immer die lokale berechnet, die globale Variable bleibt unverändert.
-
Hi Elektronix!
Ich mein natürlich lokal und nicht privat, Schreibfehler.
Mein Problem ist ja, ich will lokale Varibalen haben in der WinProc-Funktion, diese aber mit setValue() von außen verändern können.
In einer Klasse kann man ja mit set- und getValue-Methoden auch private Variablen ändern. Hier in meinem Fall weiß ich nur nicht wie es geht oder ob überhaupt.
Winz!
-
Was meinst Du denn mit "von außen"?
Wie gesagt: lokale Variablen kann man außerhalb der lokalen Funktion nicht ändern. Die Variablen werden mit der Rückkehr der Funktion ins Hauptprogramm ungültig. Wenn Du eine Funktion schreibst und ihr Daten für eine Variable übergibst, die erst in der Funktion definiert wird, erhälst Du einen Fehler.
-
Das ist mir schon alles klar.
Vielleicht hab ich mein Problem auch nur blöd beschrieben, ist halt nicht ganz trivial.Aber ich versuchs nochmal so:
Ich möchte dieses Programm mehrmals gleichzeitig ausführen. (Funktioniert auch)
Ich setzt mit der Funktion setValue() von außen die Variablen x_1, usw.
(Funktioniert auch)
In der WndProc-Funktion male ich in Abhängigkeit der Variablen x_1, usw. etwas.
(Funktioniert auch)Da die Variablen x_1, usw. global sind, sind für jede Instanz, die ich von dem Programm erzeugt habe, die Variablen x_1, usw. gleich. Ich kann also nicht jeder Instanz unterschiedlich Werte übergeben.
Kann man das verhindern? Oder muß ich mir was komplett anderes einfallen lassen?
MfG,
Winz!
-
Du kannst in WinMain mit wndclass.cbWndExtra einen Speicherblock reservieren, der nur für dieses eine Fenster bzw. diese WinMain gilt. Darin kannst Du die Variable ablegen (SetWindowLong). Die ist dann nicht mehr global.
-
Elektronix schrieb:
Du kannst in WinMain mit wndclass.cbWndExtra einen Speicherblock reservieren, der nur für dieses eine Fenster bzw. diese WinMain gilt. Darin kannst Du die Variable ablegen (SetWindowLong). Die ist dann nicht mehr global.
Nop, ...wndclass.cbWndExtra und SetWindowLong sind 2 paar Schuhe
.Machs so:
struct SGlobalData { int iX1Value; int iX2Value; // ... } int WINAPI WinMain(...) { // ... HWND hWndMain = CreateWindowEx(...); SGlobalData gdData; gdData.iX1Value = ...; gdData.iX2Value = ...; SetWndowLongPtr(hWndMain, GWL_USERDATA, reinterpret_cast<LONG_PTR>(&gdData)); // ... } // ... LRESULT CALLBACK WndProc(...) { static SGlobalData* pData; switch(uiMessage) { case WM_CREATE: pData = reinterpret_cast<SGlobalData*>(GetWindowLongPtr(hWnd, GWL_USERDATA)); break; // ... } }EDIT: @ Elektronix: Jojo, war nicht ansatzweise böse gemeint oder so
.
-
Hmm, ich meine, mich zu erinnern- muß noch mal genauer nachschauen.
Nix für ungut...
-
http://www.win-api.de/tutorials.php?tutid=13
In diesem Tutorial wird für ein Child-Fenster in cbWndExtra ein Speicherblock (2 * sizeof(int)) reserviert und dann mit SetWindowLong beschrieben bzw. mit Get WindowLong ausgelesen.
Ist vermutlich eine quick-and-dirty-Lösung.Oder habe ich was falsch verstanden?
-
Elektronix schrieb:
Oder habe ich was falsch verstanden?
Jo ich denke denn:
Um die Hintergrundfarbe und den Status des Child Fensters zu speichern, brauchen wir zwei Integer Variablen. Diese lassen wir für jedes Child Fenster als extra Speicher anfordern. Damit haben wir auch das Problem der nicht getrennten Speicherbereiche gelöst.
Das hat ja nicht mit GetWindowLongPtr zu tun...das ist noch mal für jedes Fenster ein Speicherbereich (sizeof(LONG_PTR) , in dem man beliebige Daten ablegen kann, auch ohne die Reserivierung im cbWndExtra-Element der WNDCLASS(EX)-Struktur.
Diese Reservierung (sizeof(int) * 2) gilt für jedes, mit diesem Klassennamen erstellte Fenster.BTW: IMHO ist auf der Seite n Fehler: RGB-Werte werden in der WinAPI in COLORREF-Variablen abgelegt, die ihrerseits den Typ
unsigned int haben...man müsste also korrekterweise eigentlich sizeof(unsigned int) * 2 schreiben
.
-
CodeFinder schrieb:
EDIT: @ Elektronix: Jojo, war nicht ansatzweise böse gemeint oder so.
Danke. Hab ich auch nicht so verstanden.

CodeFinder schrieb:
Das hat ja nicht mit GetWindowLongPtr zu tun...das ist noch mal für jedes Fenster ein Speicherbereich (sizeof(LONG_PTR) , in dem man beliebige Daten ablegen kann, auch ohne die Reserivierung im cbWndExtra-Element der WNDCLASS(EX)-Struktur.
Hmmm, hab ich noch nicht so ganz verstanden. Weil ja im Tutorial SetWindowLong einmal den Status des Fensters setzt (das Fenster funktioniert als Button, der gesetzt oder nicht gesetzt wird). (sizeof(LONG_PTR) oder Parameter wie GWL_USERDATA o. ä. finde ich nicht in dem Prog. Andererseits hätte man für Farbe und Status zusätzliche Variablen definieren müssen.

-
Elektronix schrieb:
[...]sizeof(LONG_PTR) oder Parameter wie GWL_USERDATA o. ä. finde ich nicht in dem Prog.
Also wenn du die Funktion SetWindowLongPtr benutzt dann kannst du damit einen Speicherbereich der Größe sizeof(LON_PTR) beschreiben,
um darin zum Beispiel ein Zeiger auf eine Struktur abzulegen. Bei der Funktion SetWindowLong (nicht 64-Bit kompatibel) ist der
Speicherbereich eben sizeof(LPARAM) bzw. sizeof(long) groß.
-
OK, wieder was dazugelernt.
Danke.