Вопрос

Я старался изо всех сил и не могу понять, что здесь произошло.В 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, похоже, докопался до сути и разобрался в проблеме.См. его принятый ответ ниже.

Это было полезно?

Решение

Существует стандартная настройка 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 из родительского окна, что и вызывает перерисовку с помощью ускорителей.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top