私は win32 プログラミングの初心者であることを前置きします。
.dll を使用してグローバル キーボード フックを作成しています。キーボード フックの実際の設定と削除を処理するために、インストールとアンインストールの機能を追加しました。
#pragma comment(linker, "/SECTION:.SHARED,RWS")
#pragma data_seg(".SHARED")
static HHOOK hk=NULL;
//static CMyFile *pLF;
#pragma data_seg()
HINSTANCE hins = NULL;
__declspec( dllexport ) LRESULT Install(){
std::cout << "Installing" << std::endl;
hk = SetWindowsHookEx(WH_KEYBOARD_LL,EventAnalysis::KeystrokeAnalysis::KeyboardCallback,hins,0);
if(hk == NULL){
std::cout << "Hook creation failed! - " << GetLastError() << std::endl;
}
return 0;
}
__declspec(dllexport) BOOL CALLBACK UnInstall()
{
std::cout << "UnInstalling" << std::endl;
return UnhookWindowsHookEx(hk);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hins = (HINSTANCE) hModule;
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
.dll ができたので、ライブラリをロードしてフックをインストールする単純な実行可能ファイルを作成しました。
int _tmain(int argc, _TCHAR* argv[])
{
auto funHandle = LoadLibrary(L"C:\\Users\\tprodanov\\Documents\\visual studio 2010\\Projects\\HaveFun\\Release\\HaveFun.dll");
if(funHandle == NULL){
std::cout << "Library load failed! - " << GetLastError() << std::endl;
}
auto Install = (LRESULT(*)()) GetProcAddress(funHandle, "?Install@@YAJXZ");
if(Install == NULL){
std::cout << "Procedure load failed! - " << GetLastError() << std::endl;
}
Install();
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
auto Uninstall = (BOOL(*)()) GetProcAddress(funHandle, "?UnInstall@@YGHXZ");
if(Uninstall == NULL){
std::cout << "Procedure load failed! - " << GetLastError() << std::endl;
}
Uninstall();
return 0;
}
私が興味を持っているのは、私のプログラムの動作が現在の状態で期待どおりであることです (また、メッセージループの代わりに、ユーザーが [OK] をクリックするのを待つ MessageBox() をポップアウトした場合) ですが、そうではありませんstd::cin.get() または空の while ループを使用すると機能します。誰かがなぜこれが動作なのか説明できますか?
また、フォローアップの質問として、KeyboardCallback関数はコンソールに「キーが押されました」と出力するだけです。
LRESULT CALLBACK EventAnalysis::KeystrokeAnalysis::KeyboardCallback(int nCode, WPARAM wParam, LPARAM lParam){
std::cout << "Key pressed" << std::endl;
return CallNextHookEx(NULL,nCode,wParam,lParam);
}
これは、コンソール ウィンドウにフォーカスしているときにキーを押したときにのみ出力されると予想していましたが、メモ帳に入力しても、.dll のインストール機能を呼び出した実行可能ファイルに「キーが押されました」というメッセージが表示されます。私が理解している限り、動的ライブラリはすべてのプロセスで個別にロードされるため、これはわかりません。したがって、すべてのプロセスには KeyboardCallback 関数の独自のコピーがあり、フォアグラウンド ウィンドウのコンソールに出力しようとします。