Microsoft KB Archive/818361

= How to disable the Close button on the title bar of a console application by using Visual Basic 2005 or Visual Basic .NET =

Article ID: 818361

Article Last Modified on 5/12/2007

-

APPLIES TO


 * Microsoft Visual Basic 2005 Express Edition
 * Microsoft Visual Basic .NET 2003 Standard Edition
 * Microsoft Visual Basic .NET 2002 Standard Edition

-



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 &quot;Complete code listing (Module1.vb)&quot; 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 &quot;user32&quot; (ByVal hMenu As Integer, _  ByVal uPosition As Integer, ByVal uFlags As Integer) As Boolean Private Declare Function GetForegroundWindow Lib &quot;user32&quot; As Integer Private Declare Function GetSystemMenu Lib &quot;user32&quot; (ByVal hWnd As Integer, _  ByVal bRevert As Boolean) As Integer Private Declare Function GetWindow Lib &quot;user32&quot; (ByVal hWnd As Integer, _  ByVal uCmd As Integer) As Integer Private Declare Function GetWindowText Lib &quot;user32&quot; Alias &quot;GetWindowTextA&quot; _ (ByVal hWnd As Integer, ByVal lpString As String, ByVal nMaxCount As Integer) As Integer </ol>

Obtain a handle to the console application window
<ol>  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 </li>  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(&quot;<MyConsoleApplication>&quot;) Note Replace  with the name of your console application. </li></ol>

 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:

http://msdn2.microsoft.com/en-us/library/ms633499.aspx

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(&quot;Press ENTER to quit&quot;) ' 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 &quot;user32&quot; (ByVal hMenu As Integer, _     ByVal uPosition As Integer, ByVal uFlags As Integer) As Boolean Private Declare Function GetForegroundWindow Lib &quot;user32&quot; As Integer Private Declare Function GetSystemMenu Lib &quot;user32&quot; (ByVal hWnd As Integer, _     ByVal bRevert As Boolean) As Integer Private Declare Function GetWindow Lib &quot;user32&quot; (ByVal hWnd As Integer, _     ByVal uCmd As Integer) As Integer Private Declare Function GetWindowText Lib &quot;user32&quot; Alias &quot;GetWindowTextA&quot; _ (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(&quot;<MyConsoleApplication>&quot;) ' 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(&quot;Press ENTER to quit&quot;) ' 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  with the name of your console application.

Verify that it works
<ol> On the Build menu, click Build Solution.</li>  On the Debug menu, click Start to run the application.

A console appears with the following text: <pre class="fixed_text">Press ENTER to quit </li> 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.</li></ol>

Troubleshoot
<ul>  If you declare the GetWindowText method and do not specify an alias, you may receive an 'EntryPointNotFoundException' unhandled exception.

To work around this issue, replace Private Declare Function GetWindowText Lib &quot;user32&quot; (ByVal hWnd As Integer, ByVal lpString As String, ByVal nMaxCount As Integer) As Integer with Private Declare Function GetWindowText Lib &quot;user32&quot; Alias &quot;GetWindowTextA&quot; (ByVal hWnd As Integer, ByVal lpString As String, ByVal nMaxCount As Integer) As Integer </li> 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.</li></ul>

<div class="references_section">