Working with Win32 API in .NET


Windows exposes lots of functionality in the form of Win32 API. Using these API you can perform direct operation in windows, which increases performance of your application. Now you might have question in your mind that What is API?

What is an API?

API (Application Program Interface) is a set of predefined Windows functions used to control the appearance and behavior of every Windows element (from the outlook of the desktop window to the allocation of memory for a new process). Every user action causes the execution of several or more API function telling Windows what's happened.

It is something like the native code of Windows. Other languages just act as a shell to provide an automated and easier way to access APIs. In .NET we can call Win 32 API using platform Interop Services, which resides at System.Runtime.InteropServices namespace.

Whenever you perform any task in window, it gets executed by giving one or more calls to windows API. Say for example when you press a button on the form, windows sends a message to your windows procedure that eventually hidden from the user.

The windows API resides in the DLL's like User32.dll, GDI32.dll, Shell32.dll etc in the windows system directory. These basic win32 API's are splits into three different flavors, depending on code resides in them.

The separation is as follows

  • User32.dll - handles user interface stuff 
  • Kernel32.dll - file operations, memory management 
  • Gdi32.dll - involved in graphical whatnots 

These three files are collectively known as the 'Win32 API' - in other words, the main collection of accessible Windows 95/98 code.

But there are a few other DLL files available too, including:

  • Comdlg32.dll - holds all regular dialog boxes, etc 
  • Winmm.dll - does all the groovy multimedia thingies 

There are many more API are available which you can use in your programming.

Now I am coming to how can use these Win32 API in your .NET application to enjoy the luxury of Win32 API. I am covering these usage is some steps them we will go and discuss some live example which will show you beauty of Win32 API.

Let us start with API Declaration, As I mention earlier .NET has Interop Services to work with external DLL's. So by use of Syetem.Runtime.InteropServices namespace in your application you get some functionality by which you can make a call to external application.

using System;
using System.Runtime.InteropServices;
namespace Win32Application
{
/// <author>Shrijeet Nair</author>
public class Win32
{
[DllImport("User32.dll")]
public static extern Int32 FindWindow(String lpClassName,String lpWindowName);
}

Let us discuss the code: In above code I have taken two namespace one of them is System.Runtime.InteropServices, Which is useful when you are interacting with external application.

[DllImport("User32.dll")]

This statement will import the user32.dll in your program after that you can make use of its function in your program.

public static extern Int32 FindWindow(String lpClassName,String lpWindowName);

Before using any external function in .NET you have to declare that function in your program. In above statement we are trying to use FindWindow function of User32.dll.While declaring such a function we prefix extern keyword with that, which indicate that the declared function is an external function.

Now you might be thinking of what is FindWindow and what it does for us. So let us discuss some of Win32 API function to make our self-comfortable. I can't discuss all the Win32 API because it has got hundreds of function and even I don't know all.

FindWindow

An application can use this function to locate the first top-level window in the Z order that matches the given class and window title. The application can specify a particular class, a particular title, both, or neither. If the application specifies neither a class name nor a window title, the FindWindow function returns the top-level window, which is the highest in the Z order. An application cannot use the FindWindow function to locate windows farther down in the Z order after the first matching window is found.

EnumChildWindows

An application can use this function to have Windows call an application-supplied callback function for each child window of a given window. Windows enumerates all child windows, including children of child windows. Windows does not call the callback function for any child windows created after EnumChildWindows is called but before it returns.

EnumWindows

An application can use this function to have Windows call an application-supplied callback function for each top-level window. Windows enumerates all top-level windows, including owned and non-owned windows. Windows does not call the callback function for any top-level windows created after EnumWindows is called but before it returns.

GetDesktopWindow

This function returns the handle to the desktop window.

SetForegroundWindow

The SetForegroundWindow function puts the thread that created the specified window into the foreground and activates the window.Keyboard input is directed to the window, and various visual cues are changed for the user.

SendMessage

The SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts a message to a thread's message queue and returns immediately.

GetWindowText

The GetWindowText function copies the text of the specified window's title bar (if it has one) into a buffer. If the specified window is a control, the text of the control is copied.

GetWindowTextLength

The GetWindowTextLength function retrieves the length, in characters, of the specified window's title bar text (if the window has a title bar). If the specified window is a control, the function retrieves the length of the text within the control.

GetWindow

The GetWindow function retrieves the handle of a window that has the specified relationship (Z order or owner) to the specified window.

Now let us discuss some practical example where we can use of some of these functions. Our example is about reading value of all available controls from a running example. Our example contains following classes

Calling Window : Calling window is a form, from which we are require reading its control value.
Win32 class : Win 32 class contains definition of all required API's.

Main Form : Main form is a controller application by which we will perform the action for reading calling window controls.

Let us discuss Win32 class first.

using System;
using System.Text;
using System.Runtime.InteropServices;
namespace Win32Application
{
/// <author>Shrijeet Nair</author>
public class Win32
{
[DllImport("User32.dll")]
public static extern Int32 FindWindow(String lpClassName,String lpWindowName);
[DllImport("User32.dll")]
public static extern Int32 SetForegroundWindow(int hWnd);
[DllImport("User32.dll")]
public static extern Boolean EnumChildWindows(int hWndParent,Delegate lpEnumFunc,int lParam);
[DllImport("User32.dll")]
public static extern Int32 GetWindowText(int hWnd,StringBuilder s,int nMaxCount);
[DllImport("User32.dll")]
public static extern Int32 GetWindowTextLength(int hwnd);
[DllImport("user32.dll", EntryPoint="GetDesktopWindow")]
public static extern int GetDesktopWindow();
}
}

Now let me discuss main logic of our application.

int hWnd;
public delegate int Callback(int hWnd,int lParam);
Callback myCallBack =
new Callback(EnumChildGetValue);
hWnd = Win32.FindWindow(
null,"CallingWindow");
if(hWnd == 0)
{
MessageBox.Show("Please Start Calling Window Application");
}
else
{
Win32.EnumChildWindows(hWnd,myCallBack,0);
}

public
int EnumChildGetValue(int hWnd,int lParam)
{
StringBuilder formDetails =
new StringBuilder(256);
int txtValue;
string editText="";
txtValue =Win32.GetWindowText(hWnd,formDetails,256);
editText = formDetails.ToString().Trim();
MessageBox.Show("Contains text of contro:"+ editText);
return 1;
}

Explanation of Code:

The core functionality used by this code is EnumChildWindows functions of User32.dll. The EnumChildWindows enumerate the window and find out its all child control by which you can get handle of child control and can read value of the controls.

In this code I have used the delegate for callback function and for buffering the string I have used String Buffer.

hWnd = Win32.FindWindow(null,"CallingWindow");

Here hWnd is a handle of calling window.

Note: The Second parameter of FindWindow must be title of calling window.

Win32.EnumChildWindows(hWnd,myCallBack,0);

EnumChildWindows enumerate the calling window by use of its handle and call EnumChildGetValue for each control.

EnumChildGetValue will take the handle of child control and display value of it in a MessageBox.txtValue =Win32.GetWindowText(hWnd,formDetails,256);

GetWindowText enumerate text value of the handle. 

Guideline for creating calling window

Create normal window application and create a form, which would contain some command button and some text box with some default text in it. Also make sure that your window title must match with the second parameter of FindWindow.

Also execute the calling application first than invoke your main application. Keep main operation on click of some button in main Application.

Conclusion

Win32 API provides wide range of functionality. By just making use of these functionality we can make our code simpler and efficient.


Similar Articles