Возникли проблемы с отображением и скрытием экранной клавиатуры Windows 10 (osk.exe) - PullRequest
0 голосов
/ 18 мая 2018

Я пытался заставить экранную клавиатуру (osk.exe) появляться (и исчезать) в Windows 10 из моего приложения.Мое приложение работало нормально в Windows 7. Вызов ShellExecute() на osk.exe показал бы клавиатуру там, но попытка получить такое же поведение в Windows 10 оказалась болезненной.

Попытка скрыть клавиатуру, как только она видна, я попробовал это:

HANDLE wHandle = FindWindowW(L"OSKMainClass", L"On-Screen Keyboard");
if (wHandle != NULL)
{
    long style = GetWindowLong(wHandle, GWL_STYLE);
    if (style & WS_VISIBLE)
    {
        return TRUE;
    }
    else
    {
        SetWindowLongPtr(wHandle, GWL_STYLE, WS_VISIBLE);
    }

, но это не имело никакого эффекта.

Я также попытался использовать клавиатуру TabTip но не смог определить, когда он виден (я могу определить, когда он не виден, но я не могу получить ручку, когда он виден!).

Любая помощь сэта проблема была бы оценена.

Обновление: Первоначально osk не отображалась по причине 'nCmdShow parameter supplied to ShellExecute`, исходный код предоставил значение NULL для этого значения, и он прекрасно работал в WindowsЯ решил, что проблема лежит в другом месте.изменение его с NULL на SW_SHOWNORMAL устранило проблему с появлением клавиатуры.

Комментарий Пола Сандерса: В 32-разрядном приложении вам нужно сделать еще одну вещь, см., см .: https://stackoverflow.com/a/50510526/5743288.

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

Вы делаете несколько ошибок:

  • в вашем, если вы используете задание вместо теста

  • в вашем SetWindowLongPtr Вы устанавливаете только один бит, и все существующие флаги теряются.Вы должны использовать:

       long style = GetWindowLong(wHandle, GWL_STYLE);
        if (style & WS_VISIBLE) // test
        {
            return TRUE;
        }
        else
        {
            style |= WS_VISIBLE; // set the bit
            SetWindowLongPtr(wHandle, GWL_STYLE, style); // set the new style
            ShowWindow(wHandle, SW_SHOWDEFAULT);
        }
    

Примечание. В документации Windows указано, что вы должны вызывать SetWindowPos, а не ShowWindow.

0 голосов
/ 19 мая 2018

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

Прежде всего, ответ на вопрос ОП: здесь .Это должно позволить ему делать именно то, что он хочет сделать.Слава @ zett42 за указание на трюк WM_SYSCOMMAND.Теперь об интересных вещах.

Вопрос 1: почему отправка сообщения WM_SYSCOMMAND в главное окно osk работает при вызове ShowWindow(), как пытался сделать ОП, не так ли?

Ответ: Ну, если оставить в стороне тот факт, что сокрытие OSK вместо того, чтобы закрывать или минимизировать его, вероятно, в любом случае не очень хорошая идея, ответ лежит в чем-то, что называется UI Privilege Level Isolation (UIPI).OSK работает с повышенными правами, и это ограничивает способы, которыми оно может управляться обычным приложением.Вы можете прочитать больше об UIPI здесь .

. Для дальнейшего использования вы можете выяснить, работает ли программа с повышенными правами, используя SysInternals ' Process Explorer .Если вы посмотрите на вкладку «Безопасность» окна «Свойства процесса», то для ОСК вы увидите:

Флаги: Группа целостности: Обязательная метка \ Высокая Обязательная метка

, в то время как для(например, в приложении «Настройки» вы видите:

Флаги: Целостность Группа: Обязательная метка \ Средняя Обязательная метка

Вопрос 2: Есть какие-либоНа это повлиял тот факт, что OSK является приложением UWP (см. комментарии @IInspectable ниже)?

Ответ: На самом деле нет.HWND верхнего уровня приложений UWP кажутся просто обычными HWND, хотя Microsoft не хочет, чтобы вы полагались на это .Вы можете исследовать точную иерархию окон, которую они используют - что там у нее есть - с помощью Spy ++ используйте 64-битную версию, lol ).

Кроме того:

  1. OP, пожалуйста, попробуйте написать лучшие вопросы .Этот был беспорядок, и это вызвало много проблем.Я отредактировал ваш вопрос в качестве примера, и, чтобы привести его в порядок для будущих посетителей, пожалуйста, посмотрите.И, пожалуйста, проголосуй за меня.Я заработал это.

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

0 голосов
/ 18 мая 2018

Вы можете использовать функцию IsWindowVisible из WinAPI, чтобы определить, является ли ваш hwnd видимым окном или нет.Вы пробовали это?Непосредственно проверять и управлять флагами для такой простой задачи - не лучшая идея

https://msdn.microsoft.com/en-us/library/windows/desktop/ms633530(v=vs.85).aspx

...