SUMMARY
This step-by-step article describes how to disable the
Close button on the title bar of a console application. To do this,
you must declare references to external procedures that are members of the
User32.dll file, obtain a handle to the system menu of the console application,
and then delete the
Close menu item from the system menu of the console application.
Note The whole source code is available in the "Complete code listing
(Module1.vb)" section.
Requirements
The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:
- Microsoft Windows 2000, Microsoft Windows XP, or Microsoft
Windows Server 2003
- Microsoft Visual Basic 2005 or Microsoft Visual Basic .NET
This article assumes that you are familiar with the following topics:
- Visual Basic 2005 or Visual Basic .NET
- Writing unmanaged code in Visual Basic 2005 or in Visual Basic .NET
Declare references to external procedures that are in User32.dll
- Run Microsoft Visual Studio 2005 or Microsoft Visual Studio .NET.
- Point to New on the File
menu, and then click Project.
- Under Project Types, click to select
Visual Basic Projects.
Note In Visual Studio 2005, click to select
Visual Basic instead of Visual Basic Projects. - Under Templates, click to select
Console Application.
- In the Name text box, type
MyConsoleApplication, and then click
OK.
By default, Module1.vb is created. - If the following code is not added by default when the
you create the project,
add the following code to Module1.vb before the Module Module1 statement.
Option Strict On
- Add the following code to Module1.vb before the Sub Main statement.
' Declaring references to external procedures that are in user32.dll.
Private Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Integer, _
ByVal uPosition As Integer, ByVal uFlags As Integer) As Boolean
Private Declare Function GetForegroundWindow Lib "user32" () As Integer
Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Integer, _
ByVal bRevert As Boolean) As Integer
Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Integer, _
ByVal uCmd As Integer) As Integer
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hWnd As Integer, ByVal lpString As String, ByVal nMaxCount As Integer) As Integer
Obtain a handle to the console application window
- Append the following code to Module1.vb after the End Sub statement.
Private Function ObtainWindowHandle(ByVal lpstrCaption As String) As Integer
' To store the handle to a window.
Dim hWnd As Integer
' Maximum number of characters in the GetWindowText method.
Dim nMaxCount As Integer
' Actual number of characters copied in the GetWindowText method.
Dim nCopiedLength As Integer
' To store the text of the title bar of the window.
Dim lpString As String
nMaxCount = 255
' Obtain a handle to the first window.
hWnd = GetForegroundWindow
' Loop through the various windows until you encounter the console application window, _
' or there are no more windows.
While hWnd <> 0
' Fill lpString with spaces.
lpString = Space(nMaxCount)
' Get the text of the title bar of the window in lpString.
nCopiedLength = GetWindowText(hWnd, lpString, nMaxCount)
' Verify that lpString is neither empty, nor NULL.
If Len(Trim(lpString)) <> 0 And Asc(Trim(lpString)) <> 0 Then
' Verify that the title of the retrieved window is the same as the title of the console application window.
If CType(InStr(Left(lpString, nCopiedLength), lpstrCaption), Boolean) Then
' Return hWnd to the Main method.
Return hWnd
End If
End If
' Get the next window.
hWnd = GetWindow(hWnd, 2)
End While
' If no corresponding windows are found, return 0.
Return 0
End Function
- Add the following code to Module1.vb, after the Sub Main statement.
' Obtain a handle to the console application window by passing the title of your application.
Dim hWnd As Integer = ObtainWindowHandle("<MyConsoleApplication>")
Note Replace <MyConsoleApplication> with the name of your console application.
You can also use the
FindWindow function to obtain a handle to the console application window.
For more information about
FindWindow, visit the following Microsoft Developer Network (MSDN) Web site:
Obtain a handle to the console application system menu
Append the following code to Module1.vb before the
End Sub statement.
' Obtain a handle to the console application system menu.
Dim hMenu As Integer = GetSystemMenu(hWnd, False)
Delete the Close
menu item from the console application system menu
Append the following code to Module1.vb before the
End Sub statement, and then click
Save All on the
File menu.
' Delete the Close menu item from the console application system menu.
' This will automatically disable the Close button on the console application title bar.
' 6 indicates the position of the Close menu item.
' 1024 indicates that the second parameter is a positional indicator.
DeleteMenu(hMenu, 6, 1024)
System.Console.WriteLine("Press ENTER to quit")
' Wait for the user to press the ENTER key.
System.Console.ReadLine()
Complete code listing (Module1.vb)
Option Strict On
Module Module1
' Declaring references to external procedures that are in user32.dll.
Private Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Integer, _
ByVal uPosition As Integer, ByVal uFlags As Integer) As Boolean
Private Declare Function GetForegroundWindow Lib "user32" () As Integer
Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Integer, _
ByVal bRevert As Boolean) As Integer
Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Integer, _
ByVal uCmd As Integer) As Integer
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hWnd As Integer, ByVal lpString As String, ByVal nMaxCount As Integer) As Integer
Sub Main()
' Obtain a handle to the console application window by passing the title of your application.
' Replace <MyConsoleApplication> with the name of your Console Application.
Dim hWnd As Integer = ObtainWindowHandle("<MyConsoleApplication>")
' Obtain a handle to the console application system menu.
Dim hMenu As Integer = GetSystemMenu(hWnd, False)
' Delete the Close menu item from the console application system menu.
' This will automatically disable the Close button on the console application title bar.
' 6 indicates the position of the Close menu item.
' 1024 indicates that the second parameter is a positional indicator.
DeleteMenu(hMenu, 6, 1024)
System.Console.WriteLine("Press ENTER to quit")
' Wait for the user to press the ENTER key.
System.Console.ReadLine()
End Sub
Private Function ObtainWindowHandle(ByVal lpstrCaption As String) As Integer
' To store the handle to a window.
Dim hWnd As Integer
' Maximum number of characters in the GetWindowText method.
Dim nMaxCount As Integer
' Actual number of characters copied in the GetWindowText method.
Dim nCopiedLength As Integer
' To store the text of the title bar of the window.
Dim lpString As String
nMaxCount = 255
' Obtain a handle to the first window.
hWnd = GetForegroundWindow
' Loop through the various windows until you encounter the console application window, _
' or there are no more windows.
While hWnd <> 0
' Fill lpString with spaces.
lpString = Space(nMaxCount)
' Get the text of the window title bar in lpString.
nCopiedLength = GetWindowText(hWnd, lpString, nMaxCount)
' Verify that lpString is neither empty, nor NULL.
If Len(Trim(lpString)) <> 0 And Asc(Trim(lpString)) <> 0 Then
' Verify that the title of the retrieved window is the same as the title of the console application window.
If CType(InStr(Left(lpString, nCopiedLength), lpstrCaption), Boolean) Then
' Return hWnd to the Main method.
Return hWnd
End If
End If
' Get the next window.
hWnd = GetWindow(hWnd, 2)
End While
' If no corresponding windows are found, return 0.
Return 0
End Function
End Module
Note Replace
<MyConsoleApplication> with the name of your console
application.
Verify that it works
- On the Build menu, click Build
Solution.
- On the Debug menu, click
Start to run the application.
A console appears with
the following text:Press ENTER to quit
- Try to click the Close button.
You cannot click the Close
button because it is disabled.
To
quit the application, press the ENTER key in the
console.
Note The application may take some time to obtain a handle to its
console window. Therefore, the application may also take some time to disable the
Close button.
Troubleshoot
- If you declare the GetWindowText method and do not specify an alias, you may receive an
'EntryPointNotFoundException' unhandled exception.
To work around
this issue, replacePrivate Declare Function GetWindowText Lib "user32" (ByVal hWnd As Integer, ByVal lpString As String, ByVal nMaxCount As Integer) As Integer
withPrivate Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Integer, ByVal lpString As String, ByVal nMaxCount As Integer) As Integer
- If you run your console application from the command
prompt, the Close button remains disabled even after the application quits.
Therefore, Microsoft recommends that you double-click the
executable file in Visual Studio .NET to run your application.