プロが教えるわが家の防犯対策術!

VB6で、アクティブでない(フォーカスのない)コントロールの上に
マウスポインタを持ってきて、ホイールが効くようにしようとしてます。
ネットで検索したところ、NYWheelなるものが以下のサイトに、
フリーで、しかもソース付でありました。
http://park1.wakwak.com/~y-nagano/Programs/nywhe …
どうやら、そのサイトにあるDLLをVB6で参照し使用すれば、
目的の事が出来るのではないかと思い、ソースを読もうとしたところ、
VC++の様で、僕には理解できませんでした。
(一応、VCで作ったDLLをVBで読むようにする事が書いてあるサイト
http://www.h4.dion.ne.jp/~fht/htmkdll/
を見つけ、試してみましたがお手上げでした。)
そもそも、そのDLLがVBで使えるのかどうかもわかりません。
ソースを修正したら、VBでも使える様になるのでしょうか?
納期も迫っているので、回答しようにも分からないので困ってます。
環境はWindowsXP(SP2)+VisualStadio6(SP5)です。

A 回答 (2件)

ローカルフックなら、DLL を作る必要なく、VB だけで作れます。


さらに、WH_MOUSE_LL フックは、ローカルフックなのにグローバルフックのように
振る舞います。

というわけでこんなのできました。
フォームにテキストボックスを2個貼り付けて、
Text1 の方を MultiLine=True,ScrollBars=3 にしてください。
標準モジュールも1個追加しておいてください。

Win2000 SP4+VB6 SP5 で動作確認しました。

-- Form1.frm
Option Explicit

Private Sub Form_Load()

Dim i As Integer
Text1.Text = ""
For i = 1 To 100
Text1.Text = Text1.Text + CStr(i) + "行目" + vbCrLf
Next

hHook = SetWindowsHookEx(WH_MOUSE_LL, AddressOf LowLevelMouseProc, App.hInstance, 0)
If hHook <> 0 Then
Debug.Print "hook OK!"
Else
Debug.Print "hook NG", Err.LastDllError
End If
End Sub

Private Sub Form_Unload(Cancel As Integer)
UnhookWindowsHookEx hHook
End Sub


-- Module1.bas
Option Explicit

' フック関係の API
Public 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
Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const HC_ACTION = 0
Public Const WH_MOUSE_LL = 14
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Public Type MSLLHOOKSTRUCT
x As Long
y As Long
mouseData As Long
flags As Long
time As Long
dwExtraInfo As Long
End Type

' メッセージをフックした後の処理で必要な API
Public Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Const WM_MOUSEWHEEL = &H20A&
Public Type POINTAPI
x As Long
y As Long
End Type

' フックプロシージャのハンドル
Public hHook As Long

' フックプロシージャ本体
Public Function LowLevelMouseProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim m As MSLLHOOKSTRUCT
Dim pt As POINTAPI
Dim hWnd As Long
If nCode = HC_ACTION Then
If wParam = WM_MOUSEWHEEL Then
CopyMemory m, ByVal lParam, Len(m)
GetCursorPos pt
hWnd = WindowFromPoint(pt.x, pt.y)
PostMessage hWnd, WM_MOUSEWHEEL, m.mouseData, m.y * &H10000 + m.x
LowLevelMouseProc = 1
Exit Function
End If
End If
LowLevelMouseProc = CallNextHookEx(hHook, nCode, wParam, lParam)
End Function
    • good
    • 0
この回答へのお礼

QSW73j2gdaさん、どうも御回答ありがとうございます。

早速、ソースコードを貼り付けて試してみたところ、
期待通りの動作をしました。

VBだけでも、グローバルフックの様な事が出来るとは思いませんでした。

ありがとうございました。

お礼日時:2007/04/12 17:41

★WM_MOUSEWHEEL メッセージのフックですね。


・『DLL』を VC++ で作成できるのならば、その DLL を VC++ で利用した方がよいのでは。
 メッセージのフックは必ず DLL でないと出来ません。すでにその DLL は作成された
 のですよね。→プログラムの仕組みは既に NY Wheel のリンクに書かれていますので
 それを元に VC++ 用のソースを書いた方が早いと思います。
・でも、次の『猫でもわかるプログラミング』サイトでフックに関する項目を紹介します。
 http://www.kumei.ne.jp/c_lang/index_sdk2.html→『Windows SDK編 第2部』
 ・第160章 メッセージフックの基礎
 ・第162章 マウス・フック
 ・第163章 WH_CALLWNDPROCフック
 ・第164章 ジャーナルレコードとプレイバック その1
 ・第165章 ジャーナルレコードとプレイバック その2
※上記の5つの項目を参考に!C 言語+Win32 SDKでの記述ですので理解できると思います。

その他:
・VB のソースを解読して、アルゴリズムを探ってから VC++ 用に書き換えた方が早いような
 気がしますが…。どうでしょうね。VB のソースコードの内容は?
・私も VB は詳しくありませんが、VB/VC++ での DLL のやり取りの方法が載っているリンクを
 下に4つほど載せておきます。こちらも参考なればと思い紹介しておきます。
・以上。おわり。

参考文献:
http://homepage2.nifty.com/DSS/VCPP/DLL/dllvcstr …→『VC++から文字列を渡す方法』
http://homepage2.nifty.com/DSS/VCPP/MFC/CString/ …→『BSTR変換』
http://japan.internet.com/developer/20051004/27. …→『BSTR およびC文字列の変換』
http://www2.wbs.ne.jp/~kanegon/doc/bstr.txt→『BSTR 覚え書き』
    • good
    • 0
この回答へのお礼

Oh-Orangeさん、早速の御回答ありがとうございます。

恥ずかしながら、私はVBでの開発にしか携わった事がなく、
今回の件があり、CやC++についての知識はかじり始めたばかりで
今のところ無に等しいです。

フックについては、ローカルフックならVBでも可能で
WM_MOUSEWHEELメッセージを受け取ることは出来るのですが、
何故か、フォーカスを持っているコントロールによって、WM_MOUSEWHEELが発生しません。
たしか、VBではグローバルフックと言うのは実現不可と聞いたことがあり、
NYWheelは、そのグローバルフックってのを実行しているんだろうと思い、
そこで、VBでもNYWheelを起動・終了可能なDLLをVC++で作って、
取り込もうと思いました。

もう少し、Oh-Orangeさんに教えていただいたサイト等を参考にさせてもらい
C++を勉強して調べていきたいと思います。

お礼日時:2007/04/12 16:30

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!