Получение ссылки на форму диалогового окна (ShowMessage, MsgDialog и т. Д.) - PullRequest
5 голосов
/ 09 марта 2012

Могу ли я использовать какое-либо событие, чтобы я уловил момент, когда на экране появляется ShowMessage?Мне также нужно передать ссылку на TForm, который показал сообщение.

До сих пор я пытался OnDeactivate, но, похоже, ShowMessage не вызывает его ...

В .NET есть метод на Application, который перехватывает каждый MessageBox (Application.AddFilterMessage или что-то вроде этого), мне нужно что-то вроде этого в delphi

Что я пытаюсь достичьis: Я должен уловить момент, когда появляется диалоговое окно (или просто модальное окно, но это не так удобно).Мне нужно сделать пару инструкций тогда.Цель этих инструкций - дать мне ссылку на только что полученное DialogWindow, чтобы я мог, например, получить несколько кнопок, которые на нем лежат.

Ответы [ 4 ]

6 голосов
/ 09 марта 2012

В современных версиях Delphi, в современных версиях Windows, ShowMessage приводит к диалоговому окну Windows.Вы можете использовать WH_CBT ловушку, чтобы поймать активацию этого диалогового окна.

function CBTProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  wnd: HWND;
  ClassName: string;
begin
  if nCode=HCBT_ACTIVATE then
  begin
    wnd := wParam;
    SetLength(ClassName, 256);
    SetLength(ClassName, GetClassName(wnd, PChar(ClassName), Length(ClassName)));
    if (ClassName='#32770') or (ClassName='TMessageForm') then
      Beep;
  end;
  Result := CallNextHookEx(0, nCode, wParam, lParam);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Hook: HHOOK;
begin
  Hook := SetWindowsHookEx(WH_CBT, CBTProc, HInstance, GetCurrentThreadId);
  if Hook=0 then
    RaiseLastOSError;
  try
    ShowMessage('hello');
  finally
    if not UnhookWindowsHookEx(Hook) then
      RaiseLastOSError;
  end;
end;

Обратите внимание, что фактическое имя класса окна варьируется от системы к системе.В XP имя класса будет TMessageForm, потому что диалог на самом деле является Delphi TForm.Однако в Vista и более поздних версиях это диалоговое окно стандартного окна сообщения с именем класса окна #32770.

Я показал, что это обернуто вокруг одного вызова ShowMessage, но вы можете установить его по адресупри запуске, если вы хотите подключить все диалоговые окна сообщений, показанные в вашем приложении.

5 голосов
/ 09 марта 2012

Вы также можете использовать хук всего приложения, установленный в событии OnCreate основной формы (удален в OnDestroy):

procedure TMainForm.FormCreate(Sender: TObject);
begin
  ...
  Application.HookMainWindow(ApplicationHook);
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  ...
  Application.UnhookMainWindow(ApplicationHook);
end;

function TMainForm.ApplicationHook(var Message: TMessage): Boolean;
var
  I: Integer;
begin
  Result := False;
  if (Message.Msg = WM_ENABLE) and not TWMEnable(Message).Enabled then // disabling
    for I := 0 to Screen.FormCount - 1 do
      with Screen.Forms[I] do
        if Enabled and (ClassNameIs('TMessageForm') or // ShowMessage, MessageDlg
          ClassNameIs('TForm') or // InputQuery
          ClassNameIs('TMyLoginDialog')) then // your own dialogs, etc.
        begin
          Screen.Forms[I].Position := poScreenCenter; // for example
          Result := True;
          Break;
        end;
end;
2 голосов
/ 10 марта 2012

Почему бы просто не использовать OnActiveFormChange?

procedure TForm3.FormCreate(Sender: TObject);
begin
  Screen.OnActiveFormChange := ScreenActiveFormChange;
end;

procedure TForm3.ScreenActiveFormChange(Sender: TObject);
begin
  if Screen.ActiveForm is TOKRightDlg then
    Screen.ActiveForm.Caption := 'Found';
end;

procedure TForm3.Button1Click(Sender: TObject);
begin
  with TOKRightDlg.Create(nil) do
  try
    ShowModal;
  finally
    Free;
  end;
end;
0 голосов
/ 09 марта 2012

Есть TApplication.OnModalBegin и TApplicationEvents.OnModalBegin .Я на самом деле не пробовал их, поэтому не могу комментировать, можете ли вы получить владельца и / или модальную форму внутри этих событий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...