2009-03-18 7 views
1

La position par défaut de TSaveDialog est le centre de l'écran. Comment définir la position de la fenêtre TSaveDialog? Je veux quelque chose comme ça:TSaveDialog position

SaveDialog1.top := topValue; 
SaveDialog1.left := leftValue; 
if (SaveDialog1.execute(self.handle)) then begin 
    ... 
end; 

Répondre

2

Je trouve échantillon pour cela à ce page, mais je l'ai modifié pour travailler avec la sortie TSaveDialog au lieu de créer de nouvelles classes.

type 
TSaveDialog = class(Dialogs.TSaveDialog) 
    protected 
     fTop: integer; 
     fLeft: integer; 
     procedure WndProc(var Message: TMessage); override; 
    public 
     property top: integer read fTop write fTop; 
     property left: integer read fLeft write fLeft; 
    end; 

type 
    TForm1 = class(TForm) 
    dlgSave1: TSaveDialog; 
    btn1: TButton; 
    procedure btn1Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 


var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 
uses 
    CommDlg; 

procedure TForm1.btn1Click(Sender: TObject); 
begin 
    dlgSave1.left := 20; 
    dlgSave1.top := 100; 
    if dlgSave1.Execute then 
    // do your work here 
end; 

{ TMySaveDialog } 

procedure TSaveDialog.WndProc(var Message: TMessage); 
begin 
    inherited WndProc(Message); 
    if (Message.Msg = WM_NOTIFY) then 
     case (POFNotify(Message.LParam)^.hdr.code) of 
      CDN_INITDONE: SetWindowPos(POFNotify(Message.LParam)^.hdr.hwndFrom, 0, fLeft, fTop, 0, 0, SWP_NOSIZE); 
     end; 
end; 
+0

était ma question sur cette page. Mais cette solution n'est pas complète. Parce que la position est définie une seule fois au début. Le deuxième ou le troisième réglage de la position a échoué. –

+0

Ne pas le régler * une fois * assez ??? –

+0

Je veux montrer le dialogue à chaque fois au centre du formulaire principal. Exemple de problème: l'utilisateur ferme la boîte de dialogue de sauvegarde, puis déplace le formulaire principal et ouvre à nouveau la boîte de dialogue de sauvegarde => à ce stade, je ne suis pas en mesure de déplacer la boîte de dialogue de sauvegarde au centre du formulaire principal. –

2

La fonction API GetSaveFileName, qui est ce que TSaveDialog est une forme d'emballage, ne fournit aucun moyen de contrôler la position de la boîte de dialogue, de sorte que vous devez intercepter un message au début de la boîte de dialogue et d'ajuster la position là, comme d'autres solutions que vous avez vu ont fait. Vous voulez que la boîte de dialogue soit centrée sur votre formulaire, donc les solutions qui fournissent les propriétés Top et Left pour la boîte de dialogue ne fonctionneront pas très bien car elles ne tiennent pas compte de la taille de la fenêtre et elles vous demandent également pour calculer de nouvelles coordonnées avant d'appeler Execute à chaque fois.

Voici une idée différente. Il faudra toujours passer outre WndProc.

type 
    TCenterSaveDialog = class(TSaveDialog) 
    private 
    FCenterForm: TCustomForm; 
    protected 
    procedure WndProc(var Message: TMessage); override; 
    public 
    // When this property is assigned, the dialog will center 
    // itself over the given form each time the dialog appears. 
    property CenterForm: TCustomForm read FCenterForm write FCenterForm; 
    end; 

procedure TCenterSaveDialog.WndProc(var Message: TMessage); 
var 
    lpOfNotify: POFNotify; 
    FormRect, DialogRect: TRect; 
    NewLeft, NewTop: Integer; 
begin 
    inherited; 
    if (Message.Msg = wm_Notify) and Assigned(CenterForm) then begin 
    lpOfNotify := POFNotify(Message.LParam); 
    if lpOfNotify.hdr.code = cdn_InitDone then begin 
     GetWindowRect(CenterForm.Handle, FormRect); 
     GetWindowRect(lpOfNotify.hdr.hwndFrom, DialogRect); 
     NewLeft := FormRect.Left 
     + (FormRect.Right - FormRect.Left) div 2 
     - (DialogRect.Right - DialogRect.Left) div 2; 
     NewTop := FormRect.Top 
     + (FormRect.Bottom - FormRect.Top) div 2 
     - (DialogRect.Bottom - DialogRect.Top) div 2; 
     SetWindowPos(lpOfNotify.hdr.hwndFrom, 0, 
     NewLeft, NewTop, 0, 0, 
     swp_NoActivate or swp_NoOwnerZOrder or swp_NoSize or swp_NoZOrder); 
    end; 
    end; 
end; 

Voir aussi: cdn_InitDone