WindowFromPoint problem

Macuyiko

New member
Joined
Aug 10, 2007
Messages
2
Programming Experience
3-5
I've been having a problem with the WindowFromPoint API call (using VB.NET 2005) and was hoping somebody could help me.

When I try to get the handle of a window using WindowFromPoint, I always get the same handle, no matter where my cursor is located.

Strangely enough, I'm using a dual monitor setup, when the cursor is on my left monitor, it returns the handle of one of my (desktop-)toolbars (class name: BaseBar), when the cursor is on the right monitor, it returns a handle with class name: SysListView32. I tried removing my toolbars, thinking that might solve the problem, but now both left and right monitors return a (different) handle with class name: SysListView32.

Basically: it always returns the handle of the SysListView32 of the monitor the cursor is in, and Not the window the cursor is in (as it should).

P.S.: I've also tried disabling my second display - no dice.

Any ideas? Thanks in advance.
 
Here is the code I used.

In a nutshell it will get the WindowFromPoint every second and put it in label1. I found that it changed as I moved the cursor. Let me know if it works.

VB.NET:
Public Class Form1

    Public Declare Auto Function WindowFromPoint Lib "user32.dll" (ByVal point As POINT) As IntPtr
    Public Delegate Sub SetText(ByVal Text As String)

    Public Sub Set_Label1_Text(ByVal Text As String)
        If Label1.InvokeRequired Then
            Label1.Invoke(New SetText(AddressOf Set_Label1_Text), Text)
        Else
            Label1.Text = Text
        End If
    End Sub

    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim tmrGo As New Timers.Timer(1000)

        AddHandler tmrGo.Elapsed, AddressOf Tmr_Elapsed

        tmrGo.Start()
    End Sub

    Public Sub Tmr_Elapsed(ByVal sender As Object, ByVal e As Timers.ElapsedEventArgs)
        Dim point As New POINT(Me.Cursor.Position.X, Me.Cursor.Position.Y)

        Set_Label1_Text(WindowFromPoint(point).ToString)
    End Sub
End Class

<System.Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Sequential)> _
Public Structure POINT
    Public X As Integer
    Public Y As Integer

    Public Sub New(ByVal X As Integer, ByVal Y As Integer)
        Me.X = X
        Me.Y = Y
    End Sub
End Structure
 
I've also tested this with multiple monitors and it appeared functional. Here is also an alternate declaration and use of the Forms Timer that you don't have to thread-safe.
VB.NET:
Declare Function WindowFromPoint Lib "user32.dll" (ByVal xPoint As Int32, ByVal yPoint As Int32) As Int32

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    Me.Text = WindowFromPoint(Cursor.Position.X, Cursor.Position.Y)
End Sub
 
Thanks a lot! Your code worked fine and I've figured out why.

When I declare and use my function as such:

VB.NET:
Declare Function WindowFromPoint Lib "user32.dll" (ByVal xPoint As Int32, ByVal yPoint As Int32) As Int32

I have my problem as I described. However, when I use:

VB.NET:
Declare Function WindowFromPoint Lib "user32.dll" (ByVal point As POINT) As IntPtr

The code works fine. All the code samples I had found on other sites were using the (x,y) too, instead of (point). I have no idea why only the second version works (on my system), though :s.

Thanks for the help.
 
There is no difference between these two declarations as far as I know, so I don't see why the other wouldn't work for you. The POINTAPI one is the official, but it couldn't be used in classic VB, that's the reason you find the (x,y) version all around the web.
 
Back
Top