Catch Delphi MDI Child свернуть событие, когда MDI дочерняя форма развернута

Мне нужна помощь, чтобы попытаться зафиксировать событие минимизации дочерней формы MDI, когда оно развернуто.

Я могу захватить события минимизации / восстановления / максимизации, когда форма не развернута при нажатии кнопок, обведенных красным на изображении ниже.

MDI Child

Я фиксирую вышеупомянутые события с помощью WMSysCommand:

procedure TMDIChildForm.WMSysCommand(var Msg: TWMSysCommand);
begin
  if Msg.CmdType = SC_MINIMIZE then
  begin
    //my code here
  end;
end;

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

Максимальный MDI Детский

Что бы я ни пытался, мне не удалось поймать эти события. Если бы кто-то мог указать мне правильное направление, это было бы очень признательно. Спасибо.

2 ответа

Решение

Работает нормально для меня, когда я пробую это:

type
  TMDIChildForm = class(TForm)
  private
    { Private declarations }
    procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
  public
    { Public declarations }
  end;

procedure TMDIChildForm.WMSysCommand(var Msg: TWMSysCommand);
begin
  inherited; // <-- ADD THIS!!
  if Msg.CmdType = SC_MINIMIZE then
  begin
    // code here
  end;
end;

WMSysCommand() захватить SC_MINIMIZE уведомление всякий раз, когда дочерний объект MDI минимизируется, независимо от того, был ли он ранее максимизирован или нет, как ожидалось.

Удостовериться TMDIChildForm.WMSysCommand() звонки inherited (как показано выше), чтобы передать WM_SYSCOMMAND сообщение обработчику по умолчанию, чтобы у Windows была возможность его обработать.

После дальнейших раскопок я столкнулся с проблемой. @ Реми, пожалуйста, смотрите ниже.

Я использую TActionMainMenuBar вместо TMainMenu в родительской форме MDI. TActionMainMenuBar обрабатывает нажатия кнопок минимизации / восстановления / максимизации иначе, чем в TMainMenu. Код ниже взят из файла Vcl.ActnMenus:

type  
  TInternalMDIAction = class(TWindowAction)
  private
    { Private declarations }
  public
    { Public declarations }
    procedure ExecuteTarget(Target: TObject); override;
  end;

procedure TInternalMDIAction.ExecuteTarget(Target: TObject);
begin
  case MDIAction of
    maActivate: SendMessage(GetParent(Form.Handle), WM_MDIACTIVATE, Form.Handle, 0);
    maClose: Form.Close;
    maRestore: SendMessage(GetParent(Form.Handle), WM_MDIRESTORE, Form.Handle, 0);
    maMinimize: ShowWindow(Form.Handle, SW_MINIMIZE);
  end;
end;

Я не могу поймать событие минимизации, потому что WMSysCommand никогда не вызывается ShowWindow. Я включил мое исправление ниже:

type  
  TInternalMDIAction = class(TWindowAction)
  private
    { Private declarations }
  public
    { Public declarations }
    procedure ExecuteTarget(Target: TObject); override;
  end;

procedure TInternalMDIAction.ExecuteTarget(Target: TObject);
begin
  case MDIAction of
    maActivate: SendMessage(GetParent(Form.Handle), WM_MDIACTIVATE, Form.Handle, 0);
    maClose: Form.Close;
    //maRestore: SendMessage(GetParent(Form.Handle), WM_MDIRESTORE, Form.Handle, 0);
    //maMinimize: ShowWindow(Form.Handle, SW_MINIMIZE);
    maRestore: SendMessage(Form.Handle, WM_SYSCOMMAND, SC_RESTORE, 0);
    maMinimize: SendMessage(Form.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
  end;
end;

Сейчас он работает так, как я ожидал. Если кто-то видит что-то, что я мог пропустить, или лучший способ исправить проблему, вызванную VCL TActionMainMenuBar, пожалуйста, дайте мне знать. Благодарю.

Другие вопросы по тегам