2013-09-03 75 views
5

Các bạn, tôi muốn nếu có ai biết bất kỳ sự kiện hoặc phương pháp nào mà tôi có thể chặn khi tất cả các biểu mẫu MDI đã bị đóng.Sự kiện khi tất cả các biểu mẫu mdi được đóng

Ví dụ:

Tôi muốn thực hiện một sự kiện ở dạng chính của tôi ở đâu khi tôi đóng tất cả các dạng MDI, một sự kiện như vậy đã được kích hoạt.

Biết ơn nếu có ai có thể giúp đỡ.

Trả lời

7

Biểu mẫu con MDI (trên thực tế bất kỳ biểu mẫu nào), trong khi bị hủy, sẽ thông báo cho biểu mẫu chính. Bạn có thể sử dụng cơ chế thông báo này. Ví dụ:

type 
    TForm1 = class(TForm) 
    .. 
    protected 
    procedure Notification(AComponent: TComponent; Operation: TOperation); 
     override; 

    .. 

procedure TForm1.Notification(AComponent: TComponent; Operation: TOperation); 
begin 
    inherited; 
    if (Operation = opRemove) and (AComponent is TForm) and 
     (TForm(AComponent).FormStyle = fsMDIChild) and 
     (MDIChildCount = 0) then begin 

    // do work 

    end; 
end; 
+0

+1 Nice! Tốt hơn tôi. ;-) – NGLN

+0

@NGLN - Cảm ơn! Của bạn là mạnh mẽ hơn mặc dù, trong trường hợp bạn cần phải biết khi một đứa trẻ làm điều này và rằng ... :) –

+1

NGLN, Sertac Akyus và Remy Lebeau. Cảm ơn câu trả lời của bạn, tất cả đều tuyệt vời. Bạn rất tốt. Đối với tình huống này, mã tốt nhất là Sertac Akyuz. Đơn giản hơn và giải quyết được vấn đề của tôi. NGLN và Remy, tôi đã lưu mã của bạn cho các tình huống trong tương lai. Cảm ơn. – Delphiman

4

Săn nhắn WM_MDIDESTROY gửi đến cửa sổ client MDI:

type 
    TForm1 = class(TForm) 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    private 
    FOldClientWndProc: TFarProc; 
    procedure NewClientWndProc(var Message: TMessage); 
    end; 

... 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    if FormStyle = fsMDIForm then 
    begin 
    HandleNeeded; 
    FOldClientWndProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC)); 
    SetWindowLong(ClientHandle, GWL_WNDPROC, 
     Integer(MakeObjectInstance(NewClientWndProc))); 
    end; 
end; 

procedure TForm1.FormDestroy(Sender: TObject); 
begin 
    SetWindowLong(ClientHandle, GWL_WNDPROC, Integer(FOldClientWndProc)); 
end; 

procedure TForm1.NewClientWndProc(var Message: TMessage); 
begin 
    if Message.Msg = WM_MDIDESTROY then 
    if MDIChildCount = 1 then 
     // do work 
    with Message do 
    Result := CallWindowProc(FOldClientWndProc, ClientHandle, Msg, WParam, 
     LParam); 
end; 
2

Bạn có thể có MainForm gán một event handler OnClose hoặc OnDestroy để mỗi đứa trẻ MDI nó tạo ra. Mỗi khi một máy khách MDI được đóng/hủy, trình xử lý có thể kiểm tra xem có bất kỳ biểu mẫu con MDI nào khác vẫn đang mở, và nếu không thì làm bất cứ điều gì cần làm.

procedure TMainForm.ChildClosed(Sender: TObject; var Action: TCloseAction); 
begin 
    Action := caFree; 

    // the child being closed is still in the MDIChild list as it has not been freed yet... 
    if MDIChildCount = 1 then 
    begin 
    // do work 
    end; 
end; 

Hoặc:

const 
    APPWM_CHECK_MDI_CHILDREN = WM_APP + 1; 

procedure TMainForm.ChildDestroyed(Sender: TObject); 
begin 
    PostMessage(Handle, APPWM_CHECK_MDI_CHILDREN, 0, 0); 
end; 

procedure TMainForm.WndProc(var Message: TMessage); 
begin 
    if Message.Msg = APPWM_CHECK_MDI_CHILDREN then 
    begin 
    if MDIChildCount = 0 then 
    begin 
     // do work 
    end; 
    Exit; 
    end; 
    inherited; 
end;