#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.