VB6でプリントスクリーンを無効にする

このQ&Aのポイント
  • VB6でプリントスクリーンを無効にする機能を作成する方法を説明します。
  • ハンドルを使用してフックを正常に定義し、KeyBoardProcでプリントスクリーンキーを捕まえて戻り値を1に設定します。
  • しかし、クリップボードに画像が生成されてしまう問題が発生しています。画像が生成されないようにするためには、どのような設定が必要かを教えてください。
回答を見る
  • ベストアンサー

VB6でプリントスクリーンを無効にする

お世話になります VB6でプリントスクリーンを無効にする機能を作成しているのですが、 hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KeyBoardProc, 0&, App.ThreadID) フックはたぶん正常に定義できているようで、 KeyBoardProcでプリントスクリーンキーを捕まえて「44」でブレイクも脹れています。 ここで戻り値「1」を返しているのですが、クリップボードに画像が生成されてしまいます。 画像が生成されない様にするには、何が間違っているのかおしえていただけないでしょうか? '********************************************************************* ' フックプロシジャー '********************************************************************* Public Function KeyBoardProc(ByVal nCode As Integer, ByVal wParam As Long, ByVal lParam As Long) As Long Dim ret As Long If nCode < 0 Then KeyBoardProc = CallNextHookEx(hHook, nCode, wParam, lParam) Exit Function End If Select Case wParam ' Print Screen Case 44 KeyBoardProc = 1 Exit Function End Select KeyBoardProc = CallNextHookEx(hHook, nCode, wParam, lParam) End Function

質問者が選んだベストアンサー

  • ベストアンサー
  • ShowMeHow
  • ベストアンサー率28% (1424/5027)
回答No.1

