Delphi-PRAXiS

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 Controls - Doublebuffered (https://www.delphipraxis.net/102644-nonvcl-controls-doublebuffered.html)

Neutral General 1. Nov 2007 17:38


nonVCL Controls - Doublebuffered
 
Hi,

Benutze gerade den AeroGlass Effekt in einer NonVCL Anwendung. Und die Controls werden alle sehr unschön gezeichnet. In der VCL stellt man ja nur Doublebuffered auf true, aber wie mache ich das hier? Hab schon gegoogelt und auch hier im Forum gesucht. Aber weitergeholfen hat mir das alles nicht...

Gruß
Neutral General

SirThornberry 1. Nov 2007 17:39

Re: nonVCL Controls - Doublebuffered
 
dir wird nichts anderes übrig bleiben als das doublebuffering selbst zu programmieren.

Neutral General 1. Nov 2007 17:41

Re: nonVCL Controls - Doublebuffered
 
Ja ich weiß aber meine Frage ist eben wie ich das genau mache.. Hab mehrmals was von Subclassing oder auch der WM_PRINT und WM_ERASEBKGND gelesen, kann mir aber leider daraus nichts zusammenbauen.

Apollonius 1. Nov 2007 18:06

Re: nonVCL Controls - Doublebuffered
 
Was spricht dagegen, es so wie die VCL zu machen? Die erledigt es folgendermaßen: CreateCompatibleBitmap mit dem Desktop-DC und den Control-Maßen, dann CreateCompatibleDC mit dem Desktop-DC, in diesen DC dann das compatible Bitmap selecten, malen, BitBlt und dann aufräumen. Das habe ich jetzt durch ein paar Minuten Studium der Controls.pas herausgekriegt.

xaromz 1. Nov 2007 18:58

Re: nonVCL Controls - Doublebuffered
 
Hallo,

Zitat:

Zitat von Apollonius
Das habe ich jetzt durch ein paar Minuten Studium der Controls.pas herausgekriegt.

...und liegst damit voll daneben. In Delphi 2007 funktioniert der Doublebuffered-Modus (bei Verwendung von Aero-Glass) grundsätzlich anders. Ich poste mal einen Ausschnitt aus der Control.pas:
Delphi-Quellcode:
if DwmCompositionEnabled then
begin
  DC := BeginPaint(Handle, PS);
  try
    PaintBuffer := BeginBufferedPaint(DC, PS.rcPaint, BPBF_COMPOSITED, nil, MemDC);
    Perform(WM_ERASEBKGND, MemDC, MemDC);
    Perform(WM_PRINTCLIENT, MemDC, PRF_CLIENT);
    if not (Self is TCustomForm) then
      BufferedPaintMakeOpaque(PaintBuffer, @PS.rcPaint);
    EndBufferedPaint(PaintBuffer, True);
  finally
    EndPaint(Handle, PS);
  end;
end;
Die interessanten Funktionen sind MSDN-Library durchsuchenBeginBufferedPaint, MSDN-Library durchsuchenBufferedPaintMakeOpaque und MSDN-Library durchsuchenEndBufferedPaint. Diese sind in der Unit UxTheme deklariert und befinden sich in der Bibliothek uxtheme.dll.

Gruß
xaromz

Apollonius 1. Nov 2007 19:17

Re: nonVCL Controls - Doublebuffered
 
Zitat:

Zitat von xaromz
Hallo,

Zitat:

Zitat von Apollonius
Das habe ich jetzt durch ein paar Minuten Studium der Controls.pas herausgekriegt.

...und liegst damit voll daneben.

Danke. :-D Ich habe die Controls.pas von Turbo Delphi 2006 verwendet. dort heißt es:
Delphi-Quellcode:
procedure TWinControl.WMPaint(var Message: TWMPaint);
var
  DC, MemDC: HDC;
  MemBitmap, OldBitmap: HBITMAP;
  PS: TPaintStruct;
if not FDoubleBuffered or (Message.DC <> 0) then
  begin
    if not (csCustomPaint in ControlState) and (ControlCount = 0) then
      inherited
    else
      PaintHandler(Message);
  end
  else
    DC := GetDC(0);
    MemBitmap := CreateCompatibleBitmap(DC, ClientRect.Right, ClientRect.Bottom);
    ReleaseDC(0, DC);
    MemDC := CreateCompatibleDC(0);
    OldBitmap := SelectObject(MemDC, MemBitmap);
    try
      DC := BeginPaint(Handle, PS);
      Perform(WM_ERASEBKGND, MemDC, MemDC);
      Message.DC := MemDC;
      WMPaint(Message);
      Message.DC := 0;
      BitBlt(DC, 0, 0, ClientRect.Right, ClientRect.Bottom, MemDC, 0, 0, SRCCOPY);
      EndPaint(Handle, PS);
    finally
      SelectObject(MemDC, OldBitmap);
      DeleteDC(MemDC);
      DeleteObject(MemBitmap);
    end;
  end;
Ich habe allerdings kein Vista, sodass ich den Aero-Glass-Effekt nicht kommentieren kann.

Neutral General 2. Nov 2007 10:52

Re: nonVCL Controls - Doublebuffered
 
Liste der Anhänge anzeigen (Anzahl: 2)
Ja Leute. Ihr werdets mir nicht glauben aber auch ich hab mir die Controls.pas vorher angeschaut ;)

