Working with External Window Handles in Visual Basic
WEBINAR: On-demand webcast
How to Boost Database Development Productivity on Linux, Docker, and Kubernetes with Microsoft SQL Server 2017 REGISTER >
Today, I will show you how easy it is to work with an external window.
The Windows API is a set of several hundred functions and subroutines that are located in a set of files called Dynamic Link Libraries (DLLs). You can make a function from the Windows API available to your Visual Basic program by declaring the function to be callable from your program. You then can use the Windows API function as you would any built-in Visual Basic function or a function that you have written yourself.
Windows API Library FilesThe Dynamic Link Library (DLL) files that make up the Windows API are commonly located in the Windows SYSTEM subdirectory. These files are found on every PC that is running Windows, so you don't have to worry about including them if you create a set of setup disks for distribution. The three Windows DLLs are User32.DLL, Kernel32.DLL, and GDI32.DLL.
Several smaller DLLs, known as Extension DLLs, provide functions in addition to those found in the three major DLLs. Some useful extension DLLs include the following:
- Advapi32.dll: Advanced API services library supporting numerous APIs, including many security and Registry calls
- Comdlg32.dll: Common dialog API library
- Lz32.dll: 32-bit compression routines
- Mpr.dll: Multiple Provider Router library
- Netapi32.dll: 32-bit Network API library
- Shell32.dll: 32-bit Shell API library
- Version.dll: Version library
- Winmm.dll: Windows multimedia library
- Winspool.drv: Print spooler interface that contains the print spooler API calls
Indicates that the attributed method is exposed by an unmanaged dynamic-link library (DLL) as a static entry point. The DllImport attribute provides the information needed to call a function exported from an unmanaged DLL. As a minimum requirement, you must supply the name of the DLL containing the entry point. The DllImport attribute specifies that the target method is an export from an unmanaged shared library such as the Win32 API.
Imports System.Runtime.InteropServices <DllImport("KERNEL32.DLL", _ EntryPoint := "MoveFileW", _ SetLastError := True, _ CharSet := CharSet.Auto, _ ExactSpelling := True, _ CallingConvention := CallingConvention.StdCall)> _ Public Shared Function MoveFile(src As String, _ dst As String) _ As Boolean ' Leave function empty - DLLImport attribute forwards ' calls to MoveFile to MoveFileW in KERNEL32.DLL. End Function
More Info on DLLImport.
There isn't much of a design. Start a new VB Windows Forms project and add two buttons to the form. You may name the objects anything you desire.
The purpose of today's little application is just to manipulate the Notepad window. You may now open Notepad, as we will use it during the course of this program.
Add the Interopservices Namespace:
' Used with APIs Imports System.Runtime.InteropServices
We use the InteropServices namespace for dealing with APIs.
Add the following API Constant:
' Minimize constant Private Const SW_SHOWMINIMIZED As Int32 = 2
This will let the external window (Notepad) show in a minimized state.
Add the two APIs we will be using:
<DllImport("user32.dll", EntryPoint:="ShowWindow", _ CharSet:=CharSet.Auto)> _ Private Shared Function ShowWindow(ByVal hwnd As Int32, _ ByVal nCmdShow As Int32) As Int32 End Function 'ShowWindow API <DllImport("user32.dll", EntryPoint:="MoveWindow", _ CharSet:=CharSet.Auto)> _ Public Shared Function MoveWindow(ByVal hWnd As IntPtr, _ ByVal X As Int32, _ ByVal Y As Int32, _ ByVal nWidth As Int32, _ ByVal nHeight As Int32, _ ByVal bRepaint As Boolean _ ) As Boolean End Function
ShowWindow will display the external window with the handle that will get determined. MoveWindow can be used to move the external window, and even resize it!
Add the subs for the two buttons:
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click 'Get Notepad's handle Dim NoteProc() As Process = _ Process.GetProcessesByName("notepad") ' Minimize If NoteProc.Length > 0 Then _ ShowWindow(NoteProc(0).MainWindowHandle, _ SW_SHOWMINIMIZED) End Sub Private Sub Button2_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button2.Click ' Get Notepad's handle Dim NoteProc() As Process = _ Process.GetProcessesByName("notepad") ' Resize MoveWindow(NoteProc(0).MainWindowHandle, 10, 10, _ 200, 300, True) End Sub
With the first button, I initially determined whether there is in fact a Notepad window open. Based on that, I get its handle and minimize it. The second button simply resizes the Notepad window.
For more information on dealing with external window handles, have a read through this article.
I have attached a working sample for you to play with.
Short and sweet. I hope you have learned from today's article. Until next time, let me go get something ice cold to drink…