Problem mit verdecktem Fenster
-
Hoi...
Ich würde gern eine Art Menüsystem in einem Fenster verwirklichen (bitte keine Kommentare zu Sinn und Unsinn eines solchen Vorhabens... ich brauchs halt).
Klappt ja auch soweit ganz gut... bis auf eine Kleinigkeit:
Sobald das Fenster verdeckt wurde, bekomme ich den "falschen" Text ausgegeben.
Hier mal der Code zum verständlich machen:#include <windows.h> LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); char szClassName[ ] = "WindowsApp"; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { HWND hwnd; MSG messages; WNDCLASSEX wincl; wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; wincl.style = CS_DBLCLKS; wincl.cbSize = sizeof (WNDCLASSEX); wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; wincl.cbClsExtra = 0; wincl.cbWndExtra = 0; wincl.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); if (!RegisterClassEx (&wincl)) return 0; hwnd = CreateWindowEx ( 0, szClassName, "Invalidate", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 100, HWND_DESKTOP, NULL, hThisInstance, NULL ); ShowWindow (hwnd, nFunsterStil); while (GetMessage (&messages, NULL, 0, 0)) { TranslateMessage(&messages); DispatchMessage(&messages); } return messages.wParam; } LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static LONG i=0, j=0; /* i = Tastaturpuffer, j = Status der Ebene; */ switch (message) { case WM_KEYDOWN: { switch (wParam) { case VK_NUMPAD0: i=0; break; case VK_NUMPAD1: i=1; break; case VK_NUMPAD2: i=2; break; } InvalidateRect(hwnd, NULL, TRUE); return 0; } case WM_PAINT: { PAINTSTRUCT ps; HDC hdc; char mainwin[] = "Hauptfenster"; char win1[] = "Fenster 1"; char win2[] = "Fenster 2"; char subwin1[] = "Sub-Fenster 1"; char subwin2[] = "Sub-Fenster 2"; hdc = BeginPaint(hwnd, &ps); SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, RGB(0,255,0)); if(i == 0){ TextOut(hdc, 110, 25, mainwin, sizeof(mainwin)-1); j=0; } else if(i == 1 && j == 0){ TextOut(hdc, 110, 25, win1, sizeof(win1)-1); j=1; } else if(i == 2 && j == 0){ TextOut(hdc, 110, 25, win2, sizeof(win2)-1); j=2; } else if((i == 1 && j == 1) || (i == 1 && j == 2)){ TextOut(hdc, 110, 25, subwin1, sizeof(subwin1)-1); } else if((i == 2 && j == 1) || (i == 2 && j == 2)){ TextOut(hdc, 110, 25, subwin2, sizeof(subwin2)-1); } EndPaint(hwnd, &ps); return 0; } case WM_DESTROY: PostQuitMessage (0); break; default: return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }Wurde das "Fenster1" angezeigt und dann verdeckt, erscheint danach "Sub-Fenster1".
Ich kann mir schon denken, woran es liegt: wParam hält noch die Taste 1 bzw. 2, und die werden halt dann mit "Sub-Fenster1 bzw. 2" verknüpft und entsprechend neu gezeichnet.
Die Frage ist, wie kann ich das ändern? Hat mal jemand ne Idee?
Grüße
CC
-
Cloudcreature schrieb:
Wurde das "Fenster1" angezeigt und dann verdeckt, erscheint danach "Sub-Fenster1".
Ich stell mir vor, dass zu allererst der String "Hauptfenster" gezeichnet wird. Denn die statischen Variablen 'i' und 'j' werden ja mit 0 initialisiert.
Cloudcreature schrieb:
Ich kann mir schon denken, woran es liegt: wParam hält noch die Taste 1 bzw. 2, und die werden halt dann mit "Sub-Fenster1 bzw. 2" verknüpft und entsprechend neu gezeichnet.
Die Frage ist, wie kann ich das ändern? Hat mal jemand ne Idee?
Das ist völlig unmöglich. Jedesmal wenn Windows deine WindowProcedure aufruft wird auch jedesmal ein neuer Stack angelegt, d.h. der Parameter wParam kann nicht mit dem wParam einer anderen Message interferieren.
Ich kann dir bei deinem Problem leider nicht weiterhelfen. Du musst das Verhalten deines Programms schon ein bisschen besser erklären; vorallem das Problem.
Und übrigens: Wenn du nach einem Tastendruck InvalidateRect aufrufst wird erst dann gezeichnet, wenn keine Messages in der Nachrichtenschleife mehr vorhanden sind. Denn erst dann generiert Windows eine WM_PAINT Nachricht. Um diese Nachricht zu erzwingen kannst du UpdateWindow(hwnd) aufrufen...
-
Aziz schrieb:
Du musst das Verhalten deines Programms schon ein bisschen besser erklären; vorallem das Problem.
Nach Aufruf des Programmes erscheint im Fenster "Hauptmenü".
Nach drücken der Taste 1 (Numblock) erscheint "Fenster 1". Nach erneutem drücken der Taste 1 erscheint "Sub-Fenster 1", nach drücken der Taste 2 "Sub-Fenster 2", mit der 0 gehts zurück ins Hauptmenü, nach Eingabe der 2 kommt man dann zum "Fenster 2", mit der 1 wiederum "Sub-Fenster 1" usw...Problem: Bin ich gerade im "Fenster 1" oder "Fenster 2" und minimiere oder lege ein anderes Fenster drüber, erscheint danach eben nicht mehr "Fenster 1" oder "Fenster 2" sondern "Sub-Fenster 1" bzw. "Sub-Fenster 2", was ja so nicht gewünscht ist, denn natürlich möchte ich, dass nach dem minimieren oder ähnlichem noch genau das im Fenster steht, was vorher auch dort stand.
-
Cloudcreature schrieb:
Problem: Bin ich gerade im "Fenster 1" oder "Fenster 2" und minimiere oder lege ein anderes Fenster drüber, erscheint danach eben nicht mehr "Fenster 1" oder "Fenster 2" sondern "Sub-Fenster 1" bzw. "Sub-Fenster 2", was ja so nicht gewünscht ist, denn natürlich möchte ich, dass nach dem minimieren oder ähnlichem noch genau das im Fenster steht, was vorher auch dort stand.
Ich würd mal sagen, das ist auch kein Wunder

