Flackern beim darstellen mit BitBlt

Jetzt hab ich dein Problem erst richtig verstanden?!
Wenn du die Zeichenfläche löscht, ist es logisch, dass das Bild flackert, da man ja das löschen auch sieht! :)

Das kann man umgehen, indem man sich ein Bitmap, sozusagen als Zwischenablage erstellt und nur dieses bearbeitet. Wenn man dann komplett fertig ist, packt man das Bitmap zum Schluss wieder auf die Zeichenfläche. So sieht man das löschen nicht (geschieht ja nur im Arbeitsspeicher) und das Bild flackert nicht mehr. ;-)

Folgendes Beispiel kopiert eine den Desktop in ein selbst erzeugtes Bitmap im Arbeitsspeicher und dieses dann wieder auf das eigene Fenster:

Code:
 //Die ersten 2 Befehle kannst du dir unter Umständen sparen, wenn du schon Handle`s
 //vom Fenster und vom Desktop hast. "hdcScreenHandle" musst du aber erstellen!
 //Wenn du es nicht machst und direkt das Handle vom Desktop benutzt,
 //versaut dir später die Methode "SelectObject(...)" Eigenschaften vom Desktop.
 //In dem Fall müsste man sich den Rückgabewert von SelectObject(...) merken 
 //und am Ende diesen wieder zuweisen. (Aber das ist jetzt eigenlich auch egal)
 
  //Handle vom Fenster:
  HDC ZeichenFlaecheHandle = GetDC(hWnd);
  //Handle vom Desktop:
  HDC hdcScreen = CreateDC("DISPLAY", (LPCSTR) NULL,
 			(LPCSTR) NULL, (CONST DEVMODE *) NULL);
 
  HDC hdcScreenHandle = CreateCompatibleDC(hdcScreen);
 
  //Bitmap als Zwischenablage:
  BITMAP ZwischenAblage;
  HBITMAP ZwischenAblageHandle;
 
  //Ertelle Bitmap, setze Eigenschaften:
 
  //Ermittelt die Farbtiefe (16/32 Bit) des Zeichengerätes:
  ZwischenAblage.bmBitsPixel = (BYTE) GetDeviceCaps(hdcScreen, BITSPIXEL);
  //Ermittelt die Anzahl Farbebenen des Zeichengerätes:
  ZwischenAblage.bmPlanes = (BYTE) GetDeviceCaps(hdcScreen, PLANES);
  ZwischenAblage.bmWidth = FensterBreite;
  ZwischenAblage.bmHeight = FensterHoehe;
  ZwischenAblage.bmWidthBytes = 0;
 
  ZwischenAblageHandle = CreateBitmap(ZwischenAblage.bmWidth
 					    , ZwischenAblage.bmHeight, ZwischenAblage.bmPlanes
 					    , ZwischenAblage.bmBitsPixel, (CONST VOID *) NULL);
 
  //Weist die Zwischenablage dem Zeichengerät zu:
  SelectObject(hdcScreenHandle, ZwischenAblageHandle);
 
  //Kopiere vom Desktop auf die ZwischenAblage
  BitBlt(hdcScreenHandle,
 		0, 0,
 		FensterBreite, FensterHoehe,
 		hdcScreen,
 		0, 0, SRCCOPY);
 
  //An dieser Stelle kann man das Bild bearbeiten oder auch löschen
  //, ganz wie man will. Zugriff erfolgt über "hdcScreenHandle"
  //Mit den Zeichenfunktionen vom GDI kann man auch wie in "MS Paint" auf das 
  //Bitmap malen. (kann ich dir auch zeigen, wenn du nicht weißt wie´s geht)
 
  //Kopiere vom ZwischenAblage auf Fenster:
  BitBlt(ZeichenFlaecheHandle,
 		0, 0,
 		FensterBreite, FensterHoehe,
 		hdcScreenHandle,
 		0, 0, SRCCOPY);
 
  //Gibt DC´s und Grafikobjekte wieder frei	   
  DeleteDC(ZeichenFlaecheHandle);
  DeleteDC(hdcScreen);
  DeleteDC(hdcScreenHandle);
  DeleteObject(&ZwischenAblage);
  DeleteObject(ZwischenAblageHandle);

Ich hoffe ich konnte dir ne bisschen helfen, vielleicht kanntest du das aber auch schon

mfg Cecidi
 
Ich weiß, dass er das vorgeschlagen hat, aber das Beispiel hab ich ausprobiert und es klappt bei mir.

mfg Cecidi
 
moin


Danke euch!
Hab es jetzt wie Daniel gesagt hat erst zwischen gespeichert und wie Cecidi vorgeschlagen hat für das zwischenspeichern ein Bitmap genommen.

Allerdings etwas kürzer:
Code:
case WM_PAINT:
{
	HDC hDC;
	PAINTSTRUCT ps;

	HDC hDesktopDC = GetDC(hDesktop);

	HDC hMemDC = CreateCompatibleDC(hDesktopDC);
	HBITMAP hBM = CreateCompatibleBitmap(hDesktopDC, rectTotal.right, rectTotal.bottom);
	SelectObject(hMemDC, hBM);

	hDC = BeginPaint(hWnd, &ps);
	{
		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, SRCINVERT);
	}
	EndPaint(hWnd, &ps);
	ReleaseDC(hDesktop, hDesktopDC);
	DeleteDC(hMemDC);
	DeleteObject(hBM);

	return 0;
}


mfg
umbrasaxum
 
Zurück