これ(参照URLの一番上の回答)でできているけど、何が違うのか良くわかりません。 unhookを呼び出す際にclipboard.clearしても同じ状況でしょうか? Private Declare Function SetWindowsHookEx _ Lib "user32" Alias "SetWindowsHookExA" ( _ ByVal idHook As Long, _ ByVal lpfn As Long, _ ByVal hmod As Long, _ ByVal dwThreadId As Long) As Long Private Declare Function CallNextHookEx Lib "user32" ( _ ByVal hHook As Long, _ ByVal nCode As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long Private Declare Function UnhookWindowsHookEx Lib "user32" ( _ ByVal hHook As Long) As Long Private Declare Sub CopyMemory _ Lib "kernel32" Alias "RtlMoveMemory" ( _ pDest As Any, _ pSource As Any, _ ByVal cb As Long) Private Type KBDLLHOOKSTRUCT vkCode As Long scanCode As Long flags As Long time As Long dwExtraInfo As Long End Type Private Const HC_ACTION = 0 Private Const VK_SNAPSHOT = &H2C Private Const WH_KEYBOARD_LL = 13& Private hKeyb As Long Public Function KeybCallback(ByVal Code As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Static udtHook As KBDLLHOOKSTRUCT If (Code = HC_ACTION) Then 'Copy the keyboard data out of the lParam (which is a pointer) Call CopyMemory(udtHook, ByVal lParam, Len(udtHook)) If udtHook.vkCode = VK_SNAPSHOT Then KeybCallback = 1 Exit Function End If End If KeybCallback = CallNextHookEx(hKeyb, Code, wParam, lParam) End Function Public Sub HookKeyboard() UnhookKeyboard hKeyb = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf KeybCallback, App.hInstance, 0&) End Sub Public Sub UnhookKeyboard() If hKeyb <> 0 Then Call UnhookWindowsHookEx(hKeyb) hKeyb = 0 End If End Sub

参考URL:
http://www.vbforums.com/showthread.php?372390-RESOLVED-Turn-off-Print-Screen
usami33
質問者

お礼

回答ありがとうございました 本当はKeyそのものを受け付けない様にしたかったのですが clipboard.clearでも、目的を達成できたので、 採用させていただきました。

関連するQ&A

  • CallNextHookEx( ) == FALSE

    1つのアプリの中で、メインプロージャとフックプロージャを作りました。 フックはキーボードフックです。 HHOOK hHook; LRESULT CALLBACK MyHookProc(int nCode, WPARAM wParam, LPARAM lParam){  if(nCode < 0)return CallNextHookEx(hHook, nCode, wParam, lParam);  if(wParam == 0x31)return FALSE;  return TRUE; } フックしていても 「ぬ」 のキーは使えるようにしました。  if(wParam == 0x31)return FALSE; は  if(wParam == 0x31)return CallNextHookEx(hHook, nCode, wParam, lParam); にしても違いが分かりませんでした。 return FALSE では、メッセージをキューから削除らしいけど、メインの プロージャで LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){  switch(msg){  case WM_KEYDOWN:   if(wParam == 0x31)MessageBox(hWnd, "メインプロージャから", "", MB_OK);  break; にしても、フックプロージヤの戻り値は CallNextHookEx( ) でも FALSE でも MessageBox() は表示されました。 CallNextHookEx( ) にした場合と FALSE にした場合、何が違うのか、 どういうソースなら違いを確かめられるのか教えてください。

  • SetWindowsHookExで質問

    WindowsAPIの質問です。 hHook = SetWindowsHookEx( WH_CALLWNDPROCRET , (HOOKPROC)CallWndRetProc , hInsttance , 0 ) といった形で利用しています。 (hInsttance は自分自身。) CallWndRetProcですがMSDNでは nCode パラメータの値が 0 未満の場合、CallNextHookEx 関数を呼び出し、 nCode パラメータの値が 0 以上の場合も、CallNextHookEx 関数を呼び出し、その関数の戻り値を返すことを強く推奨します。 CallNextHookEx 関数を呼び出さない場合、0 を返すべきです。 http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpipc/html/_win32_callwndretproc.asp となっています。 しかし nCode == 0のとき、すなわちnCode == HC_ACTIONで CallNextHookExを呼び出すと、例外エラーがでた末、Windows自体が不安定になってしまいます。 nCode == HC_ACTIONのとき、return 0;にすれば問題はでないのですが なんだか気分的にスッキリしません。 ちなみに英語のドキュメントも読みましたがgreater than or equal to Zero となっており0を含むようでした。 LRESULT CALLBACK CallWndRetProc( int nCode, WPARAM wParam, LPARAM lParam ){ return CallNextHookEx( hHook, nCode , wParam , lParam ); } こんな感じで書くと強制終了してWindowsが不安定になってしまいます。

  • 64ビットエクセルでのAPI宣言/PtrSafe

    エクセルのInputboxで、入力された文字列を自動的にアスタリスクで隠すようにする方法を探し http://okwave.jp/qa/q2371878.html の回答No1のコードがまさに最適なコードで、これまで非常に助かっていました。 ところが、64bitのエクセルでは動かないことがわかりました。 表示されたエラーメッセージの言葉から調べて、PtrSafeという言葉を入れなければならないようなのでAPI宣言を以下のようにしてみました。 #If VBA7 And Win64 Then '64ビット版 Private Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _ ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _ (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, _ ByVal dwThreadId As Long) As Long Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long Private Declare PtrSafe Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" _ (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, _ ByVal lpClassName As String, _ ByVal nMaxCount As Long) As Long Private Declare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As Long #Else '32ビット版 Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _ ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _ (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, _ ByVal dwThreadId As Long) As Long Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" _ (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, _ ByVal lpClassName As String, _ ByVal nMaxCount As Long) As Long Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long #End If ところが、回答No1のコードで Sub Report_Open() を実行すると Public Function InputBoxDK(Prompt, Optional Title, Optional Default, Optional XPos, _ Optional YPos, Optional HelpFile, Optional Context) As String のところがハイライトされてエラーになります。 どう直せば良いのでしょうか? 全文のコードを乗せると字数制限に引っかかりますので、申し訳ありませんが宣言以外の部分は http://okwave.jp/qa/q2371878.html の回答No1のコードを見てくださいますようお願いします。

  • windows2000 フックについて

    教えてください。 Ctrl + Esc、Alt + Tab、 Alt + Escを使用不可にしたいと思いフックを使用し作成しています。 それをDLLにして、VBにて呼び出そうとしているのですが、うまくいきません。 まず、はじめにKeyboardProcを作成したのですが、KBDLLHOOKSTRUCTが宣言されていないとでます。 呼び出し関数とかあるのでしょうか? [環境] OS windows2000 VC++6.0 DLL化 [ソース] LRESULT CALLBACK KeyboardProc(int p_nCode, WPARAM p_wParam, LPARAM p_lParam) { KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam; //<--ここでエラーがでる。 BOOL bControlKeyDown = 0; if( p_nCode < 0 || p_nCode == HC_NOREMOVE ){ return CallNextHookEx( hHook, p_nCode, p_wParam, p_lParam ); } switch (p_nCode) { case HC_ACTION: { bControlKeyDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); if (pkbhs->vkCode == VK_ESCAPE && bControlKeyDown) return 1; if (pkbhs->vkCode == VK_TAB && pkbhs->flags & LLKHF_ALTDOWN) return 1; if (pkbhs->vkCode == VK_ESCAPE && pkbhs->flags & LLKHF_ALTDOWN) return 1; break; } default: break; } CallNextHookEx( hHook, p_nCode, p_wParam, p_lParam ); return TRUE; } EXPORT long __stdcall HookSet() { hHook = ::SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc, NULL, 0 ); return 1; } DLL化やフックについていろいろ調べたのですが、初めてのため、可笑しい個所があるかとは思いますが、すみませんが教えてください。よろしくお願いします。

  • VC++&グローバルフックについて質問です

    vc++2008,Windows Vistaの環境でプログラムを作成しています。 以下、aが押されたら、設定したhWndにWM_KEYDOWN,VK_LEFTのメッセージを送るプログラムのつもりで書きました。 http://www.shos.info/develop/cwin/tipswin.html#windows008 を参考にしています。 しかし、dllにしてWinMainで呼び出したのですが動作しません。 エラーも出ないのでなぜ動かないのかがわかりません。 このプログラムをちゃんと動かすにはどうしたらいいでしょうか。 どうかご指摘ください。よろしくお願いします。 //hook.h #ifdef HOOKAPI #else #define HOOKAPI extern "C" __declspec(dllimport) #endif HOOKAPI HINSTANCE _hInstance; HOOKAPI HHOOK _hHook; HOOKAPI HWND _hWnd; HOOKAPI BOOL Set(HWND hWnd); HOOKAPI void Reset(); //hook.cpp #include <windows.h> #define HOOKAPI extern "C" __declspec(dllexport) #include "hook.h" #pragma data_seg(".share") HHOOK _hHook = NULL; HWND _hWnd = NULL; HINSTANCE _hInstance; #pragma data_seg() #pragma comment(linker, "/section:.share,rws") LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) { /* ここでは 'A' が押されたら予め設定済みの _hWnd にメッセージを送る */ if (nCode >= 0 && nCode != HC_NOREMOVE && wParam == 'A') { PostMessage(_hWnd, WM_KEYDOWN, VK_LEFT, 0); CallNextHookEx(_hHook, nCode, wParam, lParam); return 1; } return CallNextHookEx(_hHook, nCode, wParam, lParam); } BOOL Set(HWND hWnd) { /* キーのフック */ _hHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)HookProc, _hInstance, 0); /* ここで hInstance は DLL のインスタンス ハンドル */ _hWnd = hWnd; return (_hHook != NULL); } void Reset() { if (_hHook != NULL) { UnhookWindowsHookEx(_hHook); _hHook = NULL; } }

  • グローバルフックについて

    VC++6.0でグローバルフック用のDLLを作っていて、どうしてもわからないので質問させていただきます。 フックの内容は、ウィンドウが最前面にあるかどうか常に監視したいので、状態が変わるメッセージをフックしています。 フック対象はとあるゲームなんですが、テストのためにメモ帳を対象にテストをしました。 まず、spy++でウィンドウの状態を変化させたときに送られてくるメッセージを調べた結果。 WM_ACTIVATEが送られてくるので、これをフックしてみたのですが、spy++だとバックグラウンドに行った時、フォアグラウンドに行った時、最小化したとき、最小化から復帰したときにWM_ACTIVATEが送られてくるんですが、いざフックしてみると最小化するときと最小化から復帰したときにしかフックが作動しません。 spy++ではWM_SETFOCUSも送られてくるようだったので、そちらも試してみたのですが、まったく反応がありません。 逆に、spy++では検知してくれないWM_SHOWWINDOWではバックグラウンドに行った時、フォアグラウンドに行った時、最小化したとき、最小化から復帰したとき、すべてに反応してくれました。 このWM_SHOWWINDOWをフックしたときのようになれば問題無いのですが、フック対象をメモ帳からとあるゲームにしたときに、バックグラウンドに行った時と最小化したときは反応してくれたものの、フォアグラウンドに行った時と最小化から復帰したときは反応してくれません。 それと、WM_SHOWWINDOWのメッセージをフックした時のwparamの値なんですが、ネットで調べてみると 表示されようとしているとき 1 非表示されようとしているとき 0 となっているはずなのですが、自分のをみてみると常に647で固定されています。 どなたか解決策をご教授お願いします。 LRESULT CALLBACK WndProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode < 0) { return CallNextHookEx(hHook, nCode, wParam, lParam); } else if (nCode == HC_ACTION) { MSG *lmsg; lmsg = (MSG *)lParam; switch (lmsg->message){ case WM_SHOWWINDOW: MessageBox(NULL,"showwindow","info",MB_OK | MB_TOPMOST); return CallNextHookEx(hHook, nCode, wParam, lParam); break; } } return CallNextHookEx(hHook, nCode, wParam, lParam); }

  • なぜhButton1ボタンからのWM_COMMANDはフックできてクライアントエリアのWM_RBUTTONDOWNはフックできないのでしょうか?

    #define STRLBUTTON TEXT("マウス左ボタンが押されました from mainProc") #define STRRBUTTON TEXT("マウス右ボタンが押されました from my_HookProc") #define STRCOMMAND TEXT("ボタンが押されました") HWND hButton1; LRESULT CALLBACK my_HookProc(int nCode, WPARAM wParam, LPARAM lParam) { CWPRETSTRUCT *pcwpRetStruct = (CWPRETSTRUCT *)lParam; HDC hDC; if(nCode==HC_ACTION) { hDC = GetDC(pcwpRetStruct->hwnd); switch(pcwpRetStruct->message) { case WM_COMMAND: TextOut(hDC, 10, 10, STRCOMMAND, strlen(STRCOMMAND)); break; case WM_RBUTTONDOWN: TextOut(hDC, 10, 10, STRRBUTTON, strlen(STRRBUTTON)); break; } ReleaseDC(pcwpRetStruct->hwnd, hDC); } return CallNextHookEx(NULL, nCode, wParam, lParam); } LRESULT CALLBACK mainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HHOOK hHook; HDC hDC; switch(uMsg) { case WM_DESTROY: UnhookWindowsHookEx(hHook); PostQuitMessage(0); return 0; case WM_CREATE: hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, my_HookProc, NULL, GetCurrentThreadId() ); if(!hHook) MessageBox(NULL, "hooking failed", NULL, MB_OK); hButton1 = CreateWindow( "BUTTON", "hButton1", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 40, 100, 20, hWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL ); return 0; case WM_LBUTTONDOWN: hDC = GetDC(hWnd); TextOut(hDC, 10, 10, STRLBUTTON, strlen(STRLBUTTON)); ReleaseDC(hWnd, hDC); return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }

  • マウスフックについて

    Dllにてマウスフックをして、左ボタンが押しあがったらWM_LBUTTONUPされたら メッセージを送信するというものです。 そのときに、マウスの位置はどこにあってもいいのです。 たとえば、自分のウインドウの中で左ボタンを押して、 デスクトップ上などで左ボタンがあがったらメッセージを送信するというようにしたいのですがうまくいきません。 以下がソースです。 よろしくお願いします。 #include <windows.h> #include "MouseHook.h" HINSTANCE hInst; HHOOK hHook; HWND hWnd; BOOL bHook; int WINAPI DllMain(HINSTANCE hInstance, DWORD fdReason, PVOID pvReserved) { hInst = hInstance; return TRUE; } EXPORT int SetMainHWND(HWND hMainWindow) { hWnd = hMainWindow; return 0; } EXPORT BOOL IsHooking() { if (bHook) return TRUE; else return FALSE; } EXPORT int MouseHookSet() { hHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHookProc,hInst, NULL); if (hHook == NULL) { return -1; } else { bHook = TRUE; return 0; } } EXPORT int MouseHookEnd() { if (UnhookWindowsHookEx(hHook) != 0) { bHook = FALSE; return 0; } else { return -1; } } EXPORT LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) { MOUSEHOOKSTRUCT *pmh; pmh = (MOUSEHOOKSTRUCT *)lParam; if (wParam == WM_LBUTTONUP) { SendMessage(hWnd,MOUSEHOOK_LBUTTONUP,0,0); } if (wParam == WM_NCLBUTTONUP) { SendMessage(hWnd,MOUSEHOOK_LBUTTONUP,0,0); } return CallNextHookEx(hHook,nCode,wParam,lParam); }

  • キーボードフックの使い道

    dll のソースの一部です。 LRESULT CALLBACK MyHookProc(int nCode, WPARAM wParam, LPARAM lParam) {  if ( wParam == 0x31 )処理;  return CallNextHookEx(hHook, nCode, wParam, lParam); } 処理の部分では、MessageBox( ) とか MessageBeep( ) ぐらいしか 使えません。 「ぬ」 のキーが押されたら、メインのウインドウのエディットボックスの 文字を書き替えたりしたいんだけど、キーボードフックのプロージャの 中では、文字列の書き替えをすると、アプリケーションが強制終了します。 メモリマップドファイル、グローバルメモリの書き替えもやってみたけど キーボードフックのプロージャの中からはできませんでした。 dll の中なのに、キーボードフックのプロージャの中では 自分自身を LoadLibrary( ) して、GetProcAddress( ) とかしないと メモリの書き換えとかができないんですか? キーボードフックのプロージャの良い活用法を教えてください。

  • vbaでmsgboxの位置を指定

    http://okwave.jp/qa/q5253604.html を参考に、http://homepage1.nifty.com/rucio/main/technique/MsgBox.htmをやってみたのですが うまくいきません。 検証はエクセル・アクセス2007で行いました。 ////////////////////////////////////////////////////////////////// Option Explicit Dim App As Object Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _ (ByVal idHook As Long, _ ByVal lpfn As Long, _ ByVal hmod As Long, _ ByVal dwThreadId As Long) As Long Private Declare Function UnhookWindowsHookEx Lib "user32" _ (ByVal hHook As Long) As Long Private Declare Function SetWindowPos Lib "user32" _ (ByVal hwnd As Long, _ ByVal hWndInsertAfter As Long, _ ByVal x As Long, _ ByVal y As Long, _ ByVal cx As Long, _ ByVal cy As Long, _ ByVal wFlags As Long) As Long Const WH_CBT = 5 Const HCBT_ACTIVATE = 5 Public Const SWP_NOSIZE = &H1 '「サイズを指定しない」オプション Public Const SWP_NOZORDER = &H4 '「Zオーダーを指定しない」オプション Public Const SWP_NOACTIVATE = &H10 Dim HookHandle As Long '元のCBTProcプロシージャへのハンドル Dim m_Left As Long 'メッセージボックスのX座標 Dim m_Top As Long 'メッセージボックスのY座標 Public Sub SetMsgBox(Left As Long, Top As Long) m_Left = Left m_Top = Top HookHandle = SetWindowsHookEx(WH_CBT, AddressOf CBTProc, App.Hinstance, App.ThreadID) End Sub Private Function CBTProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Dim Ret As Long If nCode = HCBT_ACTIVATE Then Ret = SetWindowPos(wParam, 0, m_Left, m_Top, 0, 0, SWP_NOSIZE Or SWP_NOZORDER Or SWP_NOACTIVATE) Ret = UnhookWindowsHookEx(HookHandle) End If CBTProc = Ret End Function ////////////////////////////////////////////////////////////////// を標準モジュールに貼りつけました。 Dim App As Objectについては、参考のページにはありませんでしたが エラーになるので勝手にObjectにしました。 そしてこのコードを書いた標準モジュールに Sub test() SetMsgBox 0, 0 MsgBox "この例では左上に表示されます。" End Sub を足しました。 そして実行すると、 HookHandle = SetWindowsHookEx(WH_CBT, AddressOf CBTProc, App.Hinstance, App.ThreadID) の部分で オブジェクト変数または With ブロック変数が設定されていません。(Error 91) になります。 VBAでの位置の指定方法を教えてください!!!

専門家に質問してみよう