1

概念的に単純なことをしたいのですが、キーボード入力を受け入れるすべてのコントロール(CEdit、編集可能なテキストを含むCComboboxなど)について、コントロールがフォーカスされて有効になっているときに、オンスクリーンキーボードを表示します。できれば、osk.exeユーティリティを直接呼び出すのではなく、アクセシビリティのサポート(Microsoftユーザーインターフェイスの自動化について読んだことがあります)を使用することをお勧めします。

ユーザーが編集可能なコントロールに焦点を合わせたときのタッチスクリーンスマートフォンに非常に似ています。

更新:オンスクリーンキーボードを私が説明したように動作させることができるWindowsオプションがある場合、それは問題ありません!

更新2:必要なものはhttp://msdn.microsoft.com/en-us/library/windows/apps/hh465404.aspxに似ていますが、Windows7にあります。

私はIUIAutomationクラスで実験を行い、編集可能なコントロールにフォーカスするときにosk.exeを直接呼び出し、編集不可能なコントロールにフォーカスするときにそのウィンドウを閉じました。

しかし、私にはまだ3つの問題があります。

1)CFileDialogアプリケーションを開くと応答しなくなります。同じことが、アプリケーションの別のモーダルダイアログでのみ発生します(他のすべてのモーダルダイアログでは、すべてが正常に機能します)。私は、CFileDialogがいくつかのバックグラウンドスレッドを開き、私の唯一の問題のあるモーダルも開くことを発見しました。これはスレッドの問題に関係していると思います。

2)他のコントロールにフォーカスがあり、その後、編集コントロールを選択せず​​に、CBS_DROPDOWNコンボボックスのドロップダウンボタンを直接クリックすると、OSKのフラッシュが表示されたり消えたりします。Spy++とUIAInspectを使用すると、コンボボックスがドロップ状態になる前に、テキスト編集がフォーカスされている疑いがありました。

3)SetWindowPos、MoveWindowでいくつかの実験を行った後

::MoveWindow(osk_wnd->m_hWnd, LeftOsk, TopOsk, -1, -1, FALSE);

または

osk_wnd->SetWindowPos(NULL, LeftOsk, TopOsk, -1, -1, SWP_NOSIZE | SWP_NOACTIVATE);

また、次のようなメッセージ処理実験も使用します

//osk_wnd is a CWnd* variable that represents OSK main window
osk_wnd->PostMessage(WM_SYSCOMMAND, SC_MOVE + HTCAPTION, MAKELPARAM(point.x, point.y));

または

POINT       point       = {0};

GetCursorPos(&point);
SendMessage(osk_wnd->m_hWnd, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));

SendMessage(osk_wnd->m_hWnd, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(LeftOsk, TopOsk));

GetCursorPos(&point);
SendMessage(osk_wnd->m_hWnd, WM_NCLBUTTONUP, HTCAPTION, MAKELPARAM(LeftOsk + point.x, TopOsk + point.y));

OSKウィンドウを移動できませんでした。私がそれを動かすことができることが重要です。そうしないと、フォーカスされたコントロールをカバーしているように見え、ユーザーはコントロールに与えている入力を見ることができません。補足:OSKウィンドウを最小化しないための次のコードは完全に機能しました:

if(osk_wnd->IsIconic())
    osk_wnd->PostMessage(WM_SYSCOMMAND, SC_RESTORE, NULL);

このAutoItスクリプトでそのウィンドウを動かそうとしても、何もしませんでした。

If WinActivate("[CLASS:OSKMainClass]") Then

   If WinWaitActive("[CLASS:OSKMainClass]") Then

      ConsoleWrite("activ" & @CRLF)

      Sleep(500)

      If WinMove("[CLASS:OSKMainClass]", "", 30 ,320,360,123) Then
         ConsoleWrite("move 1" & @CRLF)
      EndIf
   EndIf
EndIf

If WinMove("[CLASS:OSKMainClass]", "", 30 ,320,360,123) Then
   ConsoleWrite("move 2" & @CRLF)
EndIf

テキストが表示されます

アクティベート

移動1

移動2

印刷されていますが、OSKウィンドウはどこにも移動されていません。多分それは積極的に位置指示を拒否しています。

このAutoItスクリプトを試してTabtip.exeウィンドウを移動しようとしましたが、失敗します。このスクリプトを試して、Visual Studioコマンドプロンプトのウィンドウを移動すると、移動します。GRRRRR!

更新3:私には、これはユーザーアクセス制御とアクセス許可に関係しているようです。ユーザーアクセス制御を無効にするか、管理者としてアプリケーションを実行すると、MoveWindow命令は完全に機能します。同じことがOSKMainCLASSウィンドウを動かそうとしているAutoItにも当てはまります!それで、OSKアプリケーションに例外を設けることを許可するWindows 7のローカルまたはグループポリシーはありますか?

4)64ビットオペレーティングシステムでosk.exeを実行するために、SysWOW64リダイレクトを強制的に無効にしないすべてのことを試しましたが、それから逃れることはできませんでした。今まで問題はありませんでしたが、今後は次のコードで問題が発生する可能性があります。

const int sysDirNameSize= 1024;
TCHAR sysDir[sysDirNameSize];
if( !GetSystemDirectory( sysDir,  sysDirNameSize) )
{
    ASSERT(FALSE);
    return;
}

CString osk_path = CString(sysDir) + _T("\\osk.exe");
PVOID pOldValue = NULL;
BOOL bRes= Wow64DisableWow64FsRedirection(&pOldValue);
::ShellExecute(NULL, NULL, osk_path, _T("") , sysDir, SW_SHOW);
if(bRes)
    Wow64RevertWow64FsRedirection(pOldValue);

更新5:前回osk.exeを実行しようとしたときにプロセスが開始されたようですが、ウィンドウが表示されません。値をosk_wndに関連付けるために、CWnd :: GetDesktopWindow()のすべてのGW_CHILDウィンドウをトラバースして、GetClassName(...)が「OSKMainClass」で何も見つからないウィンドウを検索する関数があります。

4

2 に答える 2

0

もう一度、私は自分で問題を解決しました:)

1) http://social.msdn.microsoft.com/Forums/br/windowsaccessibilityandautomation/thread/aee0be4d-2cf5-45e7-8406-2de3e5d0af03およびhttp://www.c-plusplus.de/forum/285011-を読んだ後フル(ドイツ語ですが、Google翻訳者がお手伝いします)、私は関連するコードを別のスレッドに置くことにしました。CFileDialogウィンドウを開いたときにぶら下がることはもうありません:)

2)プロジェクトマネージャーは、これは小さな問題だと言いました:)

3)プロジェクトマネージャーにosk.exeを実行するときにセキュリティトークンを渡す必要があると言った後、彼は非常に単純なことのためにコードが非常に複雑になると答えました、そしてアプリケーションが管理者で実行できることが望ましいですモード:)

4)今まで問題を起こさなかったので、そうさせてください:)

とにかく、助けてくれてありがとう。

于 2013-02-08T13:29:46.143 に答える
-1

OSKウィンドウの移動用。最初に、コマンドプロンプトで低整合性をoskscreenに設定します。次に、movewindow関数を使用します。それはうまくいきません。

于 2017-09-11T10:39:18.890 に答える