2013-09-03 2 views
5

Ребята, я хотел бы, чтобы кто-нибудь знал какое-либо событие или метод, который я мог бы перехватить, когда все формы MDI были закрыты.Событие, когда все формы mdi закрыты

Пример:

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

Благодарен, если кто-нибудь может помочь.

ответ

7

MDI дочерние формы (фактически любая форма), будучи уничтоженными, уведомит основную форму. Вы можете использовать этот механизм уведомления. Пример:

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! Лучше, чем моя. ;-) – NGLN

+0

@NGLN - Спасибо! Ваш более мощный, хотя, если вам нужно знать, когда ребенок делает это и то ... :) –

+1

NGLN, Sertac Akyus и Remy Lebeau. Спасибо за ваши ответы, все отлично. Ты очень хороший. Для этой ситуации лучшим кодом был Sertac Akyuz. Проще и решила моя проблема. NGLN и Remy, я сохранил ваш код для будущих ситуаций. Благодарю. – Delphiman

4

Поймать WM_MDIDESTROY сообщений клиентского окна 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

Вы можете иметь MainForm назначить обработчик события OnClose или OnDestroy для каждого MDI ребенка он создает. Каждый раз, когда клиент MDI закрывается/уничтожается, обработчик может проверить, все ли еще открыты дочерние формы MDI, а если нет, то делайте все, что ему нужно.

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; 

Или:

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;