|
-
Nov 20th, 2005, 04:35 PM
#1
Thread Starter
Junior Member
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
-
Nov 22nd, 2005, 05:46 PM
#2
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.
-
Nov 24th, 2005, 03:58 AM
#3
Thread Starter
Junior Member
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:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Try
Label1.Text = ""
Label1.Text = Cursor.Position.ToString & vbCrLf
Hwnd = WindowFromPoint(Cursor.Position.X, Cursor.Position.Y)
If Not Hwnd = OldHwnd Then
Dim ClassName As String
Dim x As Int32
ClassName = Space(MAX_PATH)
x = GetClassName(Hwnd, ClassName, MAX_PATH)
If x > 0 Then
ClassName = ClassName.Substring(0, InStr(ClassName, Chr(0)) - 1)
If ClassName.Length > 0 And ClassName = "SysListView32" Then
Label1.Text &= "Classname: " & ClassName & vbCrLf
Else
Exit Sub
End If
Else
Exit Sub
End If
Dim pHwnd As Int32
pHwnd = GetParent(Hwnd)
If pHwnd > 0 Then
Label1.Text &= "pHwnd: " & pHwnd.ToString & vbCrLf
Dim pClassName As String
pClassName = Space(MAX_PATH)
x = GetClassName(pHwnd, pClassName, MAX_PATH)
If x > 0 Then
pClassName = pClassName.Substring(0, InStr(pClassName, Chr(0)) - 1)
If pClassName.Length > 0 And (pClassName = "CtrlNotifySink" Or pClassName = "SHELLDLL_DefView") Then
Label1.Text &= "pClassName: " & pClassName & vbCrLf
Else
Exit Sub
End If
Dim item As HITTESTINFO
Dim p As POINTAPI
item.iSubItem = 0
item.iItem = 0
p.x = Cursor.Position.X
p.y = Cursor.Position.Y
ScreenToClient(Hwnd, p)
item.pt.x = p.x
item.pt.y = p.y
item.flags = LVHT_ONITEM
x = SendMessage(Hwnd, LVM_HITTEST, 0, item)
Label1.Text &= "x: " & x.ToString & " item: " & item.iItem & vbCrLf
Else
Exit Sub
End If
Else
Exit Sub
End If
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)
End Try
End Sub
The declaration of Sendmessage is as follows:
VB Code:
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
Private Declare Function ScreenToClient Lib "user32.dll" (ByVal hwnd As Int32, ByRef lpPoint As POINTAPI) As Int32
Private Const LVM_FIRST As Int32 = &H1000
Private Const LVM_HITTEST As Int32 = (LVM_FIRST + 18)
Private Const LVHT_ONITEM As Int32 = (LVHT_ONITEMICON Or LVHT_ONITEMLABEL Or LVHT_ONITEMSTATEICON)
Private Const LVHT_ONITEMICON As Int32 = &H2
Private Const LVHT_ONITEMLABEL As Int32 = &H4
Private Const LVHT_ONITEMSTATEICON As Int32 = &H8
<StructLayout(LayoutKind.Sequential)> _
Public Structure POINTAPI
Public x As Int32
Public y As Int32
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure HITTESTINFO
Dim pt As POINTAPI
Dim flags As Long
Dim iItem As Long
Dim iSubItem As Long
End Structure
Can you or anyone please help me to solve this problem?
Sorry for my bad english... 
-
Nov 24th, 2005, 10:43 AM
#4
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.
-
Nov 24th, 2005, 10:49 AM
#5
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.
-
Nov 30th, 2005, 06:31 AM
#6
Thread Starter
Junior Member
Re: file under cursor
 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... 
-
Dec 1st, 2005, 06:54 AM
#7
Re: file under cursor
I believe the declaration should be as follows.
VB Code:
<DllImport("user32", EntryPoint:="SendMessageW")> Private Shared Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal uMsg As Integer, _
ByVal wParam As Integer, _
<MarshalAs(UnmanagedType.LPStruct)> ByRef lParam As Object _
) As Integer
End Function
BTW, Int32's in VB.NET are rather limited - you should use Integer's instead.
-
Dec 1st, 2005, 07:25 AM
#8
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.
-
Dec 1st, 2005, 09:51 AM
#9
Thread Starter
Junior Member
Re: file under cursor
Thanks again for your efforts!
 Originally Posted by penagate
I believe the declaration should be as follows.
VB Code:
<DllImport("user32", EntryPoint:="SendMessageW")> Private Shared Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal uMsg As Integer, _
ByVal wParam As Integer, _
<MarshalAs(UnmanagedType.LPStruct)> ByRef lParam As Object _
) As Integer
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|