PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197

PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
Get window position-VBForums
Results 1 to 8 of 8

Thread: Get window position

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Jan 2011
    Posts
    18

    Get window position

    Hello,

    I am trying to get top position and the size from a program with vb 2010, but it wont work. Does anyone know whats wrong with my code and how to solve the problem?

    Code:
    Option Explicit On
    Option Strict On
    
    Imports System.Runtime.InteropServices
    Public Class Form1
    
        Public Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hwnd As Long, ByVal lpRect As RECT) As Long
    
        <DllImport("user32.dll", CharSet:=CharSet.Auto, EntryPoint:="FindWindow")> _
        Private Shared Function FindWindow( _
         ByVal lpClassName As String, _
         ByVal lpWindowName As String) As IntPtr
        End Function
    
        Public Structure RECT
            Public bottom As Integer
            Public top As Integer
            Public left As Integer
            Public right As Integer
        End Structure
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim nPad As IntPtr
            Dim rectw As RECT
            nPad = FindWindow(vbNullString, "Calculator")
            GetWindowRect(nPad.ToInt64, rectw)
            MsgBox(rectw.top)
            If nPad.ToInt32 > 0 Then
                MessageBox.Show("Calculator Found", "Demo", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MessageBox.Show("Calculator Not Found", "Demo", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            End If
        End Sub
    End Class

  2. #2
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: Get window position

    The problem is in your API declaration of "GetWindowRect". The handle is passed as HandleRef, not IntPtr.

    Code:
    Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As System.Runtime.InteropServices.HandleRef, ByRef lpRect As RECT) As Boolean
    Here some code using it:
    Code:
        Public Property HandleRef() As Runtime.InteropServices.HandleRef
            Get
                Return New Runtime.InteropServices.HandleRef(Me, Me.hwnd)
            End Get
            Set(ByVal value As Runtime.InteropServices.HandleRef)
                Me.hwnd = value.Handle
            End Set
        End Property
    
        Public Property Bounds() As Rectangle
            Get
                Dim r As RECT
                If (GetWindowRect(Me.HandleRef, r)) Then
                    Return r.Value
                Else
                    Return Nothing
                End If
            End Get
            Set(ByVal value As Rectangle)
                SetWindowPos(Me.hwnd, -2, value.X, value.Y, value.Width, value.Height, SWP.IgnoreZOrder)
            End Set
        End Property
    I use the following RECT structure in my test codes:
    Code:
        Public Structure RECT
            Public Left, Top, Right, Bottom As Integer
            Sub New(ByVal r As Rectangle)
                Me.Value = r
            End Sub
            Public Property Value() As Rectangle
                Get
                    Return New Rectangle(Left, Top, Right - Left, Bottom - Top)
                End Get
                Set(ByVal value As Rectangle)
                    Me.Left = value.Left
                    Me.Right = value.Right
                    Me.Top = value.Top
                    Me.Bottom = value.Bottom
                End Set
            End Property
        End Structure
    (Since your RECT declaration is faulty as well)

    If the error still occurs, call this function in your code to add a "breakpoint" with an error:
    Code:
        <DebuggerStepThrough()> _
        Public Shared Sub HandleError()
            If Marshal.GetLastWin32Error() <> 0 Then
                Throw New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error())
            End If
        End Sub

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Jan 2011
    Posts
    18

    Re: Get window position

    I tried to put my code in your code, but this wasn't successful.
    Maybe its a bit noobie from me but i don't know how to use it.

  4. #4
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: Get window position

    You can always look at the class in my signature (Window container class), but it is pretty much the same as I described previously.

    Anyway, your code would look somewhat like this:
    Code:
    Imports System.Runtime.InteropServices
    Public Class Form1
    
        Public Declare Function GetWindowRect Lib "user32" (ByVal hWnd As HandleRef, ByRef lpRect As RECT) As Boolean
    
        <DllImport("user32.dll", CharSet:=CharSet.Auto, EntryPoint:="FindWindow")> _
        Private Shared Function FindWindow( _
         ByVal lpClassName As String, _
         ByVal lpWindowName As String) As IntPtr
        End Function
    
        Public Structure RECT
            Public Left, Top, Right, Bottom As Integer
            Public Function ToRectangle() As Rectangle
                Return New Rectangle(Left, Top, Right - Left, Bottom - Top)
            End Function
        End Structure
    
        <DebuggerStepThrough()> _
        Public Shared Sub HandleError()
            If Marshal.GetLastWin32Error() <> 0 Then
                Throw New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error())
            End If
        End Sub
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim nPad As IntPtr
            Dim rectw As RECT
            nPad = FindWindow(vbNullString, "Calculator")
            GetWindowRect(new HandleRef(Me, nPad), rectw)
            HandleError() 'if the line above it failed it will raise the error here
            Debug.WriteLine(rectw.ToRectangle()) 'print the bounds to the console
            If nPad.ToInt32 > 0 Then
                MessageBox.Show("Calculator Found", "Demo", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MessageBox.Show("Calculator Not Found", "Demo", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            End If
        End Sub
    End Class

  5. #5

    Thread Starter
    Junior Member
    Join Date
    Jan 2011
    Posts
    18

    Re: Get window position

    I got this error:
    System.ComponentModel.Win32Exception was unhandled
    ErrorCode=-2147467259
    Message=Een initialisatieroutine van de dynamic link library (DLL-bestand) is mislukt
    NativeErrorCode=1114
    Source=dockwindow
    StackTrace:
    at dockwindow.Form1.HandleError() in K:\bots\dockwindow\dockwindow\Form1.vb:line 22
    at dockwindow.Form1.Form1_Load(Object sender, EventArgs e) in K:\bots\dockwindow\dockwindow\Form1.vb:line 31
    at System.EventHandler.Invoke(Object sender, EventArgs e)
    at System.Windows.Forms.Form.OnLoad(EventArgs e)
    at System.Windows.Forms.Form.OnCreateControl()
    at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
    at System.Windows.Forms.Control.CreateControl()
    at System.Windows.Forms.Control.WmShowWindow(Message& m)
    at System.Windows.Forms.Control.WndProc(Message& m)
    at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
    at System.Windows.Forms.Form.WmShowWindow(Message& m)
    at System.Windows.Forms.Form.WndProc(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    at System.Windows.Forms.SafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow)
    at System.Windows.Forms.Control.SetVisibleCore(Boolean value)
    at System.Windows.Forms.Form.SetVisibleCore(Boolean value)
    at System.Windows.Forms.Control.set_Visible(Boolean value)
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
    at dockwindow.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    at System.Threading.ThreadHelper.ThreadStart()
    InnerException:

  6. #6
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    22,827

    Re: Get window position

    this should work. i can't say i've ever come across bergerkiller's handleref before:

    vb Code:
    1. Option Explicit On
    2. Option Strict On
    3.  
    4. Imports System.Runtime.InteropServices
    5. Public Class Form1
    6.  
    7.     Public Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hwnd As intptr, ByVal lpRect As RECT) As Long
    8.  
    9.     <DllImport("user32.dll", CharSet:=CharSet.Auto, EntryPoint:="FindWindow")> _
    10.     Private Shared Function FindWindow( _
    11.      ByVal lpClassName As String, _
    12.      ByVal lpWindowName As String) As IntPtr
    13.     End Function
    14.  
    15.     Public Structure RECT
    16.         Public bottom As Integer
    17.         Public top As Integer
    18.         Public left As Integer
    19.         Public right As Integer
    20.     End Structure
    21.  
    22.     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    23.         Dim nPad As IntPtr
    24.         Dim rectw As New RECT
    25.         nPad = FindWindow(vbNullString, "Calculator")
    26.         GetWindowRect(nPad, rectw)
    27.         MsgBox(rectw.top)
    28.         If nPad.ToInt32 > 0 Then
    29.             MessageBox.Show("Calculator Found", "Demo", MessageBoxButtons.OK, MessageBoxIcon.Information)
    30.         Else
    31.             MessageBox.Show("Calculator Not Found", "Demo", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    32.         End If
    33.     End Sub
    34. End Class

    edit: that should be:
    vb Code:
    1. Public Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hwnd As intptr, ByRef lpRect As RECT) As integer
    Last edited by .paul.; Jul 15th, 2011 at 07:04 AM.

  7. #7
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: Get window position

    Neither did I, and that is the odd bit. GetWindowRect only worked with me when I used a HandleRef there. When I used the IntPtr it failed.

    Same for the following functions:
    Code:
        Private Declare Function GetClientRect Lib "user32" (ByVal hWnd As System.Runtime.InteropServices.HandleRef, ByRef lpRect As API.WRECT) As Boolean
        <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetWindowLong")> _
        Private Shared Function GetWindowLongPtr32(ByVal hWnd As Runtime.InteropServices.HandleRef, ByVal nIndex As Integer) As Long
        End Function
        <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetWindowLongPtr")> _
        Private Shared Function GetWindowLongPtr64(ByVal hWnd As Runtime.InteropServices.HandleRef, ByVal nIndex As Integer) As Long
        End Function
    It only seems to count for some of the "Get" functions, the Set functions use a regular IntPtr. Any idea why it restricts me to using a HandleRef?

    (I thought it was an "API Thing", but since you're a professional I start to doubt this)

    Wraps a managed object holding a handle to a resource that is passed to unmanaged code using platform invoke.
    Also PInvoke.net says:
    <DllImport("user32.dll")> _
    Private Shared Function GetWindowRect(ByVal hWnd As HandleRef, ByRef lpRect As RECT) As Boolean
    End Function

  8. #8
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    22,827

    Re: Get window position

    ok. I investigated it.

    IntPtr is just a simple integer-based struct that can hold a pointer (ie., 32 bit size on 32-bit systems, 64-bit size on 64-bit systems).

    HandleRef is a way to make sure that an unmanaged handle is not GC'ed when you're in the middle of a P/Invoke call.

Posting Permissions

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



Featured


Click Here to Expand Forum to Full Width