В программе, что мы написали прошлый раз, можно сделать небольшое улучшение.
Оно заключается в использовании последнего параметра метода IContextMenu.QueryContextMenu:
CMF_DEFAULTONLY
Этот флаг устанавливается, когда пользователь активирует действие по-умолчанию, обычно с помощью двойного щелчка мышью. Этот флаг подсказывает расширению меню ничего не добавлять, если оно не изменяет пункт меню по-умолчанию в меню. Например, расширители всплывающих меню или обработчики drag-and-drop не должны добавлять своих пунктов меню, если этот флаг включён. Расширитель пространства имён (namespace) должен добавлять в меню только пункт по-умолчанию (если таковой есть).
Как следует из этого текста из MSDN, этот флаг указывает реализации IContextMenu, что она должна волноваться только о команде по-умолчанию.
procedure TForm1.FormContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
var
pcm: IContextMenu;
Menu: HMENU;
Info: TCMInvokeCommandInfo;
Id: UINT;
begin
Handled := True;
if SUCCEEDED(GetUIObjectOfFile(Handle, 'C:\Windows\clock.avi', IID_IContextMenu, pcm)) then
try
Menu := CreatePopupMenu;
if Menu <> 0 then
try
if SUCCEEDED(pcm.QueryContextMenu(Menu, 0, SCRATCH_QCM_FIRST, SCRATCH_QCM_LAST, CMF_DEFAULTONLY)) then
begin
Id := GetMenuDefaultItem(Menu, 0, 0);
if Id <> UINT(-1) then
begin
FillChar(Info, SizeOf(Info), 0);
Info.cbSize := SizeOf(info);
Info.hwnd := Handle;
Info.lpVerb := MAKEINTRESOURCEA(Id - SCRATCH_QCM_FIRST);
SetLastError(pcm.InvokeCommand(Info));
if GetLastError <> 0 then
RaiseLastOSError;
end;
end;
finally
DestroyMenu(Menu);
end;
finally
pcm := nil;
end;
end;
С этим изменением на моей машине время выполнения вызова IContextMenu.QueryContextMenu сократилось со 100 мс до 50 мс. Выигрыш на вашей машине может быть иным. Это сильно зависит от того, сколько расширителей меню установлено на вашей машине и сколько из них действительно учитывают флаг CMF_DEFAULTONLY.
(И этот пример показывает, как важно людям, реализующим интерфейс IContextMenu, учитывать все флаги. Если ваш обработчик контекстого меню не учитывает флаг CMF_DEFAULTONLY, то вы будете частью этой проблемы).
Спасибо,
ОтветитьУдалитьСтатьи полезные. Запуск через команду по умолчанию устраивает (пока?).