Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi nonVCL - Bitmap in Bitmap kopieren (https://www.delphipraxis.net/53913-nonvcl-bitmap-bitmap-kopieren.html)

Flocke 25. Sep 2005 20:26

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:
// 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);
und das nur ein mal (für jeden Animationsschritt) und nicht bei jedem WM_PAINT.

Olli 25. Sep 2005 20:32

Re: nonVCL - Bitmap in Bitmap kopieren
 
Zitat:

Zitat von Flocke
Ich schreib's jetzt mal aus dem Kopf, habe hier schon alles beendet (da fehlen noch etliche try-finally-Blöcke)...

Nicht vergessen die alten Bitmaps freizugeben. Aber so in etwa könnte es gehen. Ich schaue gerade selber über den Source.

Olli 25. Sep 2005 21:50

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:
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;
Um "weiterzuschalten":
Delphi-Quellcode:
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;
PS: Sorry, aber ich mußte einen Sourceformatter verwenden. Irgendwie kam ich mit weiten Teilen deiner Formatierung überhaupt nicht klar.

BITTE NEU HERUNTERLADEN!!! Verwendung: einfach die Datei durch die alte im obigen Archiv von Matti ersetzen.

turboPASCAL 26. Sep 2005 10:38

Re: nonVCL - Bitmap in Bitmap kopieren
 
:shock:


Zitat:

Zitat von Olli
BITTE NEU HERUNTERLADEN!!!

Habe ich gemacht. :wink:

Zitat:

Zitat von Olli
So, hier meine Variante. Ich habe mal schamlos Flocke's Code weiterverwertet.
Habe ihn noch schnell auf Thread umgestellt (hatte zuvor mit Timer getestet).

Ich auch, hat mir aber nicht so gefallen andauernt den Timer zu ändern. :wink:

Zitat:

Zitat von Olli
In Sachen Thread hat sich ein wenig geändert und außerdem werden alle (Einzel-)Bitmaps der Animationen nun im Speicher gehalten.

Nunja, was hat dir denn daran nicht gefallen das Bitmap im ganzen im Speicher zu halten dass du es aufteilen musstest ? :wink:

Zitat:

Zitat von Olli
Man könnte das so optimieren, daß nur jeweils eine "Zeile" im Speicher bliebe.

Jupp, wollte ich auch erst, habe es dann aber wieder verworfen. :wink:

Zitat:

Zitat von Olli
Die Arrays beginnen nun sinnvollerweise bei 0 ...

...jaja, das wollte ich auch noch machen... :wink:

Zitat:

Zitat von Olli
Hinweis: Die Transparenz habe ich komplett entfernt, da bei mir die Funktion nicht deklariert war und es so schneller ging.

Nanu, warum nicht ?

Delphi-Quellcode:
// def. in Windows.pas
function SetLayeredWindowAttributes(Wnd: hwnd; crKey: ColorRef; Alpha: Byte; dwFlags: DWORD): Boolean; stdcall; external 'user32.dll';
Zitat:

Zitat von Olli
Da es nun funktioniert, sollte das das geringste Problem sein ;)

Nunja, :wink: da das Bitmap mit
Delphi-Quellcode:
CreateCompatibleBitmap(MemDC, BMPWIDTH, BMPHEIGHT);
erstellt wird ist der Hintergrund schwarz, also müsste ich diese Sache durch
Delphi-Quellcode:
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
   );
ersetzen. Wobei ich nicht so recht wei mit pointer to array containing color data etwas anzufangen.


Zitat:

Zitat von Olli
PS: Sorry, aber ich mußte einen Sourceformatter verwenden. Irgendwie kam ich mit weiten Teilen deiner Formatierung überhaupt nicht klar.

:wink: heheh... ich bin ja auch noch nicht fertig gewesen mit dem schreiben. Dass sollte dann ja auch mal besser aussehen. :mrgreen:

Vielen Dank an euch beide!

:hi:

Olli 26. Sep 2005 10:42

Re: nonVCL - Bitmap in Bitmap kopieren
 
Reicht es dir erstmal so, oder gibt es noch andere Probleme?

MSDN-Library durchsuchenTransparentBlt könntest du auch einfach benutzen, statt deine Idee von oben. Sollte auf allen Systemen vorhanden sein, auf denen es auch Layered Windows gibt ;)

turboPASCAL 26. Sep 2005 10:44

Re: nonVCL - Bitmap in Bitmap kopieren
 
Hm, eigentlich wollte ich so 'ne kleine Spielerei mit ein und Ausblenden einbauen.... desswegen.

Olli 26. Sep 2005 10:46

Re: nonVCL - Bitmap in Bitmap kopieren
 
Zitat:

Zitat von turboPASCAL
Hm, eigentlich wollte ich so 'ne kleine Spielerei mit ein und Ausblenden einbauen.... desswegen.

Sei mal nicht so wortkarg. Erklär mal genauer was dir noch fehlt, bzw. wo du nicht weiterkommst.
Ich geh jetzt erstmal mittagessen, hast also Zeit was Ausführliches zu schreiben :zwinker:

turboPASCAL 26. Sep 2005 10:51

Re: nonVCL - Bitmap in Bitmap kopieren
 
Zitat:

Zitat von Olli
Sei mal nicht so wortkarg. Erklär mal genauer was dir noch fehlt, bzw. wo du nicht weiterkommst.

Ähm...

Zitat:

Ich geh jetzt erstmal mittagessen
Ich auch...

Zitat:

, hast also Zeit was Ausführliches zu schreiben :zwinker:
Nö. :wink:

turboPASCAL 26. Sep 2005 12:51

Re: nonVCL - Bitmap in Bitmap kopieren
 
So, habe fertig.

Was ich machen wollte ist eine Alternative zu dem Programm Bounce for Sakura v1.0 von MaBuSE und das als Non VCL Version, weil SirThornberry fragte,
Zitat:

Zitat von SirThornberry
ist das ganze bereits nonvcl? (bischen groß die exe) Wenn das ganze noch weniger ressourcen benötigen würde wäre es supi.

und das wollte ich halt umsetzen. Das hast du aber sicherlich schon bemerkt.

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:

Zitat von Flocke
Ich schreib's jetzt mal aus dem Kopf, habe hier schon alles beendet (da fehlen noch etliche try-finally-Blöcke)...

Wenn man so etwas aus dem Kopf macht, wozu braucht man dann noch einen PC ? :stupid:
Ich habe den Code gestern 1:1 übernommen und es has ohne Probleme Funktioniert. :thumb:

Olli 26. Sep 2005 13:38

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:

Zitat von turboPASCAL
Wenn man so etwas aus dem Kopf macht, wozu braucht man dann noch einen PC ? :stupid:

... zum Kompilieren :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:35 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz