質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

1回答

2964閲覧

.Netでのローカルフックの仕方について

xail2222

総合スコア1508

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2022/02/20 06:54

前提・実現したいこと

VB.Netでローカルフックを行う処理をしたい。
現状のソースコードでは、グローバルフックになってしまう。

実際のプログラムは、ArcMapのアドインなのですが
とりあえず、今回の質問は普通のVB.Netのフォームアプリケーションに関しての質問となります。
(フォームアプリケーションで出来たら、その方法をArcMapのアドインでも試そうとしています。)

参考にしたのは
VB.NETでキーフック
ローカルフック
等です。

現状のソースコード

VB.Net

1Imports System.Runtime.InteropServices 2 3Public Class Form1 4 <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> 5 Public Overloads Shared Function SetWindowsHookEx _ 6 (ByVal idHook As Integer, ByVal HookProc As CallBack, 7 ByVal hInstance As IntPtr, ByVal wParam As UInteger) As Integer 8 End Function 9 <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> 10 Public Overloads Shared Function CallNextHookEx _ 11 (ByVal idHook As Integer, ByVal nCode As Integer, 12 ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer 13 End Function 14 15 Public Delegate Function CallBack( 16 ByVal nCode As Integer, 17 ByVal wParam As IntPtr, 18 ByVal lParam As IntPtr) As Integer 19 <StructLayout(LayoutKind.Sequential)> Public Structure KeyboardLLHookStruct 20 Public vkCode As Integer 21 Public scanCode As Integer 22 Public flags As Integer 23 Public time As Integer 24 Public dwExtraInfo As Integer 25 End Structure 26 27 Const WH_KEYBOARD_LL As Integer = 13 28 Const WM_KEYDOWN As Integer = &H100 29 30 Shared hHook As Integer = 0 31 Private hookproc As CallBack 32 33 34 Public Function KeybordHookProc( 35 ByVal nCode As Integer, 36 ByVal wParam As IntPtr, 37 ByVal lParam As IntPtr) As Integer 38 39 If (nCode < 0) Then 40 Return CallNextHookEx(hHook, nCode, wParam, lParam) 41 End If 42 43 Dim hookStruct As New KeyboardLLHookStruct() 44 hookStruct = CType(Marshal.PtrToStructure(lParam, hookStruct.GetType()), KeyboardLLHookStruct) 45 46 If wParam = New IntPtr(WM_KEYDOWN) Then 47 MsgBox(hookStruct.vkCode) 48 49 Return 0 50 End If 51 Return CallNextHookEx(hHook, nCode, wParam, lParam) 52 End Function 53 54 55 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 56 hookproc = AddressOf KeybordHookProc 57 hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookproc, Nothing, 0) 58 If hHook.Equals(0) Then 59 MsgBox("SetWindowsHookEx Failed") 60 End If 61 62 End Sub 63End Class

起こっている問題と試した事

現状のソースコードでは、ローカルフックにならずグローバルフックになってしまっています。
また、二番目のリンクに書いてあった「第4引数にカレントのスレッドIDを指定する必要があるみたいです。 」ということかな?と思い
C# でスレッド ID を取得する
を参考にして

VB.Net

1hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookproc, Nothing, System.Threading.Thread.CurrentThread.ManagedThreadId)

としてみるとSetWindowsHookExが失敗します。(SetWindowsHookEx Failedが表示される)

どうすればローカルフックが出来るのでしょうか。

補足情報(FW/ツールのバージョンなど)

.Net Framework 4.6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

「SetWindowsHookExW function (winuser.h)」
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexw

の中盤あたりに、各フックでサポートされる範囲が書いてあります。
WH_KEYBOARD_LL は Global only です。

スレッドに対してフックをかける場合は、GetCurrentThreadId で取得した値を使ってください。

「GetCurrentThreadId function (processthreadsapi.h)」
https://docs.microsoft.com/ja-jp/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentthreadid

投稿2022/02/20 12:55

編集2022/02/20 12:58
KOZ6.0

総合スコア2707

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xail2222

2022/02/20 15:11 編集

なるほど。Global onlyですか。見逃していました。 だからどうやっても出来なかったのですね。 WH_KEYBOARDの方はどちらも出来ると書いてあるので試してみます。
xail2222

2022/02/20 16:10 編集

KeybordHookProcが呼び出されるときのパラメータの内容が変わりましたが WH_KEYBOARDにすることでとりあえずフォームアプリケーションで目的の事を達することが出来ました。 Arcmapのアドインの方に実装もしてみましたが、少し手を入れて目的の機能を実現出来ました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問