お世話になります。
VB6でマウスホイールを使ってPictureBoxの絵を拡大、縮小できるようにしたいと思っています。仕様としてはPicture1の上にマウスがある時だけに反応するようにしたいと思います。
マウスホイールの記事を探して(http://okwave.jp/qa2912840.html)TextBoxの文字がホイールに従ってスクロールするサンプルを試したのですがPictureBoxで反応するようにする方法が分からず質問させていただきました。よろしくお願いします。
http://homepage.mac.com/t_fukumori/iblog/C1746881529/E2116345545/index.html
ここがそのまんまかも。
と様、耳寄りな情報をありがとうございました。
ちょっとテストしてみたのですがマウスホイールのUPとDownはPictureBox内だけで反応するのですが回転イベントはPictureBox外でも、更に他のアプリにフォーカスがある時でも反応するようです。(これはhttp://okwave.jp/qa2912840.htmlでも同様です)
コードのどこかを改造すればPictureBoxだけで反応するようにできるのでしょうか。よろしくお願いします。
マウスの位置を使ってWindowFromPoint()で取得できる
ウィンドウハンドルとピクチャーボックスのウィンドウハンドルが
同じとき
という条件を入れれば可能だと思われます。
と様、ご回答をありがとうございました。
マウスの絶対位置から判定した場合は目的のアプリが裏に隠れていても反応してしまうのではないかと考え「ウィンドウハンドルとピクチャーボックスのウィンドウハンドルが同じとき」という判定が必須ではないかと考えました。現在のウインドウハンドルが何であるかを取得するにはどうしたら良いかを調べていたのですがウィンドウハンドルという言葉の意味も理解できていないので手がつけられないでいました。恐らく If PresentWindowHandele = Picture1.hDc then みたいにするのであろうと想像しました。現在のウインドウハンドルを知る方法を教えてください。
> 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
失礼しました。知りたいのは現在アクティブなウィンドウでしたね。
そちらは、GetActiveWindow API でどうぞ。
マウス ホイールは、ドライバによって
(1)アクティブなアプリの、現在フォーカスがあるウィンドウに反応
(2)アクティブなアプリの、現在マウス座標があるウィンドウに反応
(3)アクティブかどうかに問わず、現在マウス座標があるウィンドウに反応
などがありますね。(OS 標準機能だと 2 番かな?)
少し長くなってしまいますが
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
こんなもんでどうでしょ?
私の環境では
魔界の仮面弁士さんの回答にある
>(2)アクティブなアプリの、現在マウス座標があるウィンドウに反応
のようなので上の追加だけで問題なさそうでした。
>魔界の仮面弁士 2008/04/28(月) 17:13:10
さんと同じ勘違いしてました。
必要であればGetActiveWindow()とピクチャーボックスの親ウィンドウを
(GetParent APIなりGetAncestor API)取得して戻り値のハンドルの比較も
追加してみてください。
#こちらは試していません。
と様、魔界の仮面弁士様 ご丁寧な回答をありがとうございます。
ほとんど必要なコードが入ったサンプルをいただきましたのでこれからテストのプロジェクトを作って試してみます。まだ初見ではコードの意味など分からないものがありますので勉強しながら進めたいと思いますがとりあえずお礼申し上げます。どうしても理解できないところがありましたらまたよろしくお願いします。
と様、魔界の仮面弁士様、とにかく希望通りに動きました。
画面の下に隠れた場合の反応などを調べるため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