2006-07-05(Wed)

リストビュー第6回 マウスの当たり判定

小休止 7 8 回

第6回 マウスの当たり判定

久々に ActiveBasic の続きを書こう。

えーと第6回はなんだ、マウスカーソルの当たり判定だったか。
リストビューをクリックした位置の、インデックス番号を取得したいと思う。


とは言っても、難しいことは何もない。全自動で返ってくる。
例によってこれまでのソースに追加する。

まず、必要な構造体が ActiveBasic 4.24.00 の時点で定義されていないので、プログラムの先頭などで自分で定義する。


'リストビューの当たり判定用構造体を定義
Type LVHITTESTINFO
    pt As POINTAPI          'マウスクリック位置をクライアント座標で格納
    flags As DWord          'ヒットテストの結果を示すフラグ
    iItem As DWord          'ヒットしたリストビューの iItem
    iSubItem As DWord       'ヒットしたリストビューの iSubItem
End Type


次に、RAD ツールでリストビューを右クリックし、「イベントコード」から「RClick…コントロール内でマウスの右ボタンがクリックされた時」をコーディングする。


/*マウスの当たり判定をしてみる*/
Sub MainWnd_ListView1_RClick(ByRef nmListView As NMLISTVIEW)
    Dim lvht As LVHITTESTINFO 'リストビューの当たり判定用の構造体
    Dim pos As POINTAPI
    Dim iItem As Long
    'カーソル位置を取得
    GetCursorPos( pos )                 'スクリーン座標で取得
    lvht.pt.x = pos.x
    lvht.pt.y = pos.y
    ScreenToClient( hList, lvht.pt )    'クライアント座標に変換
    'クリックされた位置のアイテムのインデックスを取得
    iItem = SendMessage( hList, LVM_HITTEST, 0, VarPtr(lvht) As Long )
    'アイテムがあるレコードならインデックス番号を表示
    If iItem > -1 And iItem < SendMessage( hList, LVM_GETITEMCOUNT, 0, 0 ) Then
        'インデックスを表示してみる
        MessageBox( hMainWnd, "右クリックされたのはインデックス"+Str$(iItem)+"だよ", "当たり判定テスト", MB_OK )
    End If
End Sub


LVHITTESTINFO 構造体の pt (POINTAPI)にクライアント領域の座標を入れ、LVM_GETITEMCOUNT へ送ってあげると、その座標のアイテムのインデックスが返ってくる。
アイテムがなかった場合は -1 が返る。
ここで実行してみよう。アイテムを右クリックすると、インデックス番号が表示される。


このままでは芸がないので、少々改造してアイテム上で右クリックした時、メニューを出してみる事にする。


/*マウスの当たり判定をしてみる*/
Sub MainWnd_ListView1_RClick(ByRef nmListView As NMLISTVIEW)
    Dim lvht As LVHITTESTINFO 'リストビューの当たり判定用の構造体
    Dim pos As POINTAPI
    Dim iItem As Long
    Dim hSubMenu As HMENU

    'カーソル位置を取得
    GetCursorPos( pos )                 'スクリーン座標で取得
    lvht.pt.x = pos.x
    lvht.pt.y = pos.y
    ScreenToClient( hList, lvht.pt )    'クライアント座標に変換
    'クリックされた位置のアイテムのインデックスを取得
    iItem = SendMessage( hList, LVM_HITTEST, 0, VarPtr(lvht) As Long )
    'アイテムがあるレコードならインデックス番号を表示
    If iItem > -1 And iItem < SendMessage( hList, LVM_GETITEMCOUNT, 0, 0 ) Then
        'メニューを出してみる
        hSubMenu = GetSubMenu( hMenu_MainMenu, 0 )  'メインウィンドウに置かれているメニューから、1つめメニューのハンドルを取得
        TrackPopupMenu( hSubMenu, TPM_TOPALIGN or TPM_LEFTALIGN, pos.x, pos.y, 0, hMainWnd, ByVal(0) )

    End If
End Sub


変更箇所は色のついた部分。
hMenu はサブメニューのハンドルの格納用。
GetSubMenu でメニューとサブメニュー番号を指定すると、サブメニューのハンドルが得られる。
あとは TrackPopupMenu で、今ほど取得したサブメニューのハンドルと座標を指定すれば、マウスカーソルの位置にメニューが出る。

ちなみに hMenu_MainMenu ってのは、第3回でメニュー IDMainMenu にしたから、自動的にそのような名前の変数にハンドルが格納された。
別な名前を付けてテストしている人は、hMenu_ の後を適宜書き換えてほしい。

実行して右クリックすると、マウスカーソルの座標位置にメニューがポップアップされると思う。



今回は以上で終わり。

以下、これまでのソースコード。
コピペし辛かったのでエディットボックスに入れてみた。

コメントの投稿

管理者にだけ表示を許可する

コメント

プロフィール

nakami

Author:nakami
可愛いテンプレートに似合う俺
うそAチームのスミス大佐

NAVI
カテゴリー
最近の記事
リンク
FC2カウンター
ブログ内検索
RSSフィード
sponsored link