2009-03-18 6 views
1

Die Standardposition von TSaveDialog ist die Bildschirmmitte. Wie setze ich die Position des TSaveDialog-Fensters? Ich möchte etwas wie folgt aus:TSaveDialog-Position

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

Antwort

2

Ich fand in diesem page für diese Probe, aber ich habe es geändert mit Verlassen TSaveDialog statt der Schaffung neuer Klasse zu arbeiten.

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

es meine Frage auf dieser Seite war. Aber diese Lösung ist nicht vollständig. Weil die Position am Anfang nur einmal festgelegt ist. Die zweite oder dritte Einstellung der Position ist fehlgeschlagen. –

+0

Einstellung nicht * einmal * genug ??? –

+0

Ich möchte den Dialog jedes Mal in der Mitte des Hauptformulars anzeigen. Beispiel des Problems: Der Benutzer schließt den Speicherdialog, dann das Hauptformular verschieben und dann den Speicherdialog wieder öffnen => an diesem Punkt kann ich den Speicherdialog nicht in die Mitte des Hauptformulars verschieben. –

2

Die GetSaveFileName API-Funktion, das ist, was TSaveDialog ein Wrapper Form ist, bietet keine Möglichkeit, die Position des Dialogfelds zu steuern, so dass Sie eine frühe Mitteilung an den Dialog müssen abzufangen und stellen Sie die Position, wie andere Lösungen, die Sie gesehen haben, getan haben.

Sie möchten, dass das Dialogfeld über Ihrem Formular zentriert wird. Lösungen, die die Eigenschaften Top und Left für den Dialog bereitstellen, funktionieren nicht sehr gut, da sie die Fenstergröße nicht berücksichtigen und auch Sie benötigen um neue Koordinaten zu berechnen, bevor Sie jedes Mal Execute anrufen.

Hier ist eine andere Idee. Es muss weiterhin überschrieben werden 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; 

Siehe auch: cdn_InitDone