Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Will do here is my import code. I'll be trying the function shortly.

 

   <DllImport("user32.dll", SetLastError:=True)> _
   Shared Function GetClassNameA(ByVal hwnd As IntPtr, ByVal lpClassName As String, ByVal nMaxCount As Integer) As Integer
   End Function

 

Thanks Again

 

ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Posted
<DllImport("user32.dll", SetLastError:=True)> _
Public Shared Function GetClassName(ByVal hwnd As IntPtr, <MarshalAs(UnmanagedType.LPStr)> ByVal buf As StringBuilder, ByVal nMaxCount As Integer) As Integer
End Function


Public Function get_ClassName() As String
     Dim builder1 As New StringBuilder(256)
     Dim num1 As Integer = NativeMethods.GetClassName(Me.Handle, builder1, 256)
     Return builder1.ToString(0, num1)
End Function

Posted

With the code above and this line,

           Dim sClassName As String 
           Dim r As Integer
           r = GetClassNameA(hwnd, sClassName, 100)

 

I was able to return the number 6 but I'm not dure what to do with that ro if it is right.

according to information on the support website they had this.

vb6 code

Dim sClassName As String * 100

 

but .NET doesn't like that. So that is my next step. Any thoughts are welcome.

 

Thanks again

 

ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Posted

Is there a Import that I am missing, stringbuilder is not defined and NativeMethods is comming up Private.

 

Thanks

 

ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Posted

found the import

 

imports system.text

 

Here is the error I am getting too.

 

"System.Drawing.NativeMethods is not accessible in this context because it is private"

 

I'm looking for it now.

 

Thanks

 

ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Posted

Removing "NativeMethods" from the code eliminated the problem and I am now returning the class name. now that I have the class name where am I to use it. I have tried placing it here,

 

Dim PTools_hWnd As IntPtr = FindWindowExA(hwnd, 0, strWinClass, vbNullString) 

 

but all this does is return a zero, I'll have to try some more things.

 

Here is my code so far

 

   Private Sub PT_Command(ByVal strCMD As String)
       Try
           Dim ret As Integer
           Dim Rec1 As Rectangle = New Rectangle
           'Find Window

           Dim returnValue() As Diagnostics.Process

           returnValue = Process.GetProcessesByName(prgWindow)

           Dim hwnd As IntPtr = returnValue(0).MainWindowHandle

           strWinClass = get_ClassName(hwnd)

          Dim PTools_hWnd As IntPtr = FindWindowExA(hwnd, 0, strWinClass, vbNullString) 'finds child windows

           'Get Left, Right, Top and Bottom of Form1
           Dim success As Boolean = GetWindowRect(hwnd, Rec1)
           Debug.WriteLine(String.Format("Rec1={0}", Rec1))

           If Not success Then
               Throw New Win32Exception
           End If

           'GetWindowRect returning zero values
           'Tried both hwnd & PTools_hWnd
           If UCase(strCMD) = "PLAY" Then
               MoveCursor((Rec1.Left + x1), (Rec1.Top + y1))
           ElseIf UCase(strCMD) = "STOP" Then
               MoveCursor((Rec1.Left + x2), (Rec1.Top + y2))
           End If

           If Not SetForegroundWindow(hwnd) Then
               Throw New Win32Exception
           End If

           If newPoint.Equals(Cursor.Position) Then
               mouse_event(2, 0, 0, 0, IntPtr.Zero)
               mouse_event(4, 0, 0, 0, IntPtr.Zero)
           Else
               SendKeys.Send(" ")
           End If

       Catch ex As Exception
           Dim tempData() As String
           Dim I As Integer

           SendKeys.Send(" ")

           tempData = Split(ex.ToString, vbCrLf)
           For I = LBound(tempData) To UBound(tempData)
               TextBox1.AppendText(Now & vbTab & tempData(I) & vbCrLf)
           Next

       End Try
   End Sub

   Private Sub MoveCursor(ByVal Fx As Integer, ByVal Fy As Integer)
       newPoint = New Point(Fx, Fy)
       Debug.WriteLine(String.Format("Old mouse position = {0}.", Cursor.Position))
       Debug.WriteLine(String.Format("Moving mouse to {0}.", newPoint))
       Cursor.Position = newPoint
   End Sub

   Public Function get_ClassName(ByVal intHandle As IntPtr) As String
       Dim builder1 As New StringBuilder(256)
       Dim num1 As Integer = GetClassName(intHandle, builder1, 256)
       Return builder1.ToString(0, num1)
   End Function

 

Thanks again for your help

 

ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Posted

I am Still trying to get the handle of the child window from class name. but I was able to get more info about the window using a freeware program called WinDowse I think it give me more info than spy++.

 

*** Window Information ***************************************

 

Text Playback 1 (1)

Process ID 0000032C

App instance 00400000

Handle 000105B8

Parent handle 000204AA

Control ID 00000000

Function 00000000

Menu handle 00000000

Coords in parent left:82, top:93, right:469, bottom:527

Coords in screen left:82, top:112, right:469, bottom:546

Window size width:387, height:434

Client area size width:379, height:407

Style 94CC0044

Extended style 00010100

