Сочетания клавиш меню не отображаются (Delphi 2009)
-
07-07-2019 - |
Вопрос
Я старался изо всех сил и не могу понять, что здесь произошло.В Delphi 4 все работало нормально.После обновления до Delphi 2009 я не знаю, так ли это должно работать или это проблема:
Вот как выглядит меню моей программы в режиме дизайна в Delphi 2009:
Обратите внимание, что каждое слово в главном меню и подменю «Файл» подчеркнуто по одной букве.Это должно быть так.Эта подчеркнутая буква называется клавишей ускорения и является стандартной в приложениях Windows, поэтому вы можете использовать клавишу Alt и эту букву для быстрого выбора пункта меню, а затем элемента подменю с помощью клавиатуры, а не мыши.
Вы можете получить их таким образом, используя символ «&» в названии элемента, например:Сохранить как...
Когда я запускаю свое приложение и использую мышь, чтобы открыть меню «Файл», оно выглядит следующим образом:
Символы подчеркнуты в главном меню, но не подчеркнуты в меню «Файл».
Если вместо этого я использую клавишу Alt-F, чтобы открыть подменю «Файл», то это будет выглядеть правильно:
и все буквы клавиш акселератора правильно подчеркнуты.
Я поигрался с опцией AutoHotKeys, но проблема не в этом.
Кто-нибудь сталкивался с этой проблемой раньше?Является ли пример на втором изображении правильным поведением, о котором я не знаю?Или есть какой-то вариант или ошибка в кодировании, которую я мог пропустить?
Ноябрь 2009 г. (год спустя):mghie, похоже, докопался до сути и разобрался в проблеме.См. его принятый ответ ниже.
Решение
Существует стандартная настройка Windows (в свойствах дисплея), которая обычно скрывает эти ускорители, если не удерживать клавишу Alt.Это объясняет, почему открытие меню с помощью Alt+F10 показывает их вам.Может быть, в этом причина?
[РЕДАКТИРОВАТЬ]:Нет, это не так.Я только что попробовал, и простой TForm с элементом меню показывает ускоритель, но как только я добавляю TImageList и устанавливаю ImageIndex для одного пункта меню или просто устанавливаю для OwnerDraw значение true, подчеркивание ускорителя исчезает.Я думаю, это действительно ошибка в VCL.
Кстати, это на Windows XP.
Обходной путь:
Я отладил это с помощью Delphi 2009 в Windows XP 64, и основная причина отсутствия ускорителей, по-видимому, заключается в том, что Windows отправляет WM_DRAWITEM
сообщения с ODS_NOACCEL
установлен флаг, чего не должно быть, если система настроена на постоянное отображение ускорителей.Таким образом, можно сказать, что это не ошибка VCL, а проблема Windows, которую VCL не решает.
Однако вы можете обойти это в своем собственном коде, вам просто нужно сбросить флаг перед передачей сообщения в VCL.Переопределить оконный процесс
protected
procedure WndProc(var Message: TMessage); override;
вот так:
procedure TYourForm.WndProc(var Message: TMessage);
const
ODS_NOACCEL = $100;
var
pDIS: PDrawItemStruct;
ShowAccel: BOOL;
begin
if (Message.Msg = WM_DRAWITEM) then begin
pDIS := PDrawItemStruct(Message.LParam);
if (pDIS^.CtlType = ODT_MENU)
and SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, @ShowAccel, 0)
then begin
if ShowAccel then
pDIS^.itemState := pDIS^.itemState and not ODS_NOACCEL;
end;
end;
inherited;
end;
Это только демонстрационный код, вам не следует вызывать SystemParametersInfo()
каждый раз, когда WM_DRAWITEM
сообщение получено, но один раз при запуске программы, а затем каждый раз, когда ваша программа получает WM_SETTINGCHANGE
сообщение.
Другие советы
Это " функция " познакомился с Windows 2000:
Старая новая вещь: Почему Windows скрывает ускорители клавиатуры и сфокусировать прямоугольники по умолчанию?
Похоже, что Delphi 4 не поддерживает эту функцию Windows. Р>
Чтобы в меню 2000 и XP отображались клавиши ускорения, щелкните правой кнопкой мыши пустое место на рабочем столе, выберите «Свойства», перейдите на вкладку «Внешний вид» и в разделе «Эффекты» снимите флажок Скрыть подчеркнутые буквы для навигации по клавиатуре, пока я не нажму Alt. Клавиша . Дважды нажмите кнопку ОК.
Не уверен, как это сделать в Vista.
Я не думаю, что это ошибка, сгенерированная Delphi, поскольку у вас такое же поведение в Notepad на Vista. Кроме того, в самой Delphi Кстати ...
Должен признаться, что я не обратил внимания на ваш вопрос. Спасибо за указание на это.
Как отметил Джим Маккит выше (правильно), это «по замыслу» поведение. Если меню запускаются с помощью клавиатуры, должны быть показаны ускорители, но если они вызваны мышью, ускорители преднамеренно не отображаются. Р>
Мой XP настроен на постоянное отображение ускорителей, но быстрый тест с измененным параметром подтверждает, что меню также не должны отображать подчеркивания (Visual Studio ответила, как я и ожидал, при использовании мыши никаких подчеркиваний не было). Однако Microsoft Office игнорирует этот параметр и всегда показывает подчеркивание. Таким образом, это похоже на ошибку в том, как меню нарисованы в Delphi (у меня самого нет никакого опыта с Delphi). Р>
Я также нашел вариант для Vista: http://www.vistax64.com/vista-general/42125-always-show-menu-underline-keyboard-accelerators.html
Вы можете включить это в новом Центре Простоты Доступа (перейдите в Контроль На панели выберите «Удобство доступа», затем нажмите «Центр доступа»). В Центр легкости доступа, нажмите «Сделать клавиатуру проще в использовании» и в самом низу выберите сочетания клавиш Подчеркнуть и откройте флажок ключей.
Во время дальнейших исследований я обнаружил эту ошибку на форумах Delphi: http: //qc.codegear.com/wc/qcmain.aspx?d=37403
Похоже, что в вашем случае дочерние окна (нарисованные меню) не получают или не обрабатывают сообщение WM_UIUPDATESTATE из родительского окна, что и вызывает перерисовку с помощью ускорителей.