SORU
15 HAZİRAN 2011, ÇARŞAMBA


En iyi yapmak için olmayan-titrek, parçalı grafik güncellemeleri Delphi şekilde?

Bu sadece orada dışarı atmak ve bunu sorabilirim diye düşündüm: Delphi grafik efektleri açısından kusursuz denetimleri gördüm. Anlamı: hiçbir titreme, kesitli güncellemeleri (sadece kirli olarak işaretlenmiş bir kontrol bölümü yeniden düzenleme) ve yumuşak kaydırma.

Ben şifreli bir sürü grafik denetimleri yıllar boyunca, bu kadar biliyorum hakkında çift ara belleğe alma, beştaş, bitblts ve tüm "ortak" şeyler (hep kullanmak beştaş Beraberlik için her şey mümkün, ama orada bir Tepegöz). InvalidateRect ve kontrol TCanvas.Güncelleştirilmesi gereken gerçek bir dörtgen için ClipRect. Tüm bu tipik çözümleri rağmen, çok zor - Express ya da Yerle Bileşenleri dediğiniz gibi aynı kalitede parçalar oluşturmak için bulabilirsiniz. Eğer grafik pürüzsüz ise kaydırma çubukları (yerli) titreme bahis yapabilirsiniz ve eğer kaydırma çubukları ve çerçeve düzgünse kaydırma sırasında arka plan titriyor yemin ederim.

Kod standart bir kurulum bu işi var mı? Tüm kontrol bir kontrol olmayan istemci alanı da dahil olmak üzere, pürüzsüz yeniden çizer sağlayan en iyi uygulamaları bir tür?

Örneğin, burada "çıplak kemik" kontrol kesimli güncellemeleri yükseklik (gerekli olan sadece yeniden düzenleme). Eğer bir form oluşturursanız, bir pencere hareket ve renkleri ile parçaları (boya yöntemi ile değiştirin izlemek deneyin.

Herkes titrek olmayan istemci alanının yeniden çizer kullanabilen benzer bir temel sınıf var mı?

type

TMyControl = Class(TCustomControl)
private
  (* TWinControl: Erase background prior to client-area paint *)
  procedure WMEraseBkgnd(var Message: TWmEraseBkgnd);message WM_ERASEBKGND;
Protected
  (* TCustomControl: Overrides client-area paint mechanism *)
  Procedure Paint;Override;

  (* TWinControl: Adjust Win32 parameters for CreateWindow *)
  procedure CreateParams(var Params: TCreateParams);override;
public
  Constructor Create(AOwner:TComponent);override;
End;


{ TMyControl }

Constructor TMyControl.Create(AOwner:TComponent);
Begin
  inherited Create(Aowner);
  ControlStyle:=ControlStyle - [csOpaque];
end;

procedure TMyControl.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);

  (* When a window has this style set, any areas that its
     child windows occupy are excluded from the update region. *)
  params.ExStyle:=params.ExStyle   WS_CLIPCHILDREN;

  (* Exclude VREDRAW & HREDRAW *)
  with Params.WindowClass do
  Begin
    (* When a window class has either of these two styles set,
       the window contents will be completely redrawn every time it is
       resized either vertically or horizontally (or both) *)
    style:=style - CS_VREDRAW;
    style:=style - CS_HREDRAW;
  end;
end;

procedure TMyControl.Paint;

  (* Inline proc: check if a rectangle is "empty" *)
  function isEmptyRect(const aRect:TRect):Boolean;
  Begin
    result:=(arect.Right=aRect.Left) and (aRect.Bottom=aRect.Top);
  end;

  (* Inline proc: Compare two rectangles *)
  function isSameRect(const aFirstRect:TRect;const aSecondRect:TRect):Boolean;
  Begin
    result:=sysutils.CompareMem(@aFirstRect,@aSecondRect,SizeOf(TRect))
  end;

  (* Inline proc: This fills the background completely *)
  Procedure FullRepaint;
  var
    mRect:TRect;
  Begin
    mRect:=getClientRect;
    AdjustClientRect(mRect);
    Canvas.Brush.Color:=clWhite;
    Canvas.Brush.Style:=bsSolid;
    Canvas.FillRect(mRect);
  end;

