Отправка WM_COMMAND в TMenuItem

В методе OnShow моей формы Delphi я определяю, что диалог должен открываться автоматически после открытия формы, и я должен быть в состоянии сделать это, имитируя щелчок по элементу меню.

Однако при вызове menuitem.Click открывается диалоговое окно до того, как открылась основная форма, а это не то, чего я хочу.

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

PostMessage(handle, WM_COMMAND, wparam, 0)

В документах MSDN WM_COMMAND говорится об идентификаторах IDM_*, но как это выглядит в Delphi?

6 ответов

Решение

Возможно, вы можете попытаться открыть диалог в событии OnActivate? Я не совсем уверен, что OnActivate будет запущен снова, кроме как при показе формы, но если это так, вы можете использовать:

procedure TForm1.FormActivate(Sender: TObject);
begin
  Form2.ShowModal;
  Self.OnActivate := nil;
end;

(Я знаю, что это очень старый вопрос, но, несмотря на то, что он каким-то образом решен, реальный вопрос действительно остался без ответа.)
-

Идентификатор элемента команды "TMenuItem" находится в Command имущество. Согласно документации WM_COMMAND старшее слово wParam будет равно 0, а младшее слово будет идентификатором меню;

PostMessage(Handle, WM_COMMAND, MakeWParam(MyMenuItem.Command, 0), 0);

или просто;

PostMessage(Handle, WM_COMMAND, MyMenuItem.Command, 0);


С элементом всплывающего меню будет небольшая разница: VCL обрабатывает сообщения всплывающих меню с помощью другого окна утилиты. Глобальная переменная PopupList имеет дескриптор Window имущество;

PostMessage(PopupList.Window, WM_COMMAND, MyPopupMenuItem.Command, 0);

Разве вам не нужно делать это с одноразовым таймером, если вы хотите, чтобы форма отображалась в соответствии с обычным Show/ShowModal, полностью прорисовывалась (и т. Д.), А затем немедленно делала что-то еще?

tmrKickOff: TTimer, интервал 100 мс, отключен во время разработки, 
запускает событие 'tmrKickOffTimer'.


в форме создания,
tmrKickOff.Enabled:= FALSE; // на случай, если что-то случилось в IDE

в форме показа, в конце всего остального;
tmrKickOff.Enabled:= True;

в tmrKickOffTimer
начать
  tmrKickOffTimer.Enabled:= FALSE;
  menuItemClick(ноль);
конец;

с извинениями за стиль, форму и любые сообщения об ошибках:-)

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

-Отметка

procedure WMPostStartup(var Message: TMessage); message WM_POSTSTARTUP;

procedure TMainForm.WMPostStartup(var Message: TMessage);
begin
  Self.Refresh;
  // Now show the dialog box.
end;

В качестве альтернативы, обработайте событие Application.OnIdle чем-то вроде...

if not DialogDone then
begin
    MyDialogForm.ShowModal; // or menuItem.Click ....
    DialogDone := true;
end;

OnIdle не будет запускаться (в первый раз), пока форма не отобразится и очередь сообщений не станет пустой.

Один из методов, который я использовал и который очень похож на решение MarkF, - это создание нового типа сообщения, определенного пользователем, и отправка себе сообщения с использованием этого типа, когда вы решите, что вам нужно выполнить этот другой процесс после отображения основной формы:

const
  wm_SpecialProc = wm_User + 1;

procedure TForm1.WMSpecialProc(var Message:tMessage); message wm_SpecialProc;
begin
  Form2.ShowModal;
end;

procedure TForm1.OnShow(Sender:tObject);
begin
  if true then
    PostMessage(Application.MainForm.Handle,wm_SpecialProc,0,0);
end;

Хорошая особенность этого метода заключается в том, что вы контролируете генерацию сообщений, поэтому можете заполнить ЛЮБОЙ lparam или wparam, который вы захотите позже использовать в своем обработчике. Я отправил сообщение напрямую через application.mainform, но вы также можете просто сказать, обрабатывать текущую форму.

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