ws_overlapped*| ws_popup*| ws_visible*| ws_clipsiblings*| ws_border*|

ws_dlgframe*| ws_sysmenu*| ws_thickframe*| ws_ex_windowedge*| ws_ex_left*|

ws_ex_ltrreading*| ws_ex_rightscrollbar*| ws_ex_controlparent

 

 

*** Class Information ****************************************

 

Name #32770

Function 77D6E54F

Icon 00000000

Small icon 00000000

Cursor 00010013

Bkg brush 00000000

Module handle 77D40000

Style 00004808

cs_dblclks*| cs_savebits*| cs_globalclass

 

This is from the test application I am using that I know has child windows that way I can move it to the primary application I want to use this on.

 

Thanks

 

ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Posted

Update

 

I have been playing with this for the last while and I can't seem to get it to return the correct window. It is returning a child window but not the one I want.

 


Private Declare Function GetWindow Lib "user32" Alias "GetWindow" _
(ByVal hwnd As IntPtr, ByVal wCmd As Integer) As IntPtr

   Private Const GW_CHILD = 5

' in a sub after the main window is found
Testtest = getChildWindow(hwnd)

'the function that is called

   Function getChildWindow(ByVal hwnd As IntPtr) As IntPtr

       Dim cHandle As IntPtr

       getChildWindow = GetWindow(hwnd, GW_CHILD)

   End Function

 

More as events arise, any thoughts?

 

Thanks

 

ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Posted
what's the name of the program you're trying to send mouse clicks to?

 

For testing it is dadpro32.exe by enco it is a broadcast audio system. The one for the final product is ProTools LE (ProToolsLE.exe) an audio editing system. ProTools will only run if the hardware is attached to the computer so I am extremely limited on testing with that application. I want to fire Protools remotely. and this is how I can do it. The spacebar is the shortcut for playing and stopping the editor but if I turn off the switch and the audio has ended it'll start to play again. So that is what I am trying to accomplish. Does this help you out?

 

Thanks

 

ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Posted

Here's code for EnumChildWindows. I converted it to vb using reflector, it's not compilable as is under vb.

 

But the idea is, you need to declare a delegate for EnumChildWindows

to use. When you call EnumChildWindows, it will invoke the delegate each time it reads/finds a new child window. In the code below, it adds it to an ArrayList.

<DllImport("user32.dll", SetLastError:=True)> _
Public Shared Function EnumChildWindows(ByVal window As IntPtr, ByVal callback As EnumWindowsProc, ByVal i As Integer) As Boolean
End Function

<Serializable> _
Public Delegate Function EnumWindowsProc(ByVal handle As IntPtr, ByVal i As Integer) As Boolean

Private ReadOnly ChildWindows As ArrayList


Public Function GetChildWindows() As IntPtr()
     Dim windowArray2 As IntPtr()
     SyncLock Me.ChildWindows
           NativeMethods.EnumChildWindows(Me.Handle, New EnumWindowsProc(AddressOf Me.EnumerateChildProc), 0)
           Dim windowArray1 As IntPtr() = CType(Me.ChildWindows.ToArray(GetType(IntPtr)), IntPtr())
           Me.ChildWindows.Clear
           windowArray2 = windowArray1
     End SyncLock
     Return windowArray2
End Function


Private Function EnumerateChildProc(ByVal Handle As IntPtr, ByVal i As Integer) As Boolean
     Me.ChildWindows.Add(Handle)
     Return True
End Function

Posted (edited)

Private Function EnumerateChildProc(ByVal Handle As IntPtr, ByVal i As Integer) As Boolean
     Me.ChildWindows.Add(Handle)
     Return True
End Function

 

I am working with the code now, I am running into this error when the code above is run.

 

System.NullReferenceException: Object reference not set to an instance of an object

 

So I am a hunting.

 

Side note I know that you have given me alot of help with this and I am slowly catching on. This is my first attempt at a program of this type so it is taking me a little bit longer to digest the code. Thank you for the help you have supplied.

 

Thanks

 

ZeroEffect

Edited by ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Posted

Console app where 5310006 is a handle of one of the instances of vs.net I had open.

 

Imports System
Imports System.Runtime.InteropServices

Module Module1

   <DllImport("user32.dll", SetLastError:=True)> _
   Function EnumChildWindows(ByVal window As IntPtr, ByVal callback As EnumWindowsProc, ByVal i As Integer) As Boolean
   End Function

   <Serializable()> _
   Delegate Function EnumWindowsProc(ByVal handle As IntPtr, ByVal i As Integer) As Boolean


   Sub Main()
       Dim parentHandle As IntPtr = New IntPtr(5310006)
       EnumChildWindows(parentHandle, New EnumWindowsProc(AddressOf EnumWindowsCallBackFunction), 0)
   End Sub

   Function EnumWindowsCallBackFunction(ByVal handle As IntPtr, ByVal i As Integer) As Boolean
       Console.WriteLine("EnumChildWindows Found {0}.", handle)
       Return True
   End Function

End Module

Posted

Progress

 

