マウスホイールのイベント取得方法

解決


カズ  2008-04-25 15:19:56  No: 139609  IP: 192.*.*.*

お世話になります。
VB6でマウスホイールを使ってPictureBoxの絵を拡大、縮小できるようにしたいと思っています。仕様としてはPicture1の上にマウスがある時だけに反応するようにしたいと思います。

マウスホイールの記事を探して(http://okwave.jp/qa2912840.html)TextBoxの文字がホイールに従ってスクロールするサンプルを試したのですがPictureBoxで反応するようにする方法が分からず質問させていただきました。よろしくお願いします。

編集 削除
 2008-04-25 17:07:00  No: 139610  IP: 192.*.*.*

http://homepage.mac.com/t_fukumori/iblog/C1746881529/E2116345545/index.html

ここがそのまんまかも。

編集 削除
カズ  2008-04-25 18:14:56  No: 139611  IP: 192.*.*.*

と様、耳寄りな情報をありがとうございました。
ちょっとテストしてみたのですがマウスホイールのUPとDownはPictureBox内だけで反応するのですが回転イベントはPictureBox外でも、更に他のアプリにフォーカスがある時でも反応するようです。(これはhttp://okwave.jp/qa2912840.htmlでも同様です)

コードのどこかを改造すればPictureBoxだけで反応するようにできるのでしょうか。よろしくお願いします。

編集 削除
 2008-04-25 18:26:31  No: 139612  IP: 192.*.*.*

マウスの位置を使ってWindowFromPoint()で取得できる
ウィンドウハンドルとピクチャーボックスのウィンドウハンドルが
同じとき

という条件を入れれば可能だと思われます。

編集 削除
カズ  2008-04-28 15:14:39  No: 139613  IP: 192.*.*.*

と様、ご回答をありがとうございました。

マウスの絶対位置から判定した場合は目的のアプリが裏に隠れていても反応してしまうのではないかと考え「ウィンドウハンドルとピクチャーボックスのウィンドウハンドルが同じとき」という判定が必須ではないかと考えました。現在のウインドウハンドルが何であるかを取得するにはどうしたら良いかを調べていたのですがウィンドウハンドルという言葉の意味も理解できていないので手がつけられないでいました。恐らく  If PresentWindowHandele =  Picture1.hDc  then  みたいにするのであろうと想像しました。現在のウインドウハンドルを知る方法を教えてください。

編集 削除
魔界の仮面弁士  2008-04-28 16:10:24  No: 139614  IP: 192.*.*.*

> If PresentWindowHandele =  Picture1.hDc  then
hDC は「デバイスコンテキスト ハンドル」、描画処理のためのハンドルです。
「ウィンドウハンドル」であれば、hWnd プロパティですね。

> 現在のウインドウハンドルを知る方法を教えてください。
とさんが既に回答されていますよね。「WindowFromPoint」の API です。


宣言例などが分からないのであれば、「google ソースコード検索」などでどうぞ。
http://www.google.com/codesearch?hl=ja&q=WindowFromPoint+VB6
http://www.google.com/codesearch?hl=ja&q=WindowFromPoint+VB

編集 削除
魔界の仮面弁士  2008-04-28 17:13:10  No: 139615  IP: 192.*.*.*

失礼しました。知りたいのは現在アクティブなウィンドウでしたね。
そちらは、GetActiveWindow API でどうぞ。


マウス ホイールは、ドライバによって
  (1)アクティブなアプリの、現在フォーカスがあるウィンドウに反応
  (2)アクティブなアプリの、現在マウス座標があるウィンドウに反応
  (3)アクティブかどうかに問わず、現在マウス座標があるウィンドウに反応
などがありますね。(OS 標準機能だと 2 番かな?)

編集 削除
 2008-04-28 17:34:18  No: 139616  IP: 192.*.*.*

少し長くなってしまいますが
http://homepage.mac.com/t_fukumori/iblog/C1746881529/E2116345545/index.html
をベースに、http://okwave.jp/qa2912840.htmlとあわせ技で追加分だけ

modWheelMouse.bas

Option Explicit
Public Type POINTAPI
x As Long
y As Long
End Type

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

Private Function SubClassProc(ByVal hwndx As Long, _
(略
    Dim hWnd As Long
    Dim pt As POINTAPI
(略

            Case WM_MOUSEWHEEL  '' Wheelを回した
                GetCursorPos pt
                hWnd = WindowFromPoint(pt.x, pt.y)
                
                If hwndx = hWnd Then
                    zDelta = CInt(wParam / 2 ^ 16)
                    略
                End If


frmMain.frm
Private Sub m_CWheel_MouseWheel(ByVal iniVector As Integer)
'これはただ単に分かりやすくするため
    lblView.Caption = "MouseWheel" & iniVector
End Sub

こんなもんでどうでしょ?

編集 削除
 2008-04-28 17:58:19  No: 139617  IP: 192.*.*.*

私の環境では
魔界の仮面弁士さんの回答にある
>(2)アクティブなアプリの、現在マウス座標があるウィンドウに反応
のようなので上の追加だけで問題なさそうでした。


>魔界の仮面弁士 2008/04/28(月) 17:13:10
さんと同じ勘違いしてました。

必要であればGetActiveWindow()とピクチャーボックスの親ウィンドウを
(GetParent APIなりGetAncestor API)取得して戻り値のハンドルの比較も
追加してみてください。
#こちらは試していません。

編集 削除
カズ  2008-04-28 17:59:14  No: 139618  IP: 192.*.*.*

と様、魔界の仮面弁士様  ご丁寧な回答をありがとうございます。

ほとんど必要なコードが入ったサンプルをいただきましたのでこれからテストのプロジェクトを作って試してみます。まだ初見ではコードの意味など分からないものがありますので勉強しながら進めたいと思いますがとりあえずお礼申し上げます。どうしても理解できないところがありましたらまたよろしくお願いします。

編集 削除
カズ  2008-04-28 19:18:19  No: 139619  IP: 192.*.*.*

と様、魔界の仮面弁士様、とにかく希望通りに動きました。
画面の下に隠れた場合の反応などを調べるためBeepを入れて確認しましたが現在のところ隠れた場合は反応しませんでした。従って(今の当方のPC環境では)  「(1)アクティブなアプリの、現在フォーカスがあるウィンドウに反応」  で動いているものと思います。

通常のPCで「(3)アクティブかどうかに問わず、現在マウス座標があるウィンドウに反応」というのはあるものなのでしょうか?

クラスとかハンドルなどは今までは言葉だけ聞いたことがあるという状態でしたので大いに勉強になります。とにかく動きますので実装してみたいと思います。  大変ありがとうございました。

            Case WM_MOUSEWHEEL  '' Wheelを回した
            
                GetCursorPos pt
                hWnd = WindowFromPoint(pt.x, pt.y)
                
                If hwndx = hWnd Then
                    zDelta = CInt(wParam / 2 ^ 16)
                    If zDelta < 0 Then
                        '' ホイールが奥に回転した場合
                        m_ColCWhell(i).raiseMyEvent 3, -1, 0, 0
                        frmMain.Text1.Text = 1:Beep
                    Else
                        '' ホイールが手前に回転した場合
                        m_ColCWhell(i).raiseMyEvent 3, 1, 0, 0
                        frmMain.Text1.Text = 2:Beep
                    End If
                Else
                    frmMain.Text1.Text = 0
                End If
 
            End Select

編集 削除