From: mp on
Hi,
I was generously given the following code for a ListBox hit test by Bob
Butler.
trying to find out would be a companion code that would do that for a
ListView?
havent' found it in a bing search yet though i'm sure the info is out there
if i keep looking...
in the meantime, if anyone knows off the top of their heads...i'm wondering
if i just need a different constant than
LB_ITEMFROMPOINT, like a LV_ITEMFROMPOINT ...:-)
i searched on that and got this page
http://msdn.microsoft.com/en-us/library/bb774760%28VS.85%29.aspx
but didn't see a solution there,

Function ListBoxHitTest(ByVal Lb As ListBox, _
ByVal x As Single, ByVal y As Single) As Long
Dim uParam As MakeDWord
Dim lParam As Long
Dim r As Long
uParam.x = x / Screen.TwipsPerPixelX
uParam.y = y / Screen.TwipsPerPixelY
CopyMemory lParam, uParam.x, 4
r = SendMessage(Lb.hWnd, LB_ITEMFROMPOINT, 0, ByVal lParam)
ListViewHitTest = r
End Function


i also found this for Ce but i'm in vb6 so don't know how to convert...also
found somethings in vbnet, but again, i'm looking for vb6 at this point.
LVM_SUBITEMHITTEST
This message determines which list-view item or subitem is at a specified
position.

LVM_SUBITEMHITTEST wParam = 0;
lParam = (LPARAM)(LVHITTESTINFO FAR *)pInfo;
OS Versions: Windows CE 1.0 and later.
Header: Commctrl.h.

any pointers appreciated
mark


From: Bob Butler on

"mp" <nospam(a)Thanks.com> wrote in message
news:i05m5t$uhr$1(a)news.eternal-september.org...
> Hi,
> I was generously given the following code for a ListBox hit test by Bob
> Butler.
> trying to find out would be a companion code that would do that for a
> ListView?

what version of the listview are you using? The one in the Common Controls
6 library has a hittest built in

Dim oItem As MSComctlLib.ListItem
Set oItem = ListView1.HitTest(x, y)


From: MikeD on


"mp" <nospam(a)Thanks.com> wrote in message
news:i05m5t$uhr$1(a)news.eternal-september.org...
>
> i also found this for Ce but i'm in vb6 so don't know how to
> convert...also found somethings in vbnet, but again, i'm looking for vb6
> at this point.
> LVM_SUBITEMHITTEST
> This message determines which list-view item or subitem is at a specified
> position.
>
> LVM_SUBITEMHITTEST wParam = 0;
> lParam = (LPARAM)(LVHITTESTINFO FAR *)pInfo;
> OS Versions: Windows CE 1.0 and later.
> Header: Commctrl.h.
>

As Bob said, the v6 ListView has a HitTest method, but I personally find it
lacking. Primarily in that it won't tell you what subitem was clicked
because it only returns a reference to a ListItem object. This sub will give
you the index of the ListItem AND the index of the subitem. It will work
with both the v5 and v6 ListView control. The X and Y parameters that you
pass in should always be in twips because the sub converts them to pixels,
but you could change that aspect if you wanted to. You might also want to
change this to a function that returns a Boolean indicating if the hit test
was successful. As is, ItemIndex will be 0 if there there was no item at
the specified coordinate.

-----BEGIN CODE
Private Const LVM_FIRST As Long = &H1000
Private Const LVM_SUBITEMHITTEST As Long = LVM_FIRST + 57

Private Const LVHT_NOWHERE As Long = &H1
Private Const LVHT_ONITEMICON As Long = &H2
Private Const LVHT_ONITEMLABEL As Long = &H4
Private Const LVHT_ONITEMSTATEICON As Long = &H8
Private Const LVHT_ONITEM As Long = (LVHT_ONITEMICON
Or LVHT_ONITEMLABEL Or LVHT_ONITEMSTATEICON)

Private Type POINTAPI
x As Long
y As Long
End Type

Private Type LVHITTESTINFO
pt As POINTAPI
Flags As Long
iItem As Long
iSubItem As Long
End Type

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

Public Sub HitTestEx(ByVal hWnd As Long, ByVal X As Single, ByVal Y As
Single, ByRef ItemIndex As Long, ByRef SubItemIndex As Long)

'Performs a hit test at the specified coordinates.
'IconIndex is the index of the ListItem at the coordinates
'SubItemIndex is the index of the ListSubItem at the coordinates

Dim HTI As LVHITTESTINFO

With HTI
.pt.x = (X \ Screen.TwipsPerPixelX)
.pt.Y = (Y \ Screen.TwipsPerPixelY)
.flags = LVHT_ONITEM
End With

Call SendMessage(hWnd, LVM_SUBITEMHITTEST, 0&, HTI)

With HTI
'Determine if a listitem or listsubitem was clicked
Select Case .iSubItem
Case 0
If .iItem > -1 Then
'We need to add 1 because items are 0-based in the API
'but are 1-based in the ListItems collection.
ItemIndex = .iItem + 1
SubItemIndex = 0
End If
Case Is > 0
ItemIndex = .iItem + 1
SubItemIndex = .iSubItem 'subitems are 1-based in the API
End Select
End With

End Sub

-----END CODE

--
Mike


