質問: アプリケーションがフォーカスを盗むのを防ぐ アプリケーションがアクティブウィンドウからフォーカスを盗むのを防ぐための解決策はありますか?これは、私がアプリケーションを起動し、他のことを実行するように切り替えると、特に面倒です。新しいアプリケーションは、半文のテキストを受け取り始めます。
回答: これは、windowsの内部構造を広範囲に操作しなければ不可能であり、それを乗り越える必要があります。それはあなたがオペレーティングシステムがあなたが別のことをすることを可能にする前にあなたが1つの行動をとることが本当に重要であるとき日常的なコンピュータの使用に瞬間があります。そのためには、特定のウィンドウに焦点を絞る必要があります。 windowsでは、この動作の制御は、使用する個々のプログラムの開発者に大部分が任されています。このトピックに関しては、すべての開発者が正しい判断を下すわけではありません。私はこれが非常にイライラすることと迷惑であることを知っています、しかしあなたはあなたのケーキを持ってそれを食べることもできません。日常生活の中で、フォーカスが特定のui要素に移動したり、フォーカスがロックされたままであることを要求しているアプリケーションに問題がなくなったりしている場合は、おそらく多くの場合があります。しかし、たいていのアプリケーションは、現在誰が主導権を握っているかを判断することになるとやや同等であり、システムは決して完璧ではあり得ません。しばらく前に、私はこの問題を解決するための徹底的な調査を一度もしました(そして失敗しました)。私の研究の結果は 迷惑プロジェクトページ で見つけることができます。このプロジェクトには、次のことを繰り返してフォーカスを取得しようとするアプリケーションも含まれています。switch( message ) { case wm_timer: if( hwnd != null ) { // start off easy // setforegroundwindow will not move the window to the foreground, // but it will invoke flashwindow internally and, thus, show the // taskbar. setforegroundwindow( hwnd ); // our application is awesome! it must have your focus! setactivewindow( hwnd ); // flash that button! flashwindow( hwnd, true ); } break; このスニペットからわかるように、私の研究では、ユーザーインターフェイスの動作の他の側面にも焦点が当てられていませんでした。私がこれを解決しようとしたのは、すべての新しいプロセスにdllをロードし、別のウィンドウをアクティブにする原因となるapi呼び出しをフックすることでした。 最後の部分は簡単な部分です。素晴らしいapiがそこにライブラリをフックしているためです。私はとても素晴らしい mhookライブラリ を使いました。#include "stdafx.h" #include "mhook-2.2/mhook-lib/mhook.h" typedef ntstatus( winapi* pnt_query_system_information ) ( __in system_information_class systeminformationclass, __inout pvoid systeminformation, __in ulong systeminformationlength, __out_opt pulong returnlength ); // originals pnt_query_system_information originalflashwindow = (pnt_query_system_information)::getprocaddress( ::getmodulehandle( l"user32" ), "flashwindow" ); pnt_query_system_information originalflashwindowex = (pnt_query_system_information)::getprocaddress( ::getmodulehandle( l"user32" ), "flashwindowex" ); pnt_query_system_information originalsetforegroundwindow = (pnt_query_system_information)::getprocaddress( ::getmodulehandle( l"user32" ), "setforegroundwindow" ); // hooks bool winapi hookedflashwindow( __in hwnd hwnd, __in bool binvert ) { return 0; } bool winapi hookedflashwindowex( __in pflashwinfo pfwi ) { return 0; } bool winapi hookedsetforegroundwindow( __in hwnd hwnd ) { // pretend window was brought to foreground return 1; } bool apientry dllmain( hmodule hmodule, dword ul_reason_for_call, lpvoid lpreserved ) { switch( ul_reason_for_call ) { case dll_process_attach: mhook_sethook( (pvoid*)&originalflashwindow, hookedflashwindow ); mhook_sethook( (pvoid*)&originalflashwindowex, hookedflashwindowex ); mhook_sethook( (pvoid*)&originalsetforegroundwindow, hookedsetforegroundwindow ); break; case dll_process_detach: mhook_unhook( (pvoid*)&originalflashwindow ); mhook_unhook( (pvoid*)&originalflashwindowex ); mhook_unhook( (pvoid*)&originalsetforegroundwindow ); break; } return true; } 当時の私のテストでは、これはうまくいきました。すべての新しいプロセスにdllをロードする部分を除いて。ご想像のとおり、それは軽すぎることではありません。私は当時 appinit_dlls アプローチを使用しました(これは単に十分ではありません)。基本的に、これはうまくいきます。しかし、正しく新しいプロセスに自分のdllを挿入するようなものを書く時間がありませんでした。そしてこれに費やされた時間は、焦点を盗むことが私に引き起こす煩わしさを大いに覆い隠しています。dllインジェクションの問題に加えて、私がgoogle codeの実装でカバーしていなかったフォーカススチール方法もあります。同僚が実際にいくつかの追加の調査を行い、その方法をカバーしました。問題はsoで議論されました: https://stackoverflow.com/questions/7430864/windows-7-prevent-application-from-losing-focus