ツリービューの選択されているアイテムの領域を取得!!

エクスプローラタイプのアプリを作る上で必需品!?
ちゃんとアプリケーションキーにも対応しましょう!!
エクスプローラに使用をあわせて、アプリケーションキーで選択アイテムの
中心からポップアップメニューを表示




Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
    ByVal hwnd As Long, _
    ByVal wMsg As Long, _
    ByVal wParam As Long, _
    lParam As Any _
) As Long

Private Declare Function ClientToScreen Lib "user32" ( _
    ByVal hwnd As Long, _
    lpPoint As POINTAPI _
) As Long

Private Const TV_FIRST = &H1100 '4352
Private Const TVM_GETNEXTITEM = (TV_FIRST + 10)
Private Const TVGN_CARET = 9
Private Const TVM_GETITEMRECT = (TV_FIRST + 4)

Private Type POINTAPI
    X As Long
    Y As Long
End Type

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

' ツリービューのキー操作サンプル
' Form.KeyPreview を True にしておく
' F1 が押されればヘルプ
' F2 が押されればラベル編集
' アプリケーションキー(右Ctrlキー隣)が押されればポップアップメニュー
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    Dim hItem As Long
    Dim r As RECT
    Dim lpData(4) As Long
    Dim Pnt1 As POINTAPI
    Dim Pnt2 As POINTAPI
    
    If KeyCode = 93 Then    ' アプリケーションキー
        If ActiveControl.Name = trvTree.Name Then   ' ツリービューにフォーカスがあれば
            hItem = SendMessage(trvTree.hwnd, TVM_GETNEXTITEM, TVGN_CARET, ByVal 0)     ' 現在選択されているアイテム取得
            lpData(0) = hItem                                                           ' 引数にセット
            Call SendMessage(trvTree.hwnd, TVM_GETITEMRECT, True, lpData(0))            ' 領域取得
            
            ' ツリービューのAppearanceによるずれを取得
            Pnt1.X = 0
            Pnt1.Y = 0
            Call ClientToScreen(trvTree.hwnd, Pnt1)
            Pnt2.X = trvTree.Left / Screen.TwipsPerPixelX
            Pnt2.Y = trvTree.Top / Screen.TwipsPerPixelY
            Call ClientToScreen(Me.hwnd, Pnt2)
            
            r.Left = trvTree.Left + (lpData(0) + Pnt1.X - Pnt2.X) * Screen.TwipsPerPixelX
            r.Top = trvTree.Top + (lpData(1) + Pnt1.Y - Pnt2.Y) * Screen.TwipsPerPixelY
            r.Right = trvTree.Left + (lpData(2) + Pnt1.X - Pnt2.X) * Screen.TwipsPerPixelX
            r.Bottom = trvTree.Top + (lpData(3) + Pnt1.Y - Pnt2.Y) * Screen.TwipsPerPixelY
            
            ' 擬似イベント生成(ポップアップメニュー表示)
            Call trvTree_MouseDown(vbRightButton, 0, r.Left - trvTree.Left + (r.Right - r.Left) / 2, r.Top - trvTree.Top + (r.Bottom - r.Top) / 2)
        End If
    ElseIf KeyCode = vbKeyF1 Then
        Call mnuHelp_Click
        KeyCode = 0
    ElseIf KeyCode = vbKeyF2 Then
        trvTree.StartLabelEdit
    End If
End Sub