Making a window system modal

Posted on 1997-03-13
Last Modified: 2012-08-14
Is there anyone out there that knows how to make a window or form system modal?
There doesn't seem to be a straightforward way to do it directly from VB (you can make windows modal, but not system modal), and the help available on the one API function that seems to do what I need (SetSystemModalWindow)
simply says that the function hasen't been implemented under Win32...

Any help would be greatly appreciated!...


Dave Bruzzone
Question by:DangerousDave

Accepted Solution

volking earned 150 total points
ID: 1424266
To do this right, there are two steps. First you need to set the window system modal, then you have to prevent Task-Switching. Below are two articles. Each describes one of the steps.

==============================> Frederick

VB3 How to Create a System-Modal Program/Window

Article ID: Q72674
Creation Date: 04-JUN-1991
Revision Date: 09-JAN-1997

The information in this article applies to:

- Standard and Professional Editions of Microsoft Visual Basic for

  Windows, versions 2.0 and 3.0

- Microsoft Visual Basic programming system for Windows, version 1.0


From a Microsoft Visual Basic for Windows program, you can disable the ability to switch to other Windows programs by calling the Windows API function SetSysModalWindow.


Microsoft Windows is designed so that the user can switch between applications without terminating one program to run another program. There may be times when the program needs to take control of the entire environment and run from only one window, restricting the user from switching to any other application. An example of this is a simple security system, or a time-critical application that may need to go uninterrupted for long periods of time.

Passing the handle to the window through the argument of SetSysModalWindow will limit the user to that particular window. This will not allow the user to move to any other applications with the mouse or use ALT+ESC or CTRL+ESC to bring up the Task Manager. You can even remove the system menu if you do not want the user to exit through the ALT+F4 (Close) combination.

All child windows that are created by the system-modal window become system-modal windows. When the original window becomes active again, it is system-modal. To end the system-modal state, destroy the original system-modal window.

Care must be taken when using the SetSysModalWindow API from within the Visual Basic for Windows programming environment. Pressing CTRL+BREAK to get to the [break] mode leaves your modal form with no way to exit unless you restart your system. When using the SetSysModalWindow within the environment, be sure to exit your application by destroying the window with either the ALT+F4 in the system menu, or by some other means from within your running program.

To use the SetSysModalWindow API function, declare the API call in your global section, as follows:

   Declare Function SetSysModalWindow Lib "User" (ByVal hwnd%) As Integer

At an appropriate place in your code, add the following:

   Success% = SetSysModalWindow(hwnd)

Once this line is executed, your window will be the only window that can get focus until that window is destroyed.

NOTE: Because Visual Basic for Windows was not designed with system modal capabilities in mind, using a MsgBox, InputBox, or Form.Show of another form from a system modal window will not work correctly. If you want to show another window from a system modal form, use another Visual Basic for Windows form and call SetSysModalWindow for this second form also, so that it becomes the system modal window. When the second form is unloaded, the original system modal form will again become the system modal window. Note that because the window(s) shown from a system modal window must also call SetSysModalWindow, and since MsgBox/InputBox windows cannot have associated code, you should not call the MsgBox or InputBox functions from a system modal window.
Created: April 24, 1995
When developing an application in Visual Basic®, you may need to perform a task that should not be interrupted. This article explains how to use the Windows® application programming interface (API) SetSysModalWindow and LockInput functions to disable task-switching.
Preventing a User from Switching to Another Application
The Windows® application programming interface (API) SetSysModalWindow function can be used to prevent a user from switching to a different Windows-based application while your program is executing. The ALT+TAB, CTRL+ESC, ALT+F4, and ALT+ESC keystroke combinations will not bring up the Task Manager or any other application—these keystrokes will simply be ignored. For a discussion of the SetSysModalWindow function, see "Additional References" below.
In addition, the LockInput function can be used to force all input to your Visual Basic® application only. No other application will receive any mouse or keyboard data. The Declare statement for the LockInput function is as follows (note that it must be typed as a single line of code):
Declare Function LockInput Lib "User" (ByVal hReserved As Integer, ByVal
   hwndInput As Integer, ByVal fLock As Integer) As Integer
The LockInput function requires three arguments:

hReserved      An integer value that must be set to a value of zero.
hwndInput      An integer value containing the window's handle. This is the window that will receive all input.
fLock      An integer value set to TRUE (nonzero) to lock input or FALSE (zero) to unlock input.
When your program is terminated, you must use the LockInput function to restore input to other Windows-based programs. In addition, you must destroy the system modal window; otherwise the user will not be able to switch to any other Windows-based applications and will have to reboot the computer system.
Example Program
The program below shows how you can prevent a user from switching to another Windows-based application while your program is executing.
 1.      Create a new project in Visual Basic. Form1 is created by default.
 2.      Set the following properties for Form1:
ClipControls = False
ControlBox = false
MaxButton = False
MinButton = False
 3.      Add the following Dim and Declare statements to the General Declarations section of Form1 (note that each Declare statement must be typed as a single line of code):
Declare Function GetActiveWindow Lib "User" () As Integer
Declare Function SetFocusAPI Lib "User" Alias "SetFocus" (ByVal Hwnd As Integer)
   As Integer
Declare Function SetSysModalWindow Lib "User" (ByVal Hwnd As Integer) As Integer
Declare Function LockInput Lib "User" (ByVal hReserved As Integer, ByVal
   hwndInput As Integer, ByVal fLock As Integer) As Integer
Dim TopHwnd As Integer
 4.      Add the following code to the Form_Load event for Form1:
Sub Form_Load()

  Dim X As Integer
  TopHwnd = GetActiveWindow()
  X = SetFocusAPI(TopHwnd)
  X = SetSysModalWindow(TopHwnd)
  X = LockInput(0, TopHwnd, 1)
End Sub
 5.      Add the following code to the Form_Unload event for Form1:
Sub Form_Unload(Cancel As Integer)
  X = LockInput(0, TopHwnd, 0)
End Sub
 6.      Add a Command Button control to Form1. Command1 is created by default. Set its Caption property to "Quit".
 7.      Add the following code to the Click event for Command1:
Sub Command1_Click()
    X = LockInput(0, TopHwnd, 0)
End Sub
Additional References
Knowledge Base Q72674. "How to Create a System-Modal Program/Window in Visual Basic." (Development Library, Knowledge Base and Bug Lists)


Expert Comment

ID: 1424267
Doesn't anyone actually read these questions before answering them??? Read part 2 of modal windows and look for my comment.

LVL 13

Expert Comment

ID: 1424268
Bought This Question.

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

895 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now