お世話になります。VC++初心者です。
フックにて、最終的にはどのアプリについても、
キーボードの入力ができないようにしたいのですが、
試作をローカルフックにて作成してみたところ、
[Alt]+[Tab]やウィンドウズキーやファンクションキーなどが無効になりません。
コードは以下のように作成しました。
BOOL CKeyboardHook::Set()
{
//フックをセット
m_hHook = ::SetWindowsHookEx( WH_KEYBOARD
, (HOOKPROC)CKeyboardHook::KeyboardProc, NULL, AfxGetApp()->m_nThreadID );
if( !m_hHook )
return FALSE;
return TRUE;
}
LRESULT CALLBACK CKeyboardHook::KeyboardProc(int p_nCode, WPARAM p_wParam,
LPARAM p_lParam)
{
//キー入力に対し、何もしない
if( p_nCode < 0 || p_nCode == HC_NOREMOVE )
return ::CallNextHookEx( m_hHook, p_nCode, p_wParam, p_lParam );
::CallNextHookEx( m_hHook, p_nCode, p_wParam, p_lParam );
return TRUE;
}
環境は、Windows2000 Visual C++ 6.0(SP5) です。
そもそも、このような方法は、
キーボードを無効化したい場合の案としては正しいのでしょうか?
何か他の案など、ございましたらご教授願います。
以上、よろしくお願い致します。
Win9x系列のみですが SystemParametersInfo() API関数の
SPI_SCREENSAVERRUNNING で Alt+Tab, Alt+Ctrl+Del が無効化できます。
WinNT系では、WH_KEYBOARD_LLを使うとより低レベルのキー操作をフックできます。
kuma様、dairygoods様、返信ありがとうございます。
dairygoods様のおっしゃるWH_KEYBOARD_LLをビルドしたところ、
error C2065: 'WH_KEYBOARD_LL' : 定義されていない識別子です。
とエラーになりました。
現在の環境(Win2Kですが)では、WH_KEYBOARD_LLは使用できないという事なのでしょうか?
//以下のように変更
m_hHook = ::SetWindowsHookEx( WH_KEYBOARD_LL
, (HOOKPROC)CKeyboardHook::KeyboardProc, NULL, AfxGetApp()->m_nThreadID );
とりあえず、kuma様のおっしゃるSPI_SCREENSAVERRUNNINGも使用してみます。
> 現在の環境(Win2Kですが)では、WH_KEYBOARD_LLは使用できないという事なのでしょ
うか?
普通コンパイルする環境とEXEを実行する環境は異なりますから、
自分の開発PCがWin2000だったら、
Win2000向けにコンパイルすると言ったことはなされません。
どんな環境で実行するEXEを作るつもりなのかを指示する必要があります。
(何も指示しなければ一番古い環境向けになるでしょう。)
定義はいろいろありますが、ターゲットがNT系であることを示す場合は、
(他のファイルをincludeするより前に)
#define _WIN32_WINNT 0x0400 // NT4.0の場合
などとします。
WINUSER.Hには次のように記載されていますが。
#if (_WIN32_WINNT >= 0x0400)
#define WH_KEYBOARD_LL 13
#define WH_MOUSE_LL 14
#endif // (_WIN32_WINNT >= 0x0400)
参考になりますでしょうか
dairygoods様、アイススケーター様、返信ありがとうございます。
試しに WINUSER.H の内容を次のように変更してみました。
//#if (_WIN32_WINNT >= 0x0400)
#define WH_KEYBOARD_LL 13
#define WH_MOUSE_LL 14
//#endif // (_WIN32_WINNT >= 0x0400)
すると、ビルドできた(WH_KEYBOARD_LLを認識してくれた?)のですが、
実際にキーボードの入力が無効になりませんでした…
ここのスレッドも最後には閉じてください。
VC++超初心者会議室 No.11208
→ http://www.mtakahashi.com/bbs.htm
> 試しに WINUSER.H の内容を次のように変更してみました。
そんなことしていいのですか?
dairygoodsさん、アイススケーターさんの話の流れからして、
#define _WIN32_WINNT 0x0400 // NT4.0の場合
#include <winuser.h>
とするべきだと思いますが…
WM_KEYBOARDとWH_KEYBOARD_LLのコールバックは同じではありませんよ。
>dairygoods様
p_lParamのレスはメッセージデータの構造体へのポインタという違いですよね?
LRESULT CALLBACK CKeyboardHook::KeyboardProc(int p_nCode, WPARAM p_wParam,
LPARAM p_lParam)
{
//キー入力に対し、何もしない
if( p_nCode < 0 || p_nCode == HC_ACTION )
return ::CallNextHookEx( m_hHook, p_nCode, p_wParam, p_lParam );
::CallNextHookEx( m_hHook, p_nCode, p_wParam, p_lParam );
return TRUE;
}
で良いのかと思いましたが…(WH_KEYBOARDとほぼ同じロジック)
具体的にどのようなロジックなのでしょうか?
>RiSK様
大変、失礼致しました。以後、気をつけます。
失礼。
コールバックで何も処理していないので、引数の違いは関係ないですね。
LRESULT CALLBACK CKeyboardHook::KeyboardProc(int p_nCode, WPARAM p_wParam,
LPARAM p_lParam)
{
if( p_nCode == HC_ACTION )
return TRUE;
return ::CallNextHookEx( m_hHook, p_nCode, p_wParam, p_lParam );
}
でよいのでは?
度々、申し訳ございません。
BOOL CKeyboardHook::Set()
{
//フックをセット
m_hHook = ::SetWindowsHookEx( WH_KEYBOARD_LL
, (HOOKPROC)CKeyboardHook::KeyboardProc, NULL, AfxGetApp()->m_nThreadID );
(以下、略)
}
にて、m_hHookが常にFALSEで返ってきてしまい、入力キーが出力されてしまいます。
KeyboardProcに何か不備があるのでしょうか?
GetLastErrorは何を返しますか?
WH_KEYBOARD_LLは、システムフックのみで使用できるようです。
ローカルフックでテストしていた為、エラーとなっていました。
(GetLastErrorにて判明)
おかげで、キーボードの無効化ができました。ありがとうございました。