Nachdem nämlich der Text "Fenster1" oder "Fenster2" gezeichnet wurde, wird die Variable 'j' auf 1 bzw. 2 gesetzt. Bei der nächsten WM_PAINT Nachricht wird der if-Block ausgeführt, auf den die Bedingung i = 1 und j = 1 (bzw. ...) zutrifft.
Das bedeutet du musst dein Konzept überarbeiten.
-
Blöder Mist....

Hast ganz recht.. danke!Grüße
CC
-
also bin ich zu doof oder:
static BOOL i=0, j=0;und dann weite unten setzt du i auf 2 wenn NUM2 gedrückt wird aber bool und 0,1,2 !?
bool -> true / false | 0 / undgleich 0
also gibt es doch keine unterscheidung ob 1 oder 2
nur 0 oder halt nicht null
oder bin ich etwa doch zu doof???
-
lol
Es muss natürlich LONG heißen, nicht BOOL.

Hat zwar in dem Fall keine Auswirkung... dennoch,
danke für den Hinweis!
-
Cloudcreature schrieb:
danke für den Hinweis!
Bitte

MfG tuti
-
Ist das Problem jetzt eigentlich gelöst

-
ja, ist es.
case WM_KEYDOWN: { switch (wParam) { case VK_NUMPAD0: i=0; j=0; break; case VK_NUMPAD1: i=1; j++; if(j>=3){ j=2; } break; case VK_NUMPAD2: i=2; j++; if(j>=3){ j=2; } break; } InvalidateRect(hwnd, NULL, TRUE); return 0; }damit gehts (WM_PAINT natürlich angepaßt). Aziz hat mich auf die richtige Spur gebracht.
Danke nochmal...