Asked By
Johana
250 points
N/A
Posted on - 05/17/2011
We have a finance application, that has many buttons and controls. There is a screen in the application that shows a lengthy list of reports in a big List Box. Every time we need to run a report, we have to scroll and select the required reports. This is taking a huge amount of time as we have to dig through this list.
I have heard that you can write a program that could send commands to another application. What I want to do is to write a small program that will accept a list of reports from the user via typing them and then automatically selecting them in the finance application.
For this I need read the values of the remote application.
How can I do this ?
Answered By
Edvard
0 points
N/A
#99587
How to read values off a list box control?
You need to use the Windows Messaging system via the Windows Application Program Interface to interact with another Windows application. This method is commonly known as Win32 API. The Win32 API defines a set of methods that you can use to query the Operating System and send messages to each application.
How it works is that each interactive element on a Windows desktop is actually a "Window". A text box , list box are all small windows. What is required is to get the memory pointer (Windows Handle) to the required window and send a message to it.
The Windows Application Programming Interface was mainly targeted for C++ programs. However, you can call these methods via other programming languages subject to those programming languages being able to support interactivity with the Windows liberties to invoke the methods. In Microsoft .Net you can call the Win32 API methods in VB or C# by declaring the required function as a function delegate into your project. Then you call the function with the required set of parameters.
Answered By
Johana
250 points
N/A
#99589
How to read values off a list box control?
I have heard about Win32 API calls. But I really have not used it in my experience. I always thought that it is only limited to C++! How can I use it in VB.Net ? I am hoping to write a desktop application in VB.Net.
Using Windows API method calls, can I manipulate any program? Is it dangerous and un-stable? Would it cause problems to the Operating System and crash it? Is there any other way that I can automate another program without using it?
Answered By
Ingrid
0 points
N/A
#99590
How to read values off a list box control?
Win32 API is required if you want to manipulate a program. There is no other method without modification to the original program. It becomes dangerous only if you do not use it correctly for your purpose. The Windows API is designed to enable sending interactive commands to the computer programs. It sits between the user input devices and the application program. Whenever you hit a key on the keyboard, the Win32 API system traps it, finds the current window that is in focus and sends the message to that window with the keyboard stroke as an input.
Similarly, when a mouse is clicked the event is trapped by the Win32 API system and then it is sent to the current application for which the click is intended. What happens is Win32 API finds the window under the current mouse coordinates, gets the handle for it and sends the clicked event message to it.
What you are basically going to do in your .Net application is to put the manual entries into source code i.e. you are going to manually send messages to the remote program and read values off its visible interface.
Answered By
Mathias
0 points
N/A
#99591
How to read values off a list box control?
You must be careful when using Win32 API calls. This is because you are going to use memory pointers that are not inside the Microsoft .Net Framework managed user space. This means, if anything crashes, it will be your program first and then the target program.
For example if you were to send a mouse click event to the remote application, there are 2 messages you need to send in order to complete the click event. First one is the mouse button down event, and then the mouse button up event. If you forget to send the mouse button up event, the target program will act as if the mouse button is still depressed. This is what people term as "un-stable and dangerous".
If you carefully choose and execute the chain of methods properly, then you should not get any problem at all. The hardest part is finding the required methods to achieve you requirement.
Answered By
Edvard
0 points
N/A
#99592
How to read values off a list box control?
You can use the following methods to interact with the remote program:
 The first thing you need to do is to get the handle to the current active window. For this you need to know the "title" and the "window class". You can get the required information by using the Spy++ tool that ships with Microsoft Visual Studio as a bundled tool.
Declare Auto Function FindWindow Lib "USER32.DLL" (ByVal lpClassName As String,ByVal lpWindowName As String) As IntPtr
The only controls that do not have a window handle are label controls. Label controls are painted in the canvas and do not receive any events. Once you gain a pointer to the main window, you need to get the target child control. Each child control is also a window by itself. To send a message to the target control, you import and use the SendMessage function defined in the Windows User 32 library.
Private Declare Function SendMessage Lib "USER32.DLL" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
Messages are actually well defined integer values. To read data off a list box you need the following set of constants.
Public Enum enListboxMessages
LB_GETCOUNT = &H18B
LB_GETTEXT = &H189
End Enum
Before reading the list of items in the text box, you need to retrieve the count of items in it. After that you do a loop and collect the list of items in it.
Dim cTotItems As Integer = SendMessage(targetControl, enListboxMessages.LB_GETCOUNT, 0, 0)
Dim listItems As Dictionary(Of Integer, String) = New Dictionary(Of Integer, String)
For i As Integer = 0 To cTotItems – 1
Dim itemText As New StringBuilder(256)
SendMessageStr(targetControl, enListboxMessages.LB_GETTEXT, i, itemText)
listItems.Add(i, itemText.ToString().ToLower())
Next
Using the above you should be able to get about your program.
Answered By
Johana
250 points
N/A
#99593
How to read values off a list box control?
I was able to use the SendMessage API call to query the items in the listbox.
This is simply great! I noticed that you are using a SendMessageStr method. How is it defined and why?
Answered By
Edvard
0 points
N/A
#99594
How to read values off a list box control?
SendMessage API is actually overloaded in the Windows Application Programming Interface. While C++ supports dynamic inference in multiple method calls, the Microsoft .Net Framework does not. Microsoft .Net Framework only supports dynamic inference for its own method calls.
Microsoft .Net is a strongly typed language. That is each variable or parameter need to be clearly defined. The SendMessage API call can receive different values as parameters. But when you are using the method inside your managed code you need to clearly define the method signature. To avoid confusing, you simple re-declare the function under a different name and put the required classes in the parameters. Following are examples on the variations of the SendMessage API when it is used in VB.Net
Private Declare Function SendMessage Lib "USER32.DLL" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
Private Declare Function SendMessageStr Lib "USER32.DLL" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As StringBuilder) As Integer
Private Declare Function SendMessageIntArray Lib "USER32.DLL" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam() As Integer) As Integer
As you can see, all the three definitions point to the same entry point in the User 32 library, but the parameters are well defined so that there will not be any problems in passing parameters.
Answered By
Johana
250 points
N/A
#99595
How to read values off a list box control?
SendMessage API worked for reading values off a List Box of a remote application.
Thank you all for your valuable advice and time.
I learnt a lot. I will keep reading about the Windows 32 API system as my project progresses.
Thank you again!