Problem mit Window Background



  • int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* pCmdLine, int nCmdShow)
    {
    	char* szClass = "jumpnrun";
    	char* szTitle = "jump&run";
    
    	WNDCLASSEX wcex;
    
    	wcex.cbSize			= sizeof(WNDCLASSEX);
    	wcex.style          = CS_OWNDC; //  | CS_GLOBALCLASS ;//CS_HREDRAW | CS_VREDRAW;
    	wcex.lpfnWndProc    = DefWindowProc;//WndProc;
    	wcex.hInstance      = hInstance;
    	wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground  = NULL;//(HBRUSH)(NULL_BRUSH);//(HBRUSH)(COLOR_WINDOW+2);
    	wcex.lpszMenuName   = NULL;
    	wcex.lpszClassName  = szClass;
    	wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
    	wcex.hIconSm        = LoadIcon(hInstance, IDI_APPLICATION);	
    	wcex.cbClsExtra     = 0;
    	wcex.cbWndExtra     = 0;
    
    	if (!RegisterClassEx(&wcex))
    	{
    		Msg("RegisterClassEx failed - Exiting EXIT_FAILURE");
    		return EXIT_FAILURE;
    	}
    
    	DWORD dwStyle =  WS_SYSMENU | WS_MINIMIZEBOX | WS_CAPTION;// | WS_BORDER | WS_OVERLAPPED   ;
    
    	RECT desktop;
    	HWND hDesktop = GetDesktopWindow();
    	GetWindowRect(hDesktop, &desktop);
    
    	int x = ((desktop.right-800)/2);
    	int y = ((desktop.bottom-600)/3);
    
    	RECT wr;
    	wr.left = 0;
    	wr.right = 800 ;//+ wr.left;
    	wr.top = 0;
    	wr.bottom = 600;//+ wr.top;
    	AdjustWindowRect(&wr, dwStyle, false);
    	//Msg("%d %d %d %d", wr.left, wr.right, wr.top, wr.bottom);
    
    	 ghWnd = CreateWindowA(szClass, szTitle, dwStyle, x, y, wr.right-wr.left, wr.bottom-wr.top, NULL, NULL, hInstance,NULL);
    	
    	if (!ghWnd)
    	{ 
    		Msg("Error Creating Main Window - Exiting EXIT_FAILURE");
    		return EXIT_FAILURE;
    	}
    	
    	ShowWindow(ghWnd, nCmdShow);
    
    
    
    	while(true)
    	{
    		if((GetAsyncKeyState(VK_SPACE)&1)==1)
    		{
    			return 0;
    		}
    		Sleep(100);
    
    	}
    }
    

    Hallo!

    Kann mir jemand sagen, warum mein Window einen weißen Background hat, obwohl ich nirgendswo GDI oder sowas verwende und Background in der Class auf NULL stelle?

    Weil ich will das Window dann mit DirectX drawen und nicht über den Windowbackground "drüberdrawen"?

    Liebe Grüße



  • hbrBackground = nullptr heißt daß Du auf WM_ERASEBKGND reagieren und deinen Hintergrund selbst malen musst.

    @CUser1 sagte in Problem mit Window Background:

    nicht über den Windowbackground "drüberdrawen"?

    Deutsch bitte?



  • @Swordfish Warum habe ich dann einen weißen Hintergrund wenn ich NULL reinschreibe? Was ist daran nicht deutsch? Wenn mein Hintergrund weiß ist, liegt es m. E. daran dass irgendwelche GDI Funktionen das weiß machen und ich ändere dann erst mit DirectX die Farbe = drüberdrawen.



  • @CUser1 sagte in Problem mit Window Background:

    Warum habe ich dann einen weißen Hintergrund wenn ich NULL reinschreibe?

    Zieh ein anderes Fenster drüber und stelle dabei fest daß der Hintergrund deines Fensters nicht neu gezeichnet wird. Daß er Anfangs Weiß ist, tjoa.
    // my knowledge is outdated: Früher, vor Compositing Window Manager war es so, daß alles was relativ zu dem Fenster im Vordergrund war lustige Artefakte hinterlassen hat wenn man sich nicht darum gekümmert hat.



  • @CUser1 sagte in Problem mit Window Background:

    @Swordfish Warum habe ich dann einen weißen Hintergrund wenn ich NULL reinschreibe?

    Wenn du hbrBackground == NULL verwendest dann zeichnet Windows für dich keinen Hintergrund. Der Inhalt ist dann undefiniert. Wie das aussieht ist dann z.B. abhängig davon ob der DWM (Desktop Window Manager) in Verwendung ist oder nicht. Ohne DWM bleiben die Pixel einfach unverändert, was auch immer vorher in dem Bereich sichtbar war bleibt so auf dem Bildschirm stehen. Mit DWM bekommst du ein leeres mit einer einheitlichen Farbe gefülltes Fenster.

    Was ist daran nicht deutsch?

    drüberdrawen

    Wenn mein Hintergrund weiß ist, liegt es m. E. daran dass irgendwelche GDI Funktionen das weiß machen und ich ändere dann erst mit DirectX die Farbe = drüberdrawen.

    Jain. Das alles im Detail zu erklären ist mir jetzt zu kompliziert. Der Knackpunkt ist einfach: wenn du hbrBackground == NULL verwendest musst du den gesamten "client" Bereich des Fensters selbst zeichnen, und so lange du das nicht tust, ist das Ergebnis undefiniert. In deinem Fall halt weiss.



  • @Swordfish sagte in Problem mit Window Background:

    Zieh ein anderes Fenster drüber und stelle dabei fest daß der Hintergrund deines Fensters nicht neu gezeichnet wird. Daß er Anfangs Weiß ist, tjoa.

    Probier das mal mit Windows 10 (=DWM per Default immer aktiv). Da passiert das nämlich nicht mehr. Da hat jedes top-level Fenster seinen eigenen, unabhängigen Puffer. Dadurch entfällt auch das ganze lästige, flackerige Neuzeichnen von Fenstern wenn man andere Fenster "drüberzieht".



  • @hustbaer nice to know. Aber das Prinzip bleibt das selbe. Keine Brush für den Bgnd = selbst zeichnen.



  • @hustbaer Die ganzen Buffer der Windows werden dann vom DWM zum Framebuffer zusammencomposiert und der wird ausgegeben? Und wenn man Background = NULL; schreibt erkennt Windows das und nimmt bei mir weiss als default?

    Angenommen ich verwende Swapchain von DirectX? Dann wird auch wieder dem DVM über eine Ecke gesagt er soll mein Window mit swappen?



  • @CUser1 sagte in Problem mit Window Background:

    @hustbaer Die ganzen Buffer der Windows werden dann vom DWM zum Framebuffer zusammencomposiert und der wird ausgegeben?

    Ja. In DirectX-Sprech hast du quasi pro Fenster eine Render-Texture, und der DWM malt die ganzen Texturen der Fenster dann in den Back-Buffer und flippt den dann auf den Schirm.

    Und wenn man Background = NULL; schreibt erkennt Windows das und nimmt bei mir weiss als default?

    Nö. Wenn du Background = NULL schreibst dann malt dir Windows einfach keinen Hintergrund. Das Fenster bekommt aber trotzdem einen Buffer. Und dieser Buffer muss halt irgendeinen initialen Zustand haben. Und dieser initiale Zustand ist scheints weiss. Unabhängig davon was für ein Background Brush Handle du verwendest. Und wenn du dann Background = NULL machst und in bestimmte Bereiche nie selbst zeichnest, dann bleiben diese Bereiche halt einfach weiss.

    Angenommen ich verwende Swapchain von DirectX? Dann wird auch wieder dem DVM über eine Ecke gesagt er soll mein Window mit swappen?

    Wie das im Windowed-Mode läuft weiss ich ehrlich gesagt nicht. Im Fullscreen Mode wird aber soweit ich weiss dem DWM die Kontrolle geklaut, und die Swapchain deines Programms dann direkt verwendet.



  • Ok ich verstehe, also bedeutet Background = NULL; soviel wie ZeroMemory(backbuffer,sizeof(backbuffer));



  • @CUser1 sagte in Problem mit Window Background:

    Ok ich verstehe, also bedeutet Background = NULL; soviel wie ZeroMemory(backbuffer,sizeof(backbuffer));

    Nein.

    Background = NULL bewirkt dass Windows nicht für dich den Hintergrundbereich des Fensters anmalt (im Puffer für das Fenster).

    Das Initialisieren des Puffers mit einer einheitlichen Farbe (Weiss) davor wird mit an Sicherheit grenzender Wahrscheinlichkeit immer gemacht, egal was du als Background angibst.



  • @hustbaer Ja eh und bei dem immer machen wird der Buffer initialisiert mit ZeroMemory einfach mal sicherheits halber meinte ich. Aber in der Windows Seite nicht in der App.



  • @CUser1 Ja. Das hast du bloss vorhin nicht so geschrieben. Und ZeroMemory wird es auch nicht sein, weil das wäre eher Schwarz 😉



  • Und das gilt nur für wenn DWM aktiv ist, und ist ziemlich sicher auch nirgends garantiert. Das einzige was garantiert ist, ist dass Windows den Hintergrundbereich deines Fensters nicht anmalt wenn du NULL als background brush angibst. Und wenn du einen definierten Hintergrund haben willst, dann musst du ihn in dem Fall selber anmalen. Ob jetzt über DirectX oder sonstwie.



  • @hustbaer Dann ist eh alle gut ich dachte mir sonst zeichne ich ständig über den weißen Hintergrund drüber und es flackert dann vielleicht sogar.


Log in to reply