begin
  (* A full redraw is only issed if:
      1. the cliprect is empty
      2. the cliprect = clientrect *)
  if isEmptyRect(Canvas.ClipRect)
  or isSameRect(Canvas.ClipRect,Clientrect) then
  FullRepaint else
  Begin
    (* Randomize a color *)
    Randomize;
    Canvas.Brush.Color:=RGB(random(255),random(255),random(255));

    (* fill "dirty rectangle" *)
    Canvas.Brush.Style:=bsSolid;
    Canvas.FillRect(canvas.ClipRect);
  end;
end;

procedure TMyControl.WMEraseBkgnd(var Message: TWmEraseBkgnd);
begin
  message.Result:=-1;
end;

Güncellendi

Ben sadece hile yaptığını bir arada olduğunu eklemek istedim:

  1. Olmayan clientarea çizim (zaman) ExcludeClipRect, yani ben clientarea grafik ile örtüşüyor
  2. WMNCCalcSize mesaj anlaşılmıştır yerine sadece ölçümler için bordersize kullanarak. Ben de kenar boyutları, yükseklik almak zorunda kaldı:

    XEdge := GetSystemMetrics(SM_CXEDGE);
    YEdge := GetSystemMetrics(SM_CYEDGE);
    
  3. RedrawWindow() çağıran hareket, kaydırma çubukları veya yeniden boyutlandırma zaman aşağıdaki bayraklı:

    mRect:=ClientRect;
    mFlags:=rdw_Invalidate
      or RDW_NOERASE
      or RDW_FRAME
      or RDW_INTERNALPAINT
      or RDW_NOCHILDREN;
    RedrawWindow(windowhandle,@mRect,0,mFlags);
    
  4. Boya sırasında arka planda güncelleme yaparken() yöntemi, Olası çocuk nesneleri çizim üzerinde önlemek için, bu gibi (RDW_NOCHİLDREN yukarıda bakınız):

    for x := 1 to ControlCount do
    begin
      mCtrl:=Controls[x-1];
      if mCtrl.Visible then
      Begin
        mRect:=mCtrl.BoundsRect;
        ExcludeClipRect(Canvas.Handle,
        mRect.Left,mRect.Top,
        mRect.Right,mRect.Bottom);
      end;
    end;
    

Yardım için teşekkürler çocuklar!

CEVAP
15 HAZİRAN 2011, ÇARŞAMBA


Tampon ve süslü çift çizim taktikleri bu hikayenin sadece yarısı. Diğer yarısı, biraz daha kritik yarısı iddia ediyorum, geçersiz nasıl sınırlamaktır.

Yorumlarınızı, RedrawWindow(handle, @R, 0, rdw_Invalidate or rdw_Frame) kullandığınız söz. R dikdörtgen için ayarı nedir? Eğer müşteri alan rect ayarlarsanız, daha sonra kontrol tüm istemci alanının yeniden çizilmesi. Kaydırma, kontrol sadece küçük bir kısmı yeniden çizilmesi gerekiyor - "" kaydırma yönü. kenardan izleyen de dilim Windows ekran için istemci alanı ekranın geri kalanı mevcut piksel kaydırma yönünde hareket etmek bitblit.

Ayrıca pencere bayraklarınızı tam gerektirecek şekilde ayarlanmış olup olmadığını kontrol kaydırma üzerinde yeniden çizmek. Bayrak isimleri aklımda birşey hatırlamıyorum, ama kaydırma eylemleri yalnızca istemci alanının bir dilim geçersiz kılmak, böylece onları kapatılır istiyorum. Bu Windows varsayılan olduğuna inanıyorum.

Hatta donanım hızlandırılmış grafik ile, daha az iş ve daha fazla iş daha. Mutlak minimum düzeyde geçersiz senin rects ve sistem otobüs iterek ucundasın piksel sayısını azaltmak.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • multimediaGEEKS LLC

    multimediaGE

    3 Mayıs 2010
  • Richard Laxa

    Richard Laxa

    30 AĞUSTOS 2012
  • Rootjunky.com

    Rootjunky.co

    22 EKİM 2011