![]() |
nonVCL - Bitmap in Bitmap kopieren
Hi,
wie kann man ein Bitmap in ein anderes kopieren ? Diese Procedure zeichnet nur darüber:
Delphi-Quellcode:
Ich möchte in einem Dialog enth. Bitmap mein eigenes einsetzen.
procedure SetBitmap(hWnd: HWND);
begin h_DC := GetDC(GetDlgItem(hwnd, IDC_IMG1)); hBitmapDC := CreateCompatibleDC(h_DC); hOldBitmap := SelectObject(hBitmapDC, Bitmap); BitBlt(h_DC, 0, 0, 32, 32, hBitmapDC, 0, 0, SRCCOPY); SelectObject(hBitmapDC, hOldBitmap); DeleteDC(hBitmapDC); ReleaseDC(hwnd, h_DC); end; VCL:
Delphi-Quellcode:
ImageX.Picture.Assign(MyBitmap);
|
Re: nonVCL - Bitmap in Bitmap kopieren
Ich weiß zwar nicht genau was du willst, aber entweder mußt du wohl ein anderes Flag in BitBlt() einsetzen als SRCCOPY - damit kannst du zwei Bitmaps "mischen".
Zitat:
|
Re: nonVCL - Bitmap in Bitmap kopieren
Wenn's ein STATIC-Element ist dann suchst du vielleicht nach der Meldung
![]() |
Re: nonVCL - Bitmap in Bitmap kopieren
Zitat:
Zitat:
Zitat:
Zitat:
Doch nun stecke ich wieder fest. Also ich möchte ein vorhandenes Image (Bitmap) auf einem Dialog durch ein selbst erstelltes (aus einer Bitmap-Resource) ersetzen.
Delphi-Quellcode:
So funktioniert das nicht. Irgendwie habe ich den Durchblick verloren... :gruebel:
// var ResBitmap: HBITMAP ist global def.
// ResBitmap := LoadBitmap(hInstance, MAKEINTRESOURCE(1)); procedure SetBitmap(hWnd: HWND); var myBitmapDC: HDC; ResBitmapDC: HDC; myBitmap: HBITMAP; hOldBitmap: HBITMAP; begin // DC von DlgItem (Image) holen myBitmapDC := GetDC(GetDlgItem(hwnd, IDC_IMG1)); // DC für ResBitmap erstellen ResBitmapDC := CreateCompatibleDC(myBitmapDC); // Mem-Bitmap erzeugen myBitmap := CreateCompatibleBitmap(myBitmapDC, 32, 32); // dem Mem-Bitmap einen DC zuweisen SelectObject(myBitmapDC, myBitmap); // dem ResBitmap einen DC zuweisen hOldBitmap := SelectObject(ResBitmapDC, ResBitmap); // Bild von ResBitmap zu Mem-Bitmap kopieren BitBlt(myBitmapDC, 0, 0, 32, 32, ResBitmapDC, 0, 0, SRCCOPY); // dem DlgItem-Image das neue (Mem)Bitmap senden SendDlgItemMessage(hwnd, IDC_IMG1, STM_SETIMAGE, IMAGE_BITMAP, myBitmap); SelectObject(ResBitmapDC, hOldBitmap); DeleteDC(ResBitmapDC); ReleaseDC(GetDlgItem(hwnd, IDC_IMG1), myBitmapDC); end; |
Re: nonVCL - Bitmap in Bitmap kopieren
Laß den Rest weg und weise einfach ResBitmap über SendDlgItemMessage(hwnd, IDC_IMG1, STM_SETIMAGE, IMAGE_BITMAP, ResBitmap); zu. Dazu vorher mit ResBitmap := LoadBitmap(hInstance, MAKEINTRESOURCE(1)); laden.
|
Re: nonVCL - Bitmap in Bitmap kopieren
Das geht nicht, äh.. schon aber ich will nur einen Ausschnitt aus dem ResBitmap auf/in das "DlgItem-Image" machen. :wink:
Delphi-Quellcode:
Sonst wäre es ja zu einfach. :zwinker:
BitBlt(myBitmapDC, 0, 0, 32, 32, ResBitmapDC, count * 32 - 32,
Animation[AnimType].Offset * 32, SRCCOPY); |
Re: nonVCL - Bitmap in Bitmap kopieren
Aha, na das kann man ja nicht wissen :zwinker:
In diesem Falle holst du dir den DC des (Client-)Fensters, erstellst einen kompatiblen (Mem-)DC. Dann selektierst du deine Ressourcen-Bitmap in den Mem-DC. Danach blittest du von dem Mem-DC auf den des Fensters mit den entsprechenden von dir vorgesehenen Offsets. An deiner Stelle würde ich die Ressourcen-Bitmap aber immer geladen lassen!!! |
Re: nonVCL - Bitmap in Bitmap kopieren
Zitat:
Ansonsten: mit STM_GETIMAGE die Bitmap des fremden Fensters holen, modifizieren (wie von Olli beschrieben), und mit STM_SETIMAGE wieder setzen. |
Re: nonVCL - Bitmap in Bitmap kopieren
Zitat:
|
Re: nonVCL - Bitmap in Bitmap kopieren
Ich auch. :wink:
Auf die Gefahr hin, dass ihr mich auf den Hof fegen schickt, hänge ich den Sourcecode mal an, in der Hoffnung, das ihr mal ein (oder auch zwei) Auge(n) drauf werft. Ich komme einfach nicht weiter. Es geht um die Procedure SetBitmap(hWnd: HWND);. [Edit=turboPASCAL] Anhang entfernt, kommt aber wo anders wieder. :tongue: [/Edit] |
Re: nonVCL - Bitmap in Bitmap kopieren
Ich schreib's jetzt mal aus dem Kopf, habe hier schon alles beendet (da fehlen noch etliche try-finally-Blöcke)...
Delphi-Quellcode:
und das nur ein mal (für jeden Animationsschritt) und nicht bei jedem WM_PAINT.
// Bitmap holen, DC erzeugen und hineinselektieren
// myDC malt jetzt in die Bitmap myBitmap := SendMessage(GetDlgItem(hwnd, IDC_IMG1), STM_GETIMAGE, IMAGE_BITMAP, 0); myDC := CreateCompatibleDC(0); oldBitmap := SelectObject(myDC, myBitmap); // Zweiten DC erzeugen und Ausgangsbitmap hineinselektieren // myDC2 malt jetzt mit der Ressourcenbitmap myDC2 := CreateCompatibleDC(0); oldBitmap2 := SelectObject(myDC2, ResBitmap); // Zeichnen BitBlt(myDC, 0, 0, 32, 32, myDC2, count * 32 - 32, Animation[AnimType].Offset * 32, SRCCOPY); // Zweiten DC freigeben SelectObject(myDC2, oldBitmap2); DeleteDC(myDC2); // Ersten DC freigeben SelectObject(myDC, oldBitmap); DeleteDC(myDC); // Bitmap wieder in das Element setzen, ggf. nicht nötig! SendMessage(GetDlgItem(hwnd, IDC_IMG1), STM_SETIMAGE, IMAGE_BITMAP, myBitmap); // Neu zeichnen InvalidateRect(GetDlgItem(hwnd, IDC_IMG1), nil, TRUE); |
Re: nonVCL - Bitmap in Bitmap kopieren
Zitat:
|
Re: nonVCL - Bitmap in Bitmap kopieren
Liste der Anhänge anzeigen (Anzahl: 1)
BITTE NEU HERUNTERLADEN!!! So, hier meine Variante. Ich habe mal schamlos Flocke's Code weiterverwertet. Habe ihn noch schnell auf Thread umgestellt (hatte zuvor mit Timer getestet). In Sachen Thread hat sich ein wenig geändert und außerdem werden alle (Einzel-)Bitmaps der Animationen nun im Speicher gehalten. Man könnte das so optimieren, daß nur jeweils eine "Zeile" im Speicher bliebe. Die Arrays beginnen nun sinnvollerweise bei 0 und die Animationen werden bis auf die Bitmaps schon vorher initialisiert (keine Zuweisung mehr). Hinweis: Die Transparenz habe ich komplett entfernt, da bei mir die Funktion nicht deklariert war und es so schneller ging. Da es nun funktioniert, sollte das das geringste Problem sein ;) Zum Erstellen der Einzelbitmaps ...
Delphi-Quellcode:
Um "weiterzuschalten":
function PrepareAnimations(var Anim: TAnimation): Boolean;
var i: TAniType; j: Integer; MemDC, MemDC2: HDC; oldBitmap, oldBitmap2, ResBitmap: HBITMAP; begin Result := True; // Bitmap der Animationen laden ResBitmap := LoadBitmap(hInstance, MAKEINTRESOURCE(10)); // DCs erzeugen MemDC := CreateCompatibleDC(0); MemDC2 := CreateCompatibleDC(0); for i := aniCat to aniGreenBounce do for j := 0 to Anim[i].MaxImages - 1 do begin Anim[i].Bitmaps[j] := CreateCompatibleBitmap(MemDC, BMPWIDTH, BMPHEIGHT); // Korrekte Bitmaps selektieren oldBitmap := SelectObject(MemDC, Anim[i].Bitmaps[j]); oldBitmap2 := SelectObject(MemDC2, ResBitmap); // Zeichnen auf MemDC von dem korrekten Offset in MemDC2 aus BitBlt(MemDC, 0, 0, BMPWIDTH, BMPHEIGHT, MemDC2, j * BMPWIDTH, Anim[i].Offset * BMPHEIGHT, SRCCOPY); // DC "freigeben" indem die alte Bitmap zurückselektiert wird SelectObject(MemDC2, oldBitmap2); // Alte Bitmap zurückselektieren und somit die Änderung in Anim[i].Bitmaps[j] schreiben SelectObject(MemDC, oldBitmap); end; // DCs freigeben DeleteDC(MemDC2); DeleteDC(MemDC); // Resourcenbitmap freigeben DeleteObject(ResBitmap); end; function UnprepareAnimations(var Anim: TAnimation): Boolean; var i: TAniType; j: Integer; begin Result := True; for i := aniCat to aniGreenBounce do for j := 0 to Anim[i].MaxImages - 1 do if (Anim[i].Bitmaps[j] <> 0) then begin // Bitmap freigeben DeleteObject(Anim[i].Bitmaps[j]); Anim[i].Bitmaps[j] := 0; end; end;
Delphi-Quellcode:
PS: Sorry, aber ich mußte einen Sourceformatter verwenden. Irgendwie kam ich mit weiten Teilen deiner Formatierung überhaupt nicht klar.
function SetNextAnimationStep(var Anim: TAnimation; hwnd: HWND; anitype: TAniType): Boolean;
begin Result := True; // Eins hochsetzen inc(Anim[anitype].Current); // Zurücksetzen bei Overflow if (Anim[anitype].Current >= Anim[anitype].MaxImages) then Anim[anitype].Current := 0; // Neuen Animationsschritt setzen SendMessage(hwnd, STM_SETIMAGE, IMAGE_BITMAP, Anim[anitype].Bitmaps[Anim[anitype].Current]); end; function MyTimerThreadFunc(Parameter: Pointer): Integer; var parms: PThreadParamBlock; begin parms := Parameter; if (Assigned(parms) and Assigned(parms^.Anim) and IsWindow(parms^.TargetWnd)) then while (not parms^.ExitThread) do begin SetNextAnimationStep(parms^.Anim^, parms^.TargetWnd, parms^.AnimType); Sleep(parms^.Anim^[parms^.AnimType].Times[0]); end; Result := 0; // Set up a 0 return value EndThread(0); // End the thread end; BITTE NEU HERUNTERLADEN!!! Verwendung: einfach die Datei durch die alte im obigen Archiv von Matti ersetzen. |
Re: nonVCL - Bitmap in Bitmap kopieren
:shock: Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
// def. in Windows.pas
function SetLayeredWindowAttributes(Wnd: hwnd; crKey: ColorRef; Alpha: Byte; dwFlags: DWORD): Boolean; stdcall; external 'user32.dll'; Zitat:
Delphi-Quellcode:
erstellt wird ist der Hintergrund schwarz, also müsste ich diese Sache durch
CreateCompatibleBitmap(MemDC, BMPWIDTH, BMPHEIGHT);
Delphi-Quellcode:
ersetzen. Wobei ich nicht so recht wei mit pointer to array containing color data etwas anzufangen.
HBITMAP CreateBitmap(
int nWidth, // bitmap width, in pixels int nHeight, // bitmap height, in pixels UINT cPlanes, // number of color planes used by device UINT cBitsPerPel, // number of bits required to identify a color CONST VOID *lpvBits // pointer to array containing color data ); Zitat:
Vielen Dank an euch beide! :hi: |
Re: nonVCL - Bitmap in Bitmap kopieren
Reicht es dir erstmal so, oder gibt es noch andere Probleme?
![]() |
Re: nonVCL - Bitmap in Bitmap kopieren
Hm, eigentlich wollte ich so 'ne kleine Spielerei mit ein und Ausblenden einbauen.... desswegen.
|
Re: nonVCL - Bitmap in Bitmap kopieren
Zitat:
Ich geh jetzt erstmal mittagessen, hast also Zeit was Ausführliches zu schreiben :zwinker: |
Re: nonVCL - Bitmap in Bitmap kopieren
Zitat:
Zitat:
Zitat:
|
Re: nonVCL - Bitmap in Bitmap kopieren
So, habe fertig.
Was ich machen wollte ist eine Alternative zu dem Programm ![]() Zitat:
Na ja, halt nicht so eins zu eins sondern mit einem kleinem Nutzen. Ich dachte mir wenn ich schon so eine nette kleine Animation unten rechts auf dem Desktop habe kann die auch ein bissel was Sinnvolles machen. Das Programm wird einen kleinen Reminder enthalten, wie du sicherlich schon bemerkt hast. Mit der Transparenz hatte ich mir das so vorgestellt, dass sich die Animation bei dem Programmstart ein- und beim Programm Ende ausblendet. Ob ich das noch während dem Wechsel zwischen den Animationen machen will ist noch nicht sicher. Deswegen benötige ich das Layered Window. ( und die ganze Sache mit dem Bitmaps ) Ich hoffe mal dass ich deine Anfrage auf Ausführlichkeit meiner Antworten hiermit zu deiner Befriedigung beantworten konnte. :stupid: PS.: Ich will halt auch mal (wieder) ein bisschen in der non VCL Sparte ein "Refresh" durchführen. Das ist schon lange, lange her und erinnert mich irgend wie doch stark an Turbo Pascal für Windows Version 1... . // Nachtrag: @Flocke Zitat:
Ich habe den Code gestern 1:1 übernommen und es has ohne Probleme Funktioniert. :thumb: |
Re: nonVCL - Bitmap in Bitmap kopieren
Ich schaue es mir heute am Abend oder im Laufe des morgigen Tages mal an. Jetzt am Nachmittag komme ich nicht mehr dazu.
Zitat:
|
Re: nonVCL - Bitmap in Bitmap kopieren
Wird wohl noch eine Weile dauern, bis ich es mir noch genauer anschauen kann. Ich behalte das Projekt solange auf der Platte. Könntest du mich mal spätestens am Wochenende an das Thema erinnern (per PN)?!
|
Re: nonVCL - Bitmap in Bitmap kopieren
Naja, so wichtig ist das auch nicht :wink: , ich mache ja eh erst mal eine kleine Schaffenspause für das Projekt (bis zum WE :wink: ).
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:33 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz