Разница между щелчком по всплывающему меню и наведением курсора мыши

#delphi #contextmenu #delphi-2007

#delphi #contextmenu #delphi-2007

Вопрос:

При наведении курсора мыши на элемент меню с подменю, расширяющим подменю, запускается событие click.

Есть ли какая-либо разница между этим событием щелчка и тем, нажимает ли пользователь на самом деле?

Я использую TPopupMenu в качестве выпадающего свойства cxButton.

РЕДАКТИРОВАТЬ Delphi 2007

Комментарии:

1. и какую версию Delphi вы используете?

2. Из любопытства: почему вы хотите узнать так или иначе? Подменю должно расширяться в обоих случаях?

3. @Marjan — Я имитировал древовидную структуру с системой меню, где можно было выбирать не только конечные узлы, поэтому при наведении курсора на них нужно расширяться, но и «выделяться» при нажатии. Я думаю, что я просто переделаю графический интерфейс для этого экрана на что-то более разумное, теперь у меня есть этот ответ.

Ответ №1:

Не уверен, что это будет работать с D2007; это работает в D7. Можете ли вы попробовать следующее?

 type
  THackPopupList = class(TPopupList)
  private
    FActuallyClicked: Boolean;
  protected
    procedure WndProc(var Message: TMessage); override;
  public
    property ActuallyClicked: Boolean read FActuallyClicked;
  end;

{ THackPopupList }

procedure THackPopupList.WndProc(var Message: TMessage);
begin
  FActuallyClicked := Message.Msg = WM_COMMAND;
  inherited WndProc(Message);
end;

{ TForm1 }

procedure TForm1.MenuFileOpenClick(Sender: TObject);
var 
  ActuallyClicked: Boolean;
begin
  ActuallyClicked := THackPopupList(PopupList).ActuallyClicked;
  ...
end;

initialization
  PopupList.Free;
  PopupList := THackPopupList.Create;

end.
  

Объяснение: OnClick, который запускается при наведении курсора, инициируется WM_INITMENUPOPUPUP, но OnClick, который запускается щелчком мыши, инициируется этой WM_COMMAND .

Это зависит от того, что Menus.pas уже инициализирован. Но, как я понимаю из порядка инициализации модуля Delphi, это гарантировано, даже если вы поместите этот код во вспомогательный модуль.

Ответ №2:

Что ж, если пользователь действительно нажимает на меню с элементами подменю, событие OnClick не запускается. Таким образом, различие заключается в:

 procedure TForm1.MenuFileOpenClick(Sender: TObject);
var
  ActuallyClicked: Boolean;
begin
  ActuallyCLicked := TMenuItem(Sender).Count = 0;
end;
  

И если элемент меню имеет связанное действие:

 procedure TForm1.FileOpenExecute(Sender: TObject);
var
  ActuallyClicked: Boolean;
begin
  if Sender is TBasicAction then
    Sender := TBasicAction(Sender).ActionComponent;
  ActuallyCLicked := TMenuItem(Sender).Count = 0;
end;
  

Комментарии:

1. Если пользователь нажимает на элемент или наводит на него курсор; вызывается один и тот же TMenuItem.Click метод (и из этого метода OnClick запускается событие), поэтому они одинаковы. Как вы указали здесь, вы можете отличить, есть ли у пункта меню какой-либо подпункт, но вы не можете узнать, нажимает ли пользователь или просто наводит курсор.

2. Да, вы можете: если есть подменю, щелчок по пункту меню не приведет к событию OnClick. Если подменю нет, наведение курсора на пункт меню не приведет к событию OnClick.

3. Нет, вы не можете. Мы говорим о ситуации, когда у вас есть элемент с некоторыми подпунктами; и нет разницы между OnClick, выполняемым при наведении курсора мыши, или реальным щелчком. По крайней мере, в D2009.

4. Хорошо, тогда это поведение где-то изменилось после D7.

Ответ №3:

Нет, это не так. Если пользователь нажимает на элемент или наводит на него курсор, запускается то же самое событие OnClick.
Я проверил это для Delphi 2009.