Как программно управлять панелью ввода текста (TabTip.exe) в Windows Vista / 7

я адаптирую приложение для интерфейса сенсорного экрана, и мы хотим использовать панель ввода текста планшета, включенную в Windows Vista / 7, в частности его клавиатуру. Я хочу показать и скрыть его в соответствии с моим приложением. В основном я хочу!--0--> и HideKeyboard() функции. Как лучше всего это контролировать?

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

приложение написано на языке C++ / MFC.

любые указатели вообще очень ценятся.

2 ответов


я решил проблему. Оказывается, Spy++ действительно является лучшим другом программистов Windows.

во-первых, класс окна окна панели ввода оказывается "IPTip_Main_Window". Я использую это, чтобы получить дескриптор окна так:

HWND wKB = ::FindWindow(_TEXT("IPTip_Main_Window"), NULL);

оказывается, я могу просто публиковать те же сообщения WM_COMMAND, которые отправляет собственное меню. Большинство операций доступны из меню: док-станция сверху, док-станция снизу и поплавок. Код для отправки этих сообщений являются:

::PostMessage(wKB, WM_COMMAND, MAKEWPARAM(X,0) , 0);

где X 10021 для дна стыковки, 10023 для верхней части стыковки и 10020 для плавать. Значение 0 в верхнем слове означает, что сообщение отправляется из меню.

наконец, я хотел, чтобы иметь возможность показывать и скрывать панель ввода. Я заметил, что могу включить полосу стола, которая включает только одну кнопку для переключения видимости панели ввода. Spy++ing в сообщениях, опубликованных с этой кнопки, показал, что он отправляет глобальное зарегистрированное сообщение окна который называется "TabletInputPanelDeskBandClicked". Отправка этого сообщения на панель ввода заставляет его переключать видимость.

функция HideKeyboard () теперь выглядит так:

DWORD WM_DESKBAND_CLICKED =
    ::RegisterWindowMessage(_TEXT("TabletInputPanelDeskBandClicked"));

void HideKeyboard()
{
    HWND wKB = ::FindWindow(_TEXT("IPTip_Main_Window"), NULL);
    if(wKB != NULL && ::IsWindowVisible(wKB))
    {
        ::PostMessage(wKB, WM_DESKBAND_CLICKED, 0, 0);
    }
}

функция ShowWindow() реализована аналогично, но она также запустит клавиатуру, если она не запущена.

обновление:

похоже, что этот обмен сообщениями между процессами запрещен в Windows Vista / 7. При выполнении этой команды в режиме без повышенных процесс он потерпит неудачу с "access denied". Я предполагаю, что это вызвано защитой изоляции процессов пользовательского интерфейса (UIPI), найденной в Windows Vista/7. Поскольку панель ввода Tablet PC работает как дочерний процесс службы, она имеет более высокий уровень целостности, чем пользовательские программы, и поэтому не может быть отправлена никаких (или очень ограниченный набор) сообщений.

обновление:

получается, что панель ввода планшетного ПК действительно работает на высоком уровне целостности, а процессы начали с ограниченной учетной записью пользователя-средний уровень целостности.


Для Windows 8:

Примечание: как и решение Windows 7, это требует повышенного процесса.

панель ввода не является потомком HWND_DESKTOP. (Это, вероятно, какое-то окно метро.) Чтобы получить дескриптор окна, выполните серию горизонтальных разверток в сетчатом тестировании шаблона с помощью WindowFromPoint (). Для каждого теста проверьте класс window родительского окна, чтобы узнать, является ли он "IPTip_Main_Window".

Показать панель ввода, запуск "C:\Program Files\Common Files\microsoft shared\ink\tabtip.exe". Чтобы определить, находится ли он уже в закрепленном режиме, прочитайте раздел реестра:

HKEY_CURRENT_USER\Software\Microsoft\TabletTip.7\EdgeTargetDockedState

значение 0 указывает, что панель ввода находится в плавающем режиме. Если это так, отправьте следующее сообщение, чтобы переключить закрепленное состояние:

DWORD WM_DOCK_BUTTON_PRESSED = ::RegisterWindowMessage(_TEXT("IPTipDockButtonPressed"));
PostMessage(hwndInputPanel, WM_DOCK_BUTTON_PRESSED, 0, 0);

чтобы скрыть клавиатуру, разместите следующее:

PostMessage(hwndInputPanel, WM_SYSCOMMAND, SC_CLOSE, 0);