Well I am able to now return all Child windows very cool. What I am doing is as one is found I grab it heigth and width and compare it to the window I need heigth and width (This window can't be resized) to get it's handle. Sounds great right... Well It grabs and goes through the child windows but it's not finding the one I want. Now using the software I mentention above I looked through the child windows it grabbed and the window I want again is not there but If I look at the window I want, it shows that the window handle for the main program as it's parent. I am not sure what I am Missing here. I do know that the child window I am looking for can exceed the bounds of the parent, it's not trapped in the main window. Is this a different kind of child window? this is on the test app and the app I want to use the program on. I am going through the msdn site now looking for some answers.

 

Thanks

 

ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Posted
The EnumChildWindows may not be recusive, so you may have to search the children of the children may making a call to EnumChildWindows on each child window found.
Posted
The EnumChildWindows may not be recusive' date=' so you may have to search the children of the children may making a call to EnumChildWindows on each child window found.[/quote']

 

 

Thanks, that was my next step and here is the result Only one of the Child windows found has a sibling and it is an edit window for a combo box. Man this is a pain, lol. So I am now I'm not sure where to go from here, Any ideas. What if this window is opened in another thread, would that make a difference?

 

Thanks

 

ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Posted

I would use spy++ to get the handle of the window you want and then call EnumChildWindows recursively and see if it finds it.

 

As long as the windows belong to the same application, it won't matter which thread it's in. All input is processed by one thread in gui apps... The message pump thread.

Posted
I would use spy++ to get the handle of the window you want and then call EnumChildWindows recursively and see if it finds it.

 

As long as the windows belong to the same application, it won't matter which thread it's in. All input is processed by one thread in gui apps... The message pump thread.

 

This is how I have done it but it isn't found is there a better way of doing this?

 

   Public Function GetChildWindows(ByVal whnd As IntPtr) As IntPtr()

       EnumChildWindows(whnd, New EnumWindowsProc(AddressOf Me.EnumerateChildProc), 0)
    
   End Function


   Private Function EnumerateChildProc(ByVal Handle As IntPtr, ByVal i As Integer) As Boolean

       EnumChildWindows(Handle, New EnumWindowsProc(AddressOf Me.EnumerateSiblingProc), 0)

       Return True
   End Function

   Private Function EnumerateSiblingProc(ByVal Handle As IntPtr, ByVal i As Integer) As Boolean
       Dim rec1 As New Rectangle
       GetWindowRect(Handle, rec1)
       Dim WindowName As Integer = Convert.ToInt32("000103D6", 16) 'hex from Spy++
       Dim int32Handle As String = Handle.ToInt32
       'WindowFound = Handle
       If int32Handle = WindowName Then
           MsgBox("Match")

            WindowFound = Handle

       End If
       Return True
   End Function

 

Thanks

 

ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Posted

Console app. I knew the handle of a deeply nested child window. Here's code to recursively call enumchildwindow.

 

Imports System
Imports System.Collections
Imports System.Runtime.InteropServices

Module Module1

   <DllImport("user32.dll", SetLastError:=True)> _
   Function EnumChildWindows(ByVal window As IntPtr, ByVal callback As EnumWindowsProc, ByVal i As Integer) As Boolean
   End Function

   <DllImport("user32.dll", SetLastError:=True)> _
   Function GetDesktopWindow() As IntPtr
   End Function

   <Serializable()> _
   Delegate Function EnumWindowsProc(ByVal handle As IntPtr, ByVal i As Integer) As Boolean


   Private childWindows As ArrayList

   Sub Main()
       'arraylist to store handles of found child window.
       childWindows = New ArrayList

       'the child handle I want to look for.
       Dim childHandle As New IntPtr(4129470)

       'search the desktop's child windows.
       EnumChildWindows(GetDesktopWindow, New EnumWindowsProc(AddressOf EnumerateChildProc), 0)

       'output stats n facts.
       Console.WriteLine("Desktop has {0:N0} child window(s).", childWindows.Count)
       Console.WriteLine("Requested child window found: {0}", childWindows.Contains(childHandle))

   End Sub

   Private Function EnumerateChildProc(ByVal childWindowHandle As IntPtr, ByVal i As Integer) As Boolean
       'add the child window's handle to the collection.
       childWindows.Add(childWindowHandle)

       'do stuff here if you want like check the properties of the child window
       'if it's the window you want, just 'Return True' because there's no need
       'to continue searching.

       'do a recursive call to retrieve the child window handles of the child window.
       EnumChildWindows(childWindowHandle, New EnumWindowsProc(AddressOf EnumerateChildProc), 0)

       Return True
   End Function

End Module

 

Inside the EnumerateChildProc function, I would place code to determine if the childwindow is the window you want. If not, call EnumerateChildProc on the childwindow.

  • 2 weeks later...
Posted

So here is what is going on. I'm still unable to return this window, but there is a update availible for the software and they have built the window I want to find into the main window. Upside I'll be able to do what I wanted to do, downside I wasn't able to find the window I was looking for. Thank for your help and I did learn alot about finding windows and such.

 

Thanks again,

 

ZeroEffect

If you can't find it, Build It.

 

There is no place Like 127.0.0.1 also don't forget 1 + 1 = 10

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...