2013-05-14 4 views
3

Я хочу создать приложение MDI с собственной панелью задач, чтобы пользователь мог быстро получить доступ к дочерним окнам, которые он хочет перенести на передний план. Тогда у меня возникла идея, что пользователь, который работает с двумя или более мониторами, может перетаскивать дочерние окна из основной формы моего приложения в другое место, например, на другой монитор.Как вытащить детское окно MDI из основной формы?

Как это сделать?

+1

То, что вы описываете, это не приложение MDI, так как я не верю, что MDI будет легко поддерживать то, что вам нужно. Скорее это приложение MDI, которое использует закрепляемые формы. Каноническим примером Delphi является сама Delphi IDE. Читайте о стыковке, и это должно быть довольно рутиной. –

+0

В Delphi IDE нет контейнера в качестве базы для этих закрепляемых элементов. MDI имеет основную форму со всем окном в качестве контейнера, в котором находится ребенок. Когда вы вытаскиваете один из них, он становится как основная форма. Так что я описываю? Может быть, третий материал? – PSyLoCKe

+0

Ну, вы можете просто создать основную форму и добавить свой собственный контейнер. –

ответ

4

Может быть, этот пример MDI форма код клиента служит источником вдохновения:

unit Unit3; 

interface 

uses 
    Windows, Messages, Controls, Forms; 

type 
    TForm3 = class(TForm) 
    private 
    FSizing: Boolean; 
    procedure WMNCMouseLeave(var Message: TMessage); 
     message WM_NCMOUSELEAVE; 
    procedure WMWindowPosChanged(var Message: TWMWindowPosChanged); 
     message WM_WINDOWPOSCHANGED; 
    protected 
    procedure CreateParams(var Params: TCreateParams); override; 
    procedure Resize; override; 
    end; 

implementation 

{$R *.dfm} 

{ TForm3 } 

var 
    FDragging: Boolean = False; 

procedure TForm3.CreateParams(var Params: TCreateParams); 
begin 
    inherited CreateParams(Params); 
    if FormStyle = fsNormal then 
    Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW 
    else 
    Params.ExStyle := Params.ExStyle and not WS_EX_APPWINDOW; 
end; 

procedure TForm3.Resize; 
begin 
    inherited Resize; 
    FSizing := True; 
end; 

procedure TForm3.WMNCMouseLeave(var Message: TMessage); 
begin 
    inherited; 
    FDragging := False; 
end; 

procedure TForm3.WMWindowPosChanged(var Message: TWMWindowPosChanged); 
var 
    P: TPoint; 
    F: TCustomForm; 
    R: TRect; 
begin 
    inherited; 
    if not FDragging and not FSizing and not (fsShowing in FormState) and 
    (WindowState = wsNormal) then 
    begin 
    F := Application.MainForm; 
    P := F.ScreenToClient(Mouse.CursorPos); 
    R := F.ClientRect; 
    InflateRect(R, -5, -5); 
    if not PtInRect(R, P) and (FormStyle = fsMDIChild) then 
    begin 
     FDragging := True; 
     FormStyle := fsNormal; 
     Top := Top + F.Top; 
     Left := Left + F.Left; 
    end 
    else if PtInRect(R, P) and (FormStyle = fsNormal) then 
    begin 
     FDragging := True; 
     FormStyle := fsMDIChild; 
    end; 
    end; 
    FSizing := False; 
end; 

end. 
+0

Это очень забавно, это делает работу! Но я немного поработаю над этим, потому что, когда мы снимаем одного ребенка, все остальные выходят из основной формы, и когда мы нажимаем кнопку восстановления, они также отрываются. :-) – PSyLoCKe

+0

@EASI объявить FDragging как класс var и ваша проблема решена – iamjoosy

+0

@EASI Да, очевидно, WM_WINDOWPOSCHANGED отправляется ко всем другим формам ... См. Edit. – NGLN