Flackern beim darstellen mit BitBlt

Tobias K.

Erfahrenes Mitglied
moin


Ich bin dabei eine Bildschirmlupe zu programmieren.
Programmiertechnis habe ich da keine Probleme, nur das das Bild flackert wenn es dargestellt wird.

Code:
case WM_PAINT:
	{
		HDC hDC;
		PAINTSTRUCT ps;

		HDC hDesktopDC = GetDC(hDesktop);
		hDC = BeginPaint(hWnd, &ps);
		{
			BitBlt(hDC, 0, 0, rectTotal.right, rectTotal.bottom,
				hDesktopDC, koord.x - rectTotal.right / 2,
				koord.y - rectTotal.bottom / 2, BLACKNESS | SRCCOPY);
		}
		EndPaint(hWnd, &ps);
		ReleaseDC(hDesktop, hDesktopDC);

		return 0;
	}

Bis jetzt noch ohne vergrößerungseffekt, flackert tut es aber trotzdem.
Wie kann ich das vermeiden?


mfg
umbrasaxum
 
Hallo,
ich kenne mich mit Windows zwar nicht aus, aber habe trotzdem eine Frage:
Wie zeichnest du denn deine Lupe?
Vielleicht hilft es wenn du sie erst auf einen internes Bufferpaint Device vorzeichnest und dann
den kompletten Buffer nimmst und ihm mit deinem Original Panel austauschst.
Nur so als Idee. Wie man das mit der WinAPI realisieren kann weiß ich leider nicht.
Aber schau auch mal bei google nach dem Begriff "Double Buffering"...

Gruß

RedWing
 
Könnte daran liegen, daß Windows meint, es müßte den Hintergrund refreshen. Wenn
du WM_ERASEBKGND abfängst - sprich, es nicht zuläßt - dann sollte es nicht mehr flackern.

BadMourning
 
moin


@RedWing
Ich zeichne keine Lupe es heisst nur so.
Es ist ein Fenster in dem einfach nur dargestellt wird was sich im Bereich des Mauszeigers befindet.

@BadMourning
Kann mal versuchen das abzufangen.
Aber was versteht man in dem Fall den unter "Hintergrund"?
Bis auf das dargestellte Bild besteht das Fenster nur auf Titelleiste und Rahmen.


mfg
umbrasaxum
 
Das Beispiel sollte eigentlich ohne Flackern funktionieren:
(bei mir zumindestens gehts, aber ich benutz auch BCB)
Code:
     HDC ZeichenFlaecheHandle = GetDC (hWnd);
     HDC hdcScreen = CreateDC("DISPLAY", (LPCSTR) NULL,
    			(LPCSTR) NULL, (CONST DEVMODE *) NULL);
    
     BitBlt(ZeichenFlaecheHandle,
 	0, 0,
 	BildschirmBreite, BildschirmHoehe,
 	hdcScreen,
 	0, 0, SRCCOPY);
    
     DeleteDC(ZeichenFlaecheHandle);
     DeleteDC(hdcScreen);

Das Beispiel kopiert den Desktop in das Fenster, ohne Flackern!.

Vielleicht kommt das Flackern durch die Funktionen "BeginPaint(...)" und "EndPaint(...)"?

mfg Cecidi
 
moin


Ja einmal Zeichnen ist kein Ding:
Und das Flackern wird nciht an Begin und EndPaint liegen, sondern daran das ich es bis zu 100 mal in der Sekunde tue. Und daran das immer erst das Bild in meinem Programm gelöscht wird bevor neu gezeichnet wird, was aber dringend nötig ist.


mfg
umbrasaxum
 
Zuletzt bearbeitet:
Umbrasaxum versuche nicht direkt aus dem Desktop zu blitten, sonder nehm einen Memory-DC. Also erst mal den DC im Speicher aufbereiten und dann in deinen eigentlichen DC blitten.
Dieses Verfahren wird auch Backbuffer-Blitting genannt.

Daniel
 
moin


Habs grad versucht, bekomm es aber nciht in.

Könntest du mir kurz die vergehensweise erklären?


mfg
umbrasaxum
 
Boah also ein Codebeispiel hab ich jetzt keins zur hand, aber das bekommst du schon hin.
Ganz kurz so sollte es gehen:
Du legst dir einen MemoryDC an:
CreateCompatibleDC() erstellt einen DC im Speicher basieren auf dem DC den du schon hast , also vom Fenster in das du rein zeichnen willst.
Dann blittest du den Inhalt den du darstellen willst den Memory DC (evtl mit Vergrösserung für deine Lupe) und danach Blittest du aus dem Memory DC in dein Fenster rein.
Fertig.

Ich hoffe du hast daran gedacht, daß das Ganze nur innerhalb deiner Anwendung funktioniert (und für den Desktop da es GetDesktopDC() gibt).
Wenn du allerdings Bereiche anderer Anwenungen vergrößert darstellen willst, so wie es in Windows eingebaute Bildschirmlupe auch kann, dann wirst du an einem Hook nicht vorbeikommen.

Daniel
 
moin


Irgendwie will das nciht gehen, es wird ncihts mehr angezeigt.

Code:
HDC hDC;
	HDC hMemDC;
	PAINTSTRUCT ps;

	HDC hDesktopDC = GetDC(hDesktop);
	
	hDC = BeginPaint(hWnd, &ps);
	{
	hMemDC = CreateCompatibleDC(hDC);

	BitBlt(hMemDC, 0, 0, rectTotal.right, rectTotal.bottom,
		hDesktopDC, koord.x - rectTotal.right / 2,
		koord.y - rectTotal.bottom / 2, SRCCOPY);

	BitBlt(hDC, 0, 0, rectTotal.right, rectTotal.bottom,
		hMemDC, 0,
		0, SRCCOPY);
	}
	EndPaint(hWnd, &ps);
	ReleaseDC(hDesktop, hDesktopDC);
	DeleteDC(hMemDC);

Das Handle vom Desktop hole ich mir mit GetDesktopWindow.

Und mein Programm konnte schon alles was die Windowslupe auch kann, auch ohne Hook! Problem war nur das flackern.


mfg
umbrasaxum
 
Zurück