Есть ли способ заставить отображать мнемоническую клавишу, не нажимая ALT?

Я работаю над приложением WinForms и хочу использовать ключ Mnemonics. Похоже, что из-за параметра Windows вы можете выбрать их отображение во время использования приложения только после нажатия клавиши ALT (эта опция по умолчанию). Я узнал об этой опции благодаря этому вопрос (кстати, связанный, но не дублирующийся).

Я изменил эту опцию, и подчеркивание мнемоники отображается правильно в начале. Но я бы хотел, чтобы пользователям не приходилось либо включать эту опцию, либо нажимать ALT, чтобы увидеть подчеркнутые клавиши.

Итак, мой вопрос: Есть ли в приложении принудительное подчеркивание мнемонической клавиши без изменения настроек или нажатия ALT?

Как правило, ответ на вопросы вида «Я хотел бы сделать что-то вопреки тому, что явно указано в параметрах, могу ли я» — либо «нет», либо «вы не должны», независимо от того, нравится вам это или нет. что делает Майкрософт. Решение о подчеркивании ускорителей принимается на основе различные оконные сообщения. Теоретически элементы управления можно уговорить сделать это даже без соответствующего ввода пользователя; на практике это было бы сложно и подвержено ошибкам. Если вы не хотите использовать полный настраиваемый контроль, это, вероятно, проигранная битва.

Jeroen Mostert 15.02.2019 09:50

Пользователи «знают», если они знают об этих клавишах, что они нажимают клавишу ALT, чтобы увидеть их или изменить свои предпочтения. Почему вы пытаетесь обмануть ожидания пользователей?

Damien_The_Unbeliever 15.02.2019 09:53

@JeroenMostert Это было немного то, что я хотел, но я хотел проверить, есть ли способ. Думаю, я просто буду подражать нажатию ALT при создании формы, чтобы показать ее. Благодаря вам, чтобы подтвердить это. Дэмиен, потому что некоторые это знают, но те, кто не часто работает с такого рода приложениями и не очень хорошо разбирается в компьютерах, не знают.

Zoma 15.02.2019 09:56

Если вы попробуете что-то подобное, будьте готовы к большему количеству запутанных пользователей и, возможно, к поломке вещей. Например, если пользователь теперь нажимает клавишу Alt, а затем передумает и не нажимает клавишу быстрого доступа (или клавишу, которой на самом деле не существует), подчеркивание по-прежнему исчезнет и не будет до тех пор, пока снова не будет нажата клавиша Alt. Это предполагает, что ускорители продолжают работать в первую очередь и не прерываются нажатием клавиши Alt! Если вам нужна согласованность этого внутри вашего рабочего места, правильным решением будет групповая политика, а не попытка решить ее на уровне приложения.

Jeroen Mostert 15.02.2019 10:01

Кроме того, очевидно (?) и для полноты - наличие или отсутствие сочетаний клавиш никогда не должно иметь решающего значения для вашего приложения. Если они должны отображаться, потому что в противном случае пользователям было бы трудно или невозможно получить доступ к чему-либо, вы определенно делаете это неправильно.

Jeroen Mostert 15.02.2019 10:02

@JeroenMostert Я не знаю, моя ли это версия WinForms, но та, которую вы нажали, подчеркнула ALT, осталась, даже если снова нажать ALT. Так что на тот момент это не было бы проблемой. И тот факт, что я хочу, чтобы они появлялись в начале, это потому, что моему начальнику нравятся ярлыки, и я предполагаю, что она захочет использовать их как можно скорее, и я предполагаю, что если ей нужно всегда нажимать ALT в каждой форме у нее кончится терпение. Чтобы в конечном итоге не вести расширенную дискуссию в комментариях, я просто пойду и спрошу ее, хорошо ли это, поскольку она почти единственная, кто использует ключи мнемоники.

Zoma 15.02.2019 10:03

Я никогда не пробовал какие-либо ключевые трюки с эмуляцией, поэтому я сказал «возможно». Поведение для нажатий клавиш действительный в моей Windows заключается в том, что подчеркивание появляется только в «режиме Alt». Но это включает в себя нажатие клавиши и отпускание; если вы имитируете только нажатие клавиши вниз, эффекты могут быть другими. Тем не менее, будьте готовы к потенциальным проблемам и тщательно протестируйте такие вещи, как открытие подменю и диалоговых окон. Если отображение подчеркиваний абсолютно необходимо для вашего приложения в некоторых сценариях, лучше использовать собственный подход — подчеркивания в метках не переключаются, меню не являются обязательными.

Jeroen Mostert 15.02.2019 10:07

(На самом деле, теперь, когда я это сказал, подчеркивания в метках все еще могут переключаться, если они подпадают под действие правил ускорителя. Давайте сделаем это более общим и скажем, что вы все еще можете использовать текст рисовать с подчеркиванием, игнорируя настройку. :-))

Jeroen Mostert 15.02.2019 10:09

Почему бы не отправить клавишу alt? Вы пробовали protected override void OnShown(EventArgs e) { base.OnShown(e); SendKeys.Send("%"); };

Reza Aghaei 15.02.2019 11:41

@RezaAghaei Я на самом деле пытаюсь эмулировать ввод ALT, но это сложнее, чем я, SendKeys здесь не работают, поэтому я пытаюсь использовать keybd_event из user32.dll, но отправка ALT сама по себе вызывает некоторые проблемы, которые у меня есть решить, прежде чем использовать его правильно

Zoma 15.02.2019 14:40
SendKeys не работает?! Вы пробовали то, что я поделился?
Reza Aghaei 15.02.2019 14:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
11
864
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для MenuStrip вам нужно создать собственный рендерер, чтобы всегда отображать мнемоники независимо от того, нажата или не нажата клавиша Alt. Чтобы сделать это, унаследуйте от ToolStripProfessionalRenderer и переопределите его OnRenderItemText, удалив флаги NoPrefix и HidePrefix из e.TextFormat. Затем зарегистрируйте средство визуализации для ToolStripManager.Renderer.

Чтобы другие элементы управления отображали мнемонику, вы можете переопределить WndProc метод формы и обработать сообщение WM_UPDATEUIISTATE и установить WParam на комбинацию UISF_HIDEACCEL в качестве слова старшего порядка и UIS_CLEAR в качестве слов младшего порядка. Таким образом, все элементы управления будут иметь мнемоническое подчеркивание.

Пример

Просто скопируйте и вставьте следующий код в форму и запустите приложение. В форме будут отображаться подчеркивания для всех мнемоник без необходимости нажимать Alt:

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
const int WM_UPDATEUISTATE = 0x0128;
const int UISF_HIDEACCEL = 0x2;
const int UIS_CLEAR = 0x2;
protected override void OnShown(EventArgs e)
{
    base.OnShown(e);
    ToolStripManager.Renderer = new MyRenderer();
}
protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_UPDATEUISTATE)
        m.WParam = (IntPtr)((UISF_HIDEACCEL & 0x0000FFFF) | (UIS_CLEAR << 16));
    base.WndProc(ref m);
}
public class MyRenderer : ToolStripProfessionalRenderer
{
    protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
    {
        e.TextFormat &= ~TextFormatFlags.NoPrefix;
        e.TextFormat &= ~TextFormatFlags.HidePrefix;
        base.OnRenderItemText(e);
    }
}

Действительно хороший ответ, отлично работает, как мне нужно. Большое спасибо.

Zoma 25.02.2019 08:16

Другие вопросы по теме