2010-11-01 4 views
3

Je suis une erreur de vérification de gamme dans ce morceau de code:erreur de vérification de gamme tout en peignant la toile

{ This procedure is copied from RxLibrary VCLUtils } 
procedure CopyParentImage(Control: TControl; Dest: TCanvas); 
var 
    I, Count, X, Y, SaveIndex: Integer; 
    DC: HDC; 
    R, SelfR, CtlR: TRect; 
begin 
    if (Control = nil) OR (Control.Parent = nil) 
    then Exit; 

    Count := Control.Parent.ControlCount; 
    DC := Dest.Handle; 
    with Control.Parent 
    DO ControlState := ControlState + [csPaintCopy]; 

    TRY 
    with Control do 
    begin 
     SelfR := Bounds(Left, Top, Width, Height); 
     X := -Left; Y := -Top; 
    end; 

    { Copy parent control image } 
    SaveIndex := SaveDC(DC); 
    TRY 
     SetViewportOrgEx(DC, X, Y, nil); 
     IntersectClipRect(DC, 0, 0, Control.Parent.ClientWidth, Control.Parent.ClientHeight); 
     with TParentControl(Control.Parent) DO 
     begin 
     {$R-} 
     Perform(WM_ERASEBKGND, DC, 0); <--------------- HERE 
     {$R+}   
     PaintWindow(DC); 
     end; 
    FINALLY 
     RestoreDC(DC, SaveIndex); 
    END; 

    { Copy images of graphic controls } 
    for I := 0 to Count - 1 do begin 
     if Control.Parent.Controls[I] = Control then Break 
     else if (Control.Parent.Controls[I] <> nil) and 
     (Control.Parent.Controls[I] is TGraphicControl) then 
     begin 
     with TGraphicControl(Control.Parent.Controls[I]) do begin 
      CtlR := Bounds(Left, Top, Width, Height); 
      if Bool(IntersectRect(R, SelfR, CtlR)) and Visible then 
      begin 
      ControlState := ControlState + [csPaintCopy]; 
      SaveIndex := SaveDC(DC); 
      try 
       SetViewportOrgEx(DC, Left + X, Top + Y, nil); 
       IntersectClipRect(DC, 0, 0, Width, Height); 
       {$R-}    
       Perform(WM_PAINT, DC, 0); <--------------- HERE 
       {$R+} 
      finally 
       RestoreDC(DC, SaveIndex); 
       ControlState := ControlState - [csPaintCopy]; 
      end; 
      end; 
     end; 
     end; 
    end; 
    FINALLY 
    with Control.Parent DO 
    ControlState := ControlState - [csPaintCopy]; 
    end; 
end; 

Quelqu'un a publié le code sans avoir le Range Check activé :(

je mets {$ R -.} {$ R +} autour des lignes qui génèrent l'erreur et le code fonctionne maintenant, mais je ne sais pas quelles sont les conséquences que je ne veux pas une étrange erreur plus tard


Delphi, Win. 7 32bit

Répondre

9

La procédure Perform s'attend à ce que son deuxième paramètre ait le type WParam, qui est un type entier signé. À partir de Delphi 3, le type HDC du paramètre réel est non signé (comme le sont la plupart des autres types de handles). Il est courant sur les systèmes NT que les poignées aient des valeurs supérieures à MaxInt, ce qui est en dehors de la plage WParam. C'est la source de votre erreur de vérification de distance.

type jeté l'argument et vous serez bien:

Perform(wm_EraseBkgnd, WParam(DC), 0); 

La méthode Perform simplement interpréter la haute valeur non signée comme une grande valeur négative à la place. Il enverra la valeur du paramètre au gestionnaire de messages, et le gestionnaire de messages la renverra au type HDC souhaité. Tous les types sont de la même taille, donc il n'y a pas de danger.

+0

Merci beaucoup. Ça a marché. J'ai vu la différence entre les paramètres mais je n'avais aucune idée que je peux typecast en utilisant WParam. Il semble que le changement est apparu dans Delphi 3 mais le code était destiné à Delphi 2005 et j'ai d'abord pensé qu'il s'agissait d'une erreur dans le code. Probablement le développeur avait l'option Range Check désactivée. – Ampere

2

Cela devrait être OK, c'est le modèle habituel Cardinal/Integer. WM_ERASEBKGND est utilisé comme ceci partout dans la VCL, par exemple dans Controls.pas, avec la directive {$ R-}.

+0

Salut. J'ai déjà essayé Integer. Ça n'a pas marché. +1 pour les explications. – Ampere

+0

Je veux dire, soit vous explicitement typé comme Rob suggéré, ou vous utilisez {$ R-} comme vous l'avez fait et comme c'est fait dans la VCL (en particulier Controls.pas). –

Questions connexes