Results 1 to 9 of 9

Thread: file under cursor

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Sep 2004
    Posts
    16

    Question file under cursor

    Hi,

    i already posted this question in the visual basic.net-forum. i got the advice, that i maybe have more luck if i post my question in this forum.

    i want to know if there is any possibility to get the filename of a file at the current cursor location within the windows explorer. i found a software called "Instant ThumbView" from ContextMagic (http://www.contextmagic.com/), which is able to do such a thing.

    maybe i can set a hook on the cursor with "SetWindowsHookEx"? another idea of mine was using "WindowFromPoint". but until now i had no luck getting the filename...

    can someone try to help me? examples are welcome

    sorry for my bad english...

    thanks in advance.

    flux

  2. #2
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: file under cursor

    Using WindowFromPoint is probably a good idea. That will get the hWnd of the ListView (if in fact you are moving your mouse in an Explorer window), you must of course check the class name of the returned hWnd to make sure it is a ListView (GetClassName is the API function). After that you must check the class name of the parent window to make sure this is an explorer window, the class name for those are either ExploreWClass or CabinetWClass depending on how the window was opened (explore or open).

    With that done send the LVM_HITTEST message to the listview hWnd to see if your mouse is over an item. You can then get the text of that item to determent what file it is.

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Sep 2004
    Posts
    16

    Red face Re: file under cursor

    Hi,

    thank you for your reply. I tried as you say and I think I am one step closer to the solution, but there is something that still won't work. I alway get "-1" as the result of SendMessage... Here is my code:

    VB Code:
    1. Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    2.         Try
    3.             Label1.Text = ""
    4.             Label1.Text = Cursor.Position.ToString & vbCrLf
    5.             Hwnd = WindowFromPoint(Cursor.Position.X, Cursor.Position.Y)
    6.             If Not Hwnd = OldHwnd Then
    7.                 Dim ClassName As String
    8.                 Dim x As Int32
    9.  
    10.                 ClassName = Space(MAX_PATH)
    11.                 x = GetClassName(Hwnd, ClassName, MAX_PATH)
    12.                 If x > 0 Then
    13.                     ClassName = ClassName.Substring(0, InStr(ClassName, Chr(0)) - 1)
    14.                     If ClassName.Length > 0 And ClassName = "SysListView32" Then
    15.                         Label1.Text &= "Classname: " & ClassName & vbCrLf
    16.                     Else
    17.                         Exit Sub
    18.                     End If
    19.                 Else
    20.                     Exit Sub
    21.                 End If
    22.  
    23.                 Dim pHwnd As Int32
    24.  
    25.                 pHwnd = GetParent(Hwnd)
    26.  
    27.                 If pHwnd > 0 Then
    28.                     Label1.Text &= "pHwnd: " & pHwnd.ToString & vbCrLf
    29.                     Dim pClassName As String
    30.  
    31.                     pClassName = Space(MAX_PATH)
    32.                     x = GetClassName(pHwnd, pClassName, MAX_PATH)
    33.  
    34.                     If x > 0 Then
    35.                         pClassName = pClassName.Substring(0, InStr(pClassName, Chr(0)) - 1)
    36.                         If pClassName.Length > 0 And (pClassName = "CtrlNotifySink" Or pClassName = "SHELLDLL_DefView") Then
    37.                             Label1.Text &= "pClassName: " & pClassName & vbCrLf
    38.                         Else
    39.                             Exit Sub
    40.                         End If
    41.                         Dim item As HITTESTINFO
    42.                         Dim p As POINTAPI
    43.                         item.iSubItem = 0
    44.                         item.iItem = 0
    45.                         p.x = Cursor.Position.X
    46.                         p.y = Cursor.Position.Y
    47.                         ScreenToClient(Hwnd, p)
    48.                         item.pt.x = p.x
    49.                         item.pt.y = p.y
    50.                         item.flags = LVHT_ONITEM
    51.                         x = SendMessage(Hwnd, LVM_HITTEST, 0, item)
    52.                         Label1.Text &= "x: " & x.ToString & " item: " & item.iItem & vbCrLf
    53.                     Else
    54.                         Exit Sub
    55.                     End If
    56.                 Else
    57.                     Exit Sub
    58.                 End If
    59.  
    60.             End If
    61.         Catch ex As Exception
    62.             MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)
    63.         End Try
    64.     End Sub

    The declaration of Sendmessage is as follows:

    VB Code:
    1. Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Object) As Int32
    2.  
    3.     Private Declare Function ScreenToClient Lib "user32.dll" (ByVal hwnd As Int32, ByRef lpPoint As POINTAPI) As Int32
    4.  
    5.     Private Const LVM_FIRST As Int32 = &H1000
    6.     Private Const LVM_HITTEST As Int32 = (LVM_FIRST + 18)
    7.     Private Const LVHT_ONITEM As Int32 = (LVHT_ONITEMICON Or LVHT_ONITEMLABEL Or LVHT_ONITEMSTATEICON)
    8.     Private Const LVHT_ONITEMICON As Int32 = &H2
    9.     Private Const LVHT_ONITEMLABEL As Int32 = &H4
    10.     Private Const LVHT_ONITEMSTATEICON As Int32 = &H8
    11.  
    12.     <StructLayout(LayoutKind.Sequential)> _
    13.     Public Structure POINTAPI
    14.         Public x As Int32
    15.         Public y As Int32
    16.     End Structure
    17.  
    18.     <StructLayout(LayoutKind.Sequential)> _
    19.         Public Structure HITTESTINFO
    20.         Dim pt As POINTAPI
    21.         Dim flags As Long
    22.         Dim iItem As Long
    23.         Dim iSubItem As Long
    24.     End Structure

    Can you or anyone please help me to solve this problem?
    Sorry for my bad english...

  4. #4
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: file under cursor

    I'm not an expert on .Net so I'm just asking if it's correct to declare the last argument to SendMessage as ByVal lParam As Object. It expects a pointer to the HITTESTINFO structure does it get that when it's declared as ByVal? If you're only using SendMessage for this purpose maybe you should try to change the declaration to ByRef lParam As HÍTTESTINFO. I don't know if that makes any difference since I'm unsure about the API declarations in .Net.

  5. #5
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: file under cursor

    Oh, another thing just hit me. You use this code in a Timer and you only go through the code if the hWnd of the control the mouse is over is different from the last time the event was fired. So I'm guessing that the first time you move the mouse inside the file view in an explorer window the code will run, but maybe you're not over an item at this point, so you keep on moving the mouse until you are over an item but since the mouse is still over the same control your code isn't running.

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Sep 2004
    Posts
    16

    Re: file under cursor

    Quote Originally Posted by Joacim Andersson
    Oh, another thing just hit me. You use this code in a Timer and you only go through the code if the hWnd of the control the mouse is over is different from the last time the event was fired. So I'm guessing that the first time you move the mouse inside the file view in an explorer window the code will run, but maybe you're not over an item at this point, so you keep on moving the mouse until you are over an item but since the mouse is still over the same control your code isn't running.
    Thanks for your ideas.

    I didn't set the variable "OldHWND", so it should be "0". This causes, that "Hwnd" and "OldHwnd" should nearly never the same.

    I changed the declaration of "SendMessage" as you said, but the returnvalue is still "-1"...
    Sorry for my bad english...

  7. #7
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: file under cursor

    I believe the declaration should be as follows.
    VB Code:
    1. <DllImport("user32", EntryPoint:="SendMessageW")> Private Shared Function SendMessage( _
    2.     ByVal hWnd As IntPtr, _
    3.     ByVal uMsg As Integer, _
    4.     ByVal wParam As Integer, _
    5.     <MarshalAs(UnmanagedType.LPStruct)> ByRef lParam As Object _
    6. ) As Integer
    7. End Function

    BTW, Int32's in VB.NET are rather limited - you should use Integer's instead.

  8. #8
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: file under cursor

    I translated the code to VB6 and tried it out. I also get -1 as the result regardless of where I put the mouse pointer, which is weird. But at least I don't think there is anything wrong with your API declarations.

  9. #9

    Thread Starter
    Junior Member
    Join Date
    Sep 2004
    Posts
    16

    Re: file under cursor

    Thanks again for your efforts!

    Quote Originally Posted by penagate
    I believe the declaration should be as follows.
    VB Code:
    1. <DllImport("user32", EntryPoint:="SendMessageW")> Private Shared Function SendMessage( _
    2.     ByVal hWnd As IntPtr, _
    3.     ByVal uMsg As Integer, _
    4.     ByVal wParam As Integer, _
    5.     <MarshalAs(UnmanagedType.LPStruct)> ByRef lParam As Object _
    6. ) As Integer
    7. End Function

    BTW, Int32's in VB.NET are rather limited - you should use Integer's instead.
    If I try this, I got an error-message: "Cannot marshal 'parameter #4': Invalid managed/unmanaged type combination (the Object class must be paired with Interface, IUnkown, IDispatch, AsAny, or Struct)."

    In my opinion it's declared as Struct, so I do not understand why this error happens
    Sorry for my bad english...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width