From: mp on

"MikeD" <nobody(a)nowhere.edu> wrote in message
news:uEydzUfFLHA.1868(a)TK2MSFTNGP05.phx.gbl...
>
>
> "mp" <nospam(a)Thanks.com> wrote in message
> news:i05m5t$uhr$1(a)news.eternal-september.org...
>>
>> i also found this for Ce but i'm in vb6 so don't know how to
>> convert...also found somethings in vbnet, but again, i'm looking for vb6
>> at this point.
>> LVM_SUBITEMHITTEST
>> This message determines which list-view item or subitem is at a specified
>> position.
>>
>> LVM_SUBITEMHITTEST wParam = 0;
>> lParam = (LPARAM)(LVHITTESTINFO FAR *)pInfo;
>> OS Versions: Windows CE 1.0 and later.
>> Header: Commctrl.h.
>>
>
> As Bob said, the v6 ListView has a HitTest method, but I personally find
> it lacking. Primarily in that it won't tell you what subitem was clicked
> because it only returns a reference to a ListItem object. This sub will
> give you the index of the ListItem AND the index of the subitem. It will
> work with both the v5 and v6 ListView control. The X and Y parameters
> that you pass in should always be in twips because the sub converts them
> to pixels, but you could change that aspect if you wanted to. You might
> also want to change this to a function that returns a Boolean indicating
> if the hit test was successful. As is, ItemIndex will be 0 if there there
> was no item at the specified coordinate.
>
> -----BEGIN CODE
> Private Const LVM_FIRST As Long = &H1000
> Private Const LVM_SUBITEMHITTEST As Long = LVM_FIRST + 57
>
> Private Const LVHT_NOWHERE As Long = &H1
> Private Const LVHT_ONITEMICON As Long = &H2
> Private Const LVHT_ONITEMLABEL As Long = &H4
> Private Const LVHT_ONITEMSTATEICON As Long = &H8
> Private Const LVHT_ONITEM As Long = (LVHT_ONITEMICON
> Or LVHT_ONITEMLABEL Or LVHT_ONITEMSTATEICON)
>
> Private Type POINTAPI
> x As Long
> y As Long
> End Type
>
> Private Type LVHITTESTINFO
> pt As POINTAPI
> Flags As Long
> iItem As Long
> iSubItem As Long
> End Type
>
> 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
>
> Public Sub HitTestEx(ByVal hWnd As Long, ByVal X As Single, ByVal Y As
> Single, ByRef ItemIndex As Long, ByRef SubItemIndex As Long)
>
> 'Performs a hit test at the specified coordinates.
> 'IconIndex is the index of the ListItem at the coordinates
> 'SubItemIndex is the index of the ListSubItem at the coordinates
>
> Dim HTI As LVHITTESTINFO
>
> With HTI
> .pt.x = (X \ Screen.TwipsPerPixelX)
> .pt.Y = (Y \ Screen.TwipsPerPixelY)
> .flags = LVHT_ONITEM
> End With
>
> Call SendMessage(hWnd, LVM_SUBITEMHITTEST, 0&, HTI)
>
> With HTI
> 'Determine if a listitem or listsubitem was clicked
> Select Case .iSubItem
> Case 0
> If .iItem > -1 Then
> 'We need to add 1 because items are 0-based in the API
> 'but are 1-based in the ListItems collection.
> ItemIndex = .iItem + 1
> SubItemIndex = 0
> End If
> Case Is > 0
> ItemIndex = .iItem + 1
> SubItemIndex = .iSubItem 'subitems are 1-based in the API
> End Select
> End With
>
> End Sub
>
> -----END CODE
>
> --
> Mike
>
>
Thanks Bob and Mike
You guys are awesome!!!
I don't know where you find this stuff, every thing i found was for dotnet.
Special thanks to Mike for the above - that is perfect. You saved me who
knows how many hours of searching!!!
thanks
Mark


From: MikeD on


"mp" <nospam(a)Thanks.com> wrote in message
news:i0803s$l0h$1(a)news.eternal-september.org...

> I don't know where you find this stuff, every thing i found was for
> dotnet.

You just gotta know where to look, and a little experience with C++ is very
helpful. Always start with MSDN Library for the documentation. You'll also
have the latest information on the message, function, or whatever. For this
message, here's the link to the documentation:

http://msdn.microsoft.com/en-us/library/bb761229(VS.85).aspx

If you look at that, you'll notice some changes for Vista and later that I
did not incorporate. For example, the LVHITTESTINFO structure has an
additional member, iGroup, and there are additional flags.

For the next part, you need to get the constant definitions. Unfortunately,
these are rarely in MSDN Library. So, if you've got Visual Studio, install
C++ to get the .h files which contain all the definitions, etc. If you DON'T
have Visual Studio, you can download and install the Platform SDK
(basically, the Windows programming documentation from MSDN Library). This
includes all the header files, and later versions of them than you'd get
from VC++6. The MSDN Library documentation usually tells you what header
(.h) file contains the definition. In this case, it's Commctrl.h. Having
some familiarity with C++ is helpful in converting everything to VB.

The rest is just knowing how to call API functions from VB (for example,
when you must pass parameters ByVal and when you must pass them ByRef).

--
Mike