ホットトラッキングされているToolButtonを取得する、座標からToolButtonを取得する

注意:
この文書は以前「.NETでいきまっしょい!」で公開していたものですが、公開以降メンテナンスされていません。 今や古い情報となった内容が記載されている場合があるのでご注意ください。

ToolBarコントロールに対してTB_GETHOTITEMおよびTB_GETITEMRECTメッセージを送信することによって、ホットトラッキングされているToolButtonや、ToolButtonの領域座標を得ることができる。 ここではそれらの機能を使い、現在ホットトラッキング状態になっているToolButtonと、指定された点にあるToolButtonを取得することができるToolBar拡張クラスを紹介する。

ソースコード
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
Public Class ToolBarEx

    Inherits System.Windows.Forms.ToolBar

    <Runtime.InteropServices.DllImport("user32.dll", charset:=Runtime.InteropServices.CharSet.Auto)> _
    Private Shared Function SendMessage( _
        ByVal hWnd As IntPtr, _
        ByVal msg As Integer, _
        ByVal wParam As Integer, _
        ByVal lParam As Integer) As Integer
    End Function

    ''' <summary>
    ''' ホットトラッキング状態のToolBarButtonを取得する
    ''' </summary>
    Public Function GetHotButton() As ToolBarButton

        Const TB_GETHOTITEM As Integer = &H447

        Dim index As Integer = SendMessage(Me.Handle, TB_GETHOTITEM, 0, 0)

        If 0 <= index Then

            Return Me.Buttons(index)

        Else

            Return Nothing

        End If

    End Function

    <Runtime.InteropServices.DllImport("user32.dll", charset:=Runtime.InteropServices.CharSet.Auto)> _
    Private Shared Function SendMessage( _
        ByVal hWnd As IntPtr, _
        ByVal msg As Integer, _
        ByVal wParam As Integer, _
        ByRef lParam As RECT) As Integer
    End Function

    <Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Sequential, Pack:=4)> _
    Private Structure RECT

        Public Left As Integer
        Public Top As Integer
        Public Right As Integer
        Public Bottom As Integer

    End Structure

    ''' <summary>
    ''' ある座標point上にあるToolBarButtonを取得する
    ''' </summary>
    Public Function GetButtonAt(ByVal point As Point) As ToolBarButton

        Const TB_GETITEMRECT As Integer = &H41D

        Dim rect As rect

        For index As Integer = 0 To Me.Buttons.Count - 1

            SendMessage(Me.Handle, TB_GETITEMRECT, index, rect)

            If rect.Left <= point.X AndAlso point.X <= rect.Right AndAlso _
               rect.Top <= point.Y AndAlso point.Y <= rect.Bottom Then

                Return Me.Buttons(index)

            End If

        Next

        Return Nothing

    End Function

End Class