Bitmaps übereinander zeichnen
-
Guten Abend,
ich befasse mich noch nicht lange mit der WinApi und habe ein Problem:
ich programmiere gerade das Spiel "Mensch ärger dich nicht" und möchte deshalb
die Spielfiguren auf das Spielfeld zeichnen. Aber bei dem Code:case WM_PAINT: { HDC hDC,MemDC; PAINTSTRUCT ps; HBITMAP hbmp; RECT r; GetWindowRect(hwnd,&r); hDC = BeginPaint(hwnd,&ps); hbmp = (HBITMAP) LoadImage (NULL,"Data\\Spielbrett.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE); MemDC = CreateCompatibleDC(hDC); SelectObject(MemDC,hbmp); BitBlt(hDC,0,0,r.right,r.bottom,MemDC,0,0,SRCCOPY); DeleteDC(MemDC); DeleteObject(hbmp); EndPaint(hwnd,&ps); GetWindowRect(hwnd,&r); hDC = BeginPaint(hwnd,&ps); hbmp = (HBITMAP) LoadImage (NULL,"Data\\Figur_blau.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE); MemDC = CreateCompatibleDC(hDC); SelectObject(MemDC,hbmp); BitBlt(hDC,0,0,r.right,r.bottom,MemDC,0,0,SRCCOPY); DeleteDC(MemDC); DeleteObject(hbmp); EndPaint(hwnd,&ps); break; }
Wird nur das Spielfeld ausgegeben und nicht die blaue Figur. (Wenn ich es anders herum mache wird nur die Figur ausgegeben)
Weiß jemand wie ich die beiden Bitmaps übereinander zeichen kann?
Danke im Voraus
-
Warum erstellst du zwei mal das target DC? Zeichne in dasselbe.
-
Danke, so funktioniert es:
case WM_PAINT: { HDC hDC,MemDC; PAINTSTRUCT ps; HBITMAP hbmp; RECT r; GetWindowRect(hwnd,&r); hDC = BeginPaint(hwnd,&ps); hbmp = (HBITMAP) LoadImage (NULL,"Data\\Spielbrett.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE); MemDC = CreateCompatibleDC(hDC); SelectObject(MemDC,hbmp); BitBlt(hDC,0,0,r.right,r.bottom,MemDC,0,0,SRCCOPY); hbmp = (HBITMAP) LoadImage (NULL,"Data\\Figur_blau.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE); MemDC = CreateCompatibleDC(hDC); SelectObject(MemDC,hbmp); BitBlt(hDC,0,0,r.right,r.bottom,MemDC,0,0,SRCCOPY); DeleteDC(MemDC); DeleteObject(hbmp); EndPaint(hwnd,&ps); break; }
-
Ich bin nicht ganz sicher, aber ich denke, Du musst
DeleteDC(MemDC); DeleteObject(hbmp);
bereits vorher einmal aufrufen, bevor Du
MemDC
und
hbmp
neue Werte zuweist.
-
Das leaked ohne Ende!
1. Die Bitmap, die mit CreateCompatibleDC miterzeugt wird, geht verloeren.
Also Den Wert von SelectObject sichern, vor dem Delete zurück selektieren.
2. Wie Belli es schreibt: Du erzeugst einen kompatiblen DC und eine Bitmap die "weggeschmissen" werden und verloren geht.
-
Ok, werde ich machen, danke.
-
Noch eine Frage:
wie erreiche ich, dass beim Start meines Programms eine Bitmap als Hintergrund geladen wird und dann für den Rest der Laufzeit "unangetastet" bleibt?
Wenn ichInvalidateRect(hWnd,NULL,TRUE);
aufrufe, dann wird ja der Bildschirminhalt gelöscht und WM_PAINT aufgerufen, ich möchte aber, dass (nur) der Hintergrund erhalten bleibt.
-
Ich glaube, dazu musst Du auf WM_ERASEBKGND einen nonzero-Returnwert zurückliefern:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648055(v=vs.85).aspx
-
Danke, es funktioniert
-
Bitmapper schrieb:
Danke, es funktioniert
Aber nicht besonders gut.
Eine (leichte) Verbesserung wäre z.B., den Hintergrund nur einmal zu laden
hbmp = (HBITMAP) LoadImage (NULL,"Data\\Spielbrett.bmp",IMAGE_BITMAP
und nicht jedesmal zu löschen.