Buttons verschwinden...



  • Hallo!
    Ich bin relativ neu bei der WinAPI Programmierung. Jetzt habe ich ein kleines Problem: Solange ich bloß Buttons, Textfelder etc einbau, läuft alles reibungslos.
    Sobald ich einen Text einfüge und dann zwischen Fenstern wechsle, sind die Buttons und das Editfeld nicht mehr zu sehen. Das wird an WM_PAINT liegen, aber ich weis nicht, wie ich das beheben soll... 😞
    Hier ist mein Code:

    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HWND hButton;
    	static HWND hEditbox;
    	char		szBuffer[20];
    	double		fnumber;
    	double		fandereZahl=5;
    	static HINSTANCE hInstance;
    	int k;
    	const char  szText[] = "Überschrift";
    
    	switch (message)
    	{
    	case WM_PAINT:
          {
             PAINTSTRUCT   ps;
             HDC           hDC;
    		 hDC = BeginPaint(hwnd, &ps);
             {
    			TextOut(hDC, 10, 10, szText, sizeof(szText) - 1);
    		 }
             EndPaint(hwnd, &ps);
    		 return 0;
          }
    
    	case WM_CREATE:
    
    		hButton = CreateWindow ( "button", "Button1", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    							 10, 60, 130, 40, hwnd, (HMENU)1, 
    							 (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL);
    		hButton = CreateWindow ( "button", "Button2", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    							 10, 100, 130, 40, hwnd, (HMENU)2, 
    							 (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL);
    		hEditbox   = CreateWindowEx (WS_EX_CLIENTEDGE, "edit", "", WS_CHILD | WS_VISIBLE,
    							 10, 30, 130, 25, hwnd, (HMENU)10, 
    							 (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL);
    		return 0;
    
    	case WM_COMMAND:
    		return 0;	
    
    	case WM_DESTROY:
    	     PostQuitMessage (0);
    		 return 0;
    
    	}
    
    	return DefWindowProc (hwnd, message, wParam, lParam);
    }
    

    BTW: wie ändert man die Schriftfarben? Ist bei mir immer Schwarz auf weiß, was bei grauem Hintergrund merkwürdig aussieht...



  • Zunächst solltest Du mal den Code richtig schreiben. Bei Deinen WM_CREATE und WM_COMMAND-Blöcken fehlen nämlich die geschweiften Funktionsklammern.

    Sobald ich einen Text einfüge und dann zwischen Fenstern wechsle, sind die Buttons und das Editfeld nicht mehr zu sehen

    den Text wo einfügst und zwichen welchen Fenstern wechselst? Und wozu brauchst Du bei den HINSTANCE-Parametern der Buttons GetWindowLong? Dort sollte normalerweise

    ((LPCREATESTRUCT)lParam)->hInstance
    

    stehen.

    Übrigens: Diese Zeile:

    case WM_COMMAND:
            return 0;
    

    ist unnötig. Wenn Du WM_COMMAND nicht bearbeiten willst, überlaß das der DefWindowProc.


  • Mod

    Sehe ich das richtig, dass sich die Fenster überlappen?
    Wenn die Fenster nicht die Stile WS_CLIPSIBLINGS haben kann dies nicht funktionieren!



  • case WM_COMMAND:
            return 0;
    

    is genau wie z.B.

    int k;
    

    überflüssig. Hab ein paar unwesentliche Sachen aus dem Code gestrichen. Normalerweise kommt das natürlich nicht ohne WM_COMMAND aus.

    Warum es aber

    ((LPCREATESTRUCT)lParam)->hInstance
    

    und nicht

    (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE)
    

    heißen muss, weis ich nicht. Blicke durch HINSTANCE nicht ganz durch.

    WS_CLIPSIBLINGS -> das hat's vollbracht 🙂 danke!
    Wie ich den Text schön formatier steht bestimmt irgendwo auch in nem tut.



  • ... sind die Buttons und das Editfeld nicht mehr zu sehen. Das wird an WM_PAINT ...liegen

    So ist es.
    Wenn Du bei "WM_PAINT" nach "EndPaint() "return 0" zurückgibst, wird nur das gezeichnet, was zwischen "BeginPaint ()" und "EndPaint ()" liegt.
    Die Controls werden aber gewissermassen von "DefWindowProc ()" gezeichnet.


  • Mod

    HINSTANCE ist das Handle auf die geladene Programm Instanz in Deinem Prozess.

    Solche HINSTANCE Handles werden benötigt um Resourcen zu finden, Fensterklassen zuzuordnen oder einfach Prozess/Modul-Infos mit zu übergeben und zu bekommen.

    Dein WinMain bekommt das hInstance. Speichere den Wert in einer globalen Variable.



  • Extinction schrieb:

    Warum es aber

    ((LPCREATESTRUCT)lParam)->hInstance
    

    und nicht

    (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE)
    

    heißen muss, weis ich nicht. Blicke durch HINSTANCE nicht ganz durch.

    HINSTANCE (Handle to an Instance) enthält die Instanz Deines Programmes. Die gesamten Programm- und Fensterparameter werden in einer CREATESTRUCT abgespeichert, eben auch das hInstance. Wenn Du Childfenster erstellst (ein Button ist nichts anderes), mußt Du dafür die Programminstance abfragen, indem Du einen Zeiger auf das Strukturelement (lParam)hInstance in der CreateStruct setzt.



  • Es ist aber total egal, ob man aufs CREATESTRUCT zugreift, die HINSTANCE via GetModuleHandle oder GetWindowLongPtr ermittelt... es sei denn Du musst auf andere Zielmodule zugreifen. Siehe Martins Erläuterung. Das kommt manchmal vor, wenn Du Resourcen in DLL's auslagerst ( ➡ Resource-Only-DLL's).


  • Mod

    GetModuleHandle(0) funktioniert z.B. in DLLs nicht. Ich würde grundsätzlich den übergebenen HINSTANCE Wert speichern und nutzen.



  • Joar, wenn mehrere Module im Spiel, verwende ich sowieso globale Variablen 😉 .


Anmelden zum Antworten