Клавиши ускорения меню не отображаются (Delphi 2009) - PullRequest
8 голосов
/ 11 ноября 2008

Я старался изо всех сил и не могу понять, что здесь произошло. В Delphi 4 все работало нормально. После обновления до Delphi 2009 я не знаю, так ли это должно работать, или это проблема:

Вот как выглядит меню моей программы в режиме разработки под Delphi 2009:

enter image description here

Обратите внимание, что каждое слово в главном меню и подменю «Файл» имеет одну подчеркнутую букву. Это должно быть так. Эта подчеркнутая буква называется клавишей ускорения и является стандартной в приложениях Windows, поэтому вы можете использовать клавишу Alt и эту букву для быстрого выбора элемента меню, а затем элемента подменю с помощью клавиатуры, а не мыши.

Вы получаете их таким образом, используя символ "&" как часть заголовка элемента, например: Сохранить и как ...

Когда я запускаю свое приложение и открываю меню Файл с помощью мыши, оно выглядит следующим образом:

enter image description here

Символы подчеркнуты в главном меню, но не подчеркнуты в меню Файл.

Если вместо этого я использую клавишу Alt-F, чтобы открыть подменю «Файл», то это выглядит так:

enter image description here

и все буквы клавиш акселератора правильно подчеркнуты.

Я играл с опцией AutoHotKeys, но это не проблема.

Кто-нибудь сталкивался с этой проблемой раньше? Является ли пример на втором изображении правильным поведением, о котором я не знаю? Или есть какая-то опция или ошибка кодирования, которую я мог пропустить?


ноябрь 2009 (год спустя): похоже, что mghie дошёл до сути и выяснил проблему. См. Его принятый ответ ниже.

Ответы [ 4 ]

7 голосов
/ 11 ноября 2008

Существует стандартная настройка 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. Переопределить окно proc

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.

6 голосов
/ 11 ноября 2008

Это «функция», представленная в Windows 2000:

Старая новая вещь: Почему Windows по умолчанию скрывает клавиатурные ускорители и фокусирует прямоугольники?

Похоже, что Delphi 4 не поддерживает эту функцию Windows.

Чтобы в меню 2000 и XP отображались клавиши ускорения, щелкните правой кнопкой мыши пустое место на рабочем столе, выберите «Свойства», перейдите на вкладку «Внешний вид» и в разделе «Эффекты» снимите флажок Скрыть подчеркнутые буквы для навигации по клавиатуре, пока я не нажму клавишу Key . Нажмите OK дважды.

Не уверен, как это сделать в Vista.

1 голос
/ 11 ноября 2008

Я не думаю, что это ошибка, сгенерированная Delphi, поскольку у вас такое же поведение с Notepad в Vista. Кроме того, в самой Delphi BTW ...
Должен признаться, что я не обратил внимания на ваш вопрос. Спасибо за указание на это.

0 голосов
/ 17 декабря 2008

Как отметил Джим Маккит выше (правильно), это поведение «по замыслу». Если меню запускаются с помощью клавиатуры, должны быть показаны ускорители, но если они вызваны мышью, ускорители преднамеренно не отображаются.

У меня есть XP, настроенная на постоянное отображение ускорителей, но быстрый тест с измененным параметром подтверждает, что меню также не должны показывать подчеркивания (Visual Studio реагировала, как я и ожидал, при использовании мыши не подчеркивает). Однако Microsoft Office игнорирует этот параметр и всегда показывает подчеркивание. Таким образом, это похоже на ошибку в том, как меню нарисованы в Delphi (у меня самого нет никакого опыта с Delphi).

Я также нашел вариант для Vista: http://www.vistax64.com/vista-general/42125-always-show-menu-underline-keyboard-accelerators.html

Вы можете включить это в новом Ease of Access Center (перейдите в Control На панели выберите «Удобство доступа», затем нажмите «Центр доступа»). В Центр легкости доступа, нажмите «Сделать клавиатуру проще в использовании» и в самом низу выберите сочетания клавиш Подчеркнуть и откройте флажок ключей.

Во время дальнейших исследований я обнаружил эту ошибку на форумах Delphi: http://qc.codegear.com/wc/qcmain.aspx?d=37403

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

...