Ich hab es im Moment so:

Delphi-Quellcode:
procedure TNVCLControl.DoPaint;
var ps: TPaintStruct;
    dc,MemDC: HDC;
begin
  DC := BeginPaint(Handle, PS);
  try
    pb := BeginBufferedPaint(DC, PS.rcPaint, BPBF_COMPOSITED, nil, MemDC);
    Perform(WM_ERASEBKGND, MemDC, MemDC);
    Perform(WM_PRINTCLIENT, MemDC, PRF_CLIENT);
    if not (Self is TNVCLForm) then
      BufferedPaintMakeOpaque(pb, @PS.rcPaint);
    EndBufferedPaint(pb,false);
  finally
    EndPaint(Handle, PS);
  end;
end;

procedure TNVCLControl.WndProc(var Message: TMessage);
begin
  case Message.Msg of
    {...}
    WM_PAINT: begin
                if FVisible then
                  DoPaint;
              end;
  end;
  Message.Result := DefProc(FHandle,Message.Msg,Message.WParam,Message.LParam);
end;
EDIT: Was mir grad auffällt.. BeginBufferedPaint liefert mir ne 0 und GetLastError "Handle is invalid". Wobei ich nicht weiß was an meinem HDC falsch sein soll :wall:

Anbei noch zwei Screenshots wie das ganze aussieht. Einmal vor weißem und einmal vor schwarzem Hintergrund.
Über dem Memo (unter dem DP-Logo) ist rechts noch ein Button und links eine Checkbox, die man jedoch nicht sieht. Die sieht man nur nachdem man die anklickt. Wenn man dann mit nem anderen Fenster "drüberwischt" sind die wieder weg.

PS: Das mit dem CreateCompatibleBitmap und BitBlt usw. hatte ich auch ausprobiert aber mein Bitmap ist immer nur Schwarz.. Hab das dann auch in der VCL versucht.. ungefähr so:

Delphi-Quellcode:
DC := BeginPaint(Button1.Handle,ps);
bmp := CreateCompatibleBitmap(DC,Button1.Width,Button1.Height);
MemDC := CreateCompatibleDC(DC);
SelectObject(MemDC,bmp);
BitBlt(Canvas.Handle,0, 0, // Wills aufs Form malen um zu kontrollieren
            Button1.Width,
            Button1.Height,
            MemDC, // mit MemDC erhalte ich nen schwarzen kasten mit DC wird der Button gemalt
            0, 0,
            SRCCOPY);
Gruß
Neutral General

Neutral General 20. Nov 2007 14:13

Re: nonVCL Controls - Doublebuffered
 
Wenn wir schonmal dabei sind: Wäre froh wenn wir für das hier noch ne Lösung fänden :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:15 Uhr.

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