2009-02-25 7 views
4

Y at-il un moyen de suspendre tous les contrôles ancrés sur un formulaire de se déplacer ou de se redimensionner temporairement? i.e. .:Delphi 5: comment suspendre les dispositions d'ancre?

procedure ScaleFormBy(AForm: TForm; n, d: Integer); 
begin 
    AForm.SuspendAnchors(); 
    try 
     AForm.ScaleBy(n, d); 
    finally 
     AForm.ResumeAnchors(); 
    end; 
end; 

que je dois faire cela parce que j'appelle

AForm.ScaleBy(m, d); 

Ce qui ne gère pas correctement les contrôles ancrés. (Il pousse gauche + droite ou en haut + bas ancré contrôle du bord de la forme

Note:.. Je veux désactiver Ancres, pas d'alignement

Répondre

4

Guy avait une bonne idée, mais il ne s'occupait pas du contrôle des enfants (c.-à-d. TPanel, TPageControl, etc.)

Voici une variante qui utilise la récursivité. Notez également que je ne désactive pas réellement les ancres - il s'avère que ScaleBy ne fonctionne pas non plus.

Alors maintenant, vous pouvez redimensionner un formulaire en utilisant:

procedure ScaleFormBy(AForm: TForm; M, D: Integer); 
var 
    StoredAnchors: TAnchorsArray; 
begin 
    StoredAnchors := DisableAnchors(AForm); 
    try 
     AForm.ScaleBy(M, D); 
    finally 
     EnableAnchors(AForm, StoredAnchors); 
    end; 
end; 

Avec les fonctions de bibliothèque de support:

TAnchorsArray = array of TAnchors; 

function DisableAnchors(ParentControl: TWinControl): TAnchorsArray; 
var 
    StartingIndex: Integer; 
begin 
    StartingIndex := 0; 
    DisableAnchors_Core(ParentControl, Result, StartingIndex); 
end; 

procedure EnableAnchors(ParentControl: TWinControl; aAnchorStorage: TAnchorsArray); 
var 
    StartingIndex: Integer; 
begin 
    StartingIndex := 0; 
    EnableAnchors_Core(ParentControl, aAnchorStorage, StartingIndex); 
end; 

procedure DisableAnchors_Core(ParentControl: TWinControl; var aAnchorStorage: TAnchorsArray; var StartingIndex: Integer); 
var 
    iCounter: integer; 
    ChildControl: TControl; 
begin 
    if (StartingIndex+ParentControl.ControlCount+1) > (Length(aAnchorStorage)) then 
     SetLength(aAnchorStorage, StartingIndex+ParentControl.ControlCount+1); 

    for iCounter := 0 to ParentControl.ControlCount - 1 do 
    begin 
     ChildControl := ParentControl.Controls[iCounter]; 
     aAnchorStorage[StartingIndex] := ChildControl.Anchors; 

     if ([akLeft, akRight ] * ChildControl.Anchors) = [akLeft, akRight] then 
     ChildControl.Anchors := ChildControl.Anchors - [akRight]; 

     if ([akTop, akBottom] * ChildControl.Anchors) = [akTop, akBottom] then 
     ChildControl.Anchors := ChildControl.Anchors - [akBottom]; 

     Inc(StartingIndex); 
    end; 

    //Add children 
    for iCounter := 0 to ParentControl.ControlCount - 1 do 
    begin 
     ChildControl := ParentControl.Controls[iCounter]; 
     if ChildControl is TWinControl then 
     DisableAnchors_Core(TWinControl(ChildControl), aAnchorStorage, StartingIndex); 
    end; 
end; 

procedure EnableAnchors_Core(ParentControl: TWinControl; aAnchorStorage: TAnchorsArray; var StartingIndex: Integer); 
var 
    iCounter: integer; 
    ChildControl: TControl; 
begin 
    for iCounter := 0 to ParentControl.ControlCount - 1 do 
    begin 
     ChildControl := ParentControl.Controls[iCounter]; 
     ChildControl.Anchors := aAnchorStorage[StartingIndex]; 

     Inc(StartingIndex); 
    end; 

    //Restore children 
    for iCounter := 0 to ParentControl.ControlCount - 1 do 
    begin 
     ChildControl := ParentControl.Controls[iCounter]; 
     if ChildControl is TWinControl then 
     EnableAnchors_Core(TWinControl(ChildControl), aAnchorStorage, StartingIndex); 
    end; 
end; 


end; 
+0

Tout ce hackery pour résoudre les problèmes de Borland. –

6

SuspendAnchors sonnent comme une méthode de base mais je n » t pense qu'il fait partie de la base langage Delphi :) Voici un code qui fait l'affaire:


var aAnchorStorage: Array of TAnchors; 
procedure AnchorsDisable(AForm: TForm); 
var 
    iCounter: integer; 
begin 
    SetLength(aAnchorStorage, AForm.ControlCount); 
    for iCounter := 0 to AForm.ControlCount - 1 do begin 
    aAnchorStorage[iCounter] := AForm.Controls[iCounter].Anchors; 
    AForm.Controls[iCounter].Anchors := []; 
    end; 
end; 

procedure AnchorsEnable(AForm: TForm); 
var 
    iCounter: integer; 
begin 
    SetLength(aAnchorStorage, AForm.ControlCount); 
    for iCounter := 0 to AForm.ControlCount - 1 do 
    AForm.Controls[iCounter].Anchors := aAnchorStorage[iCounter]; 
end; 

procedure TForm1.btnAnchorsDisableClick(Sender: TObject); 
begin 
    AnchorsDisable(Self); 
end; 

procedure TForm1.btnAnchorsEnableClick(Sender: TObject); 
begin 
    AnchorsEnable(Self); 
end; 

Profitez

+0

Je remplacerais la variable globale par des paramètres supplémentaires aux procédures, ou faire une sorte de carte entre la référence TForm et les ancres sauvegardées, mais à part ça c'est un +1. – mghie

+0

Oui - ce code doit être ajusté pour une utilisation en production. J'ai testé le code avec un formulaire simple et il fonctionne très bien en ce qui concerne la mise à l'échelle, en ajustant la taille et la largeur. –

+0

Il ne gère pas le contrôle imbriqué - c'est-à-dire TPanel, TTabSheet –

Questions connexes