We help IT Professionals succeed at work.

System modal windows part 2

Medium Priority
Last Modified: 2008-03-10
OK, now that volking has explained how to make a Window system modal (using SetSysModalWindow and LockInput), does anyone know how to do it under Windows 95 (where there's no user.dll)?
Is it possible?

The application I'm writing will be running mainly under Windows 95 and if I can't prevent users from accessing anything else (the application is a login/access control app)then there's really no point...

What other options could I look into?

Watch Question

Under Windows 95 you can disable the ability to switch to other Windows programs by calling the Windows API function SetSysModalWindow. .

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.


Similar answer (if not exactly the same) answer I got before. I'm sure it works under Windows 3.1 etc. but Windows 95 doesn't ship with user.dll (at least mine doesn't). I suspect that's why the documentation says that SetSysModalWindow hasn't been implemented under Win32. Therefore, when I run the application, I get run-time error number 48 (error in loading DLL). I expect it's because the DLL isn't there...
There must be some other way of doing it under Win32 though...
I thought the whole point of win32 was the concept of allowing programs to run in their own totally separate address spaces (except 16bit apps which cheat). The idea being that this would increase reliability (snigger) and not allow one program to dominate the processor and/or adversely affect other tasks. Hence I think what you are trying to do is not possible directly.

However you could always have your window as the topmost window of the system *and* have it the same size as the desktop (but hiding the startmenu - if its 16bit this is easy). This may give the semblance of a locked system and deter most users from trying anything before your app has processed. This idea falls down though if there are other applications loaded behind which can be switched to (and unfortunatly explorer is always loaded and can be accessed from the task dialog).

I hope this helps.
Is it not possible to ship user.dll with your app?
Whoa, isnt that a bit dangerous dirkmartin? I for one am not sure what effect calling a 16 bit obsolete api on 95 will do ... It may be worth a try though ...

Does not the DLL named User32.dll contain the API function you need,which is the 32 bit version of user.dll?

Many of the dll in Windows 3.11 exists in 32 bit versions in Windows 95 (with the same name but containing 32.dll).


Regarding user32.dll containing SetSysModalWindow etc., no, it doesn't... The docs specify that these API calls have not been implemented under Win32...


Also, I thought of including user.dll within the application's installation (I plan to give it a try as soon as I find a 16-bit Windows machine from which I can copy it...), however, like andyb, I'm a bit sceptical...

Is the application designed as a login app for the entire 95 system?  Or just a front-end login to another application?

Just asking for clarification...


Yes, it's a login application that checks a database (on another machine on the network) to see if the user is authorized to use the network. It's purpose is to restrict access, as well as to track usage times, activities etc. (this information is either generated automatically, or entered by the user, and is added to the database).


I've solved the problem another way:
By running the application when the system is first started and setting it's position to topmost in the z-order (this is also done when the window loses focus etc.), and having the application size itself so that it takes up the whole screen, the user is effectively prevented from using any of the machine's applications etc. until the window is closed by providing it with a valid user name.
The SetSysModalWindow function is not implemented in the Win32 API. The new input
model does not allow for System Modal windows.

Instead of your current approach, try this one...
The ClipCursor and APPACTIVATE calls will effectivly disable any other windows or keys.

Declare Function GetClipCursor Lib "user32" (lprc As RECT) As Long
Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Declare Function ClipCursor Lib "user32" (lpRect As Any) As Long
Type RECT            'the type variable for the                          'window coordenents
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type
Global OldClipping As RECT 'Old Clipping (so you can restore it)
Global WindowClipping As RECT 'coordenents of the window that you                               'want to limit the mouse to.
First start a new project and place the above declarations in the new MODULE
Next, place two buttons on the new form that was created by default.
Next, create a timer with an interval of 10.
Next, put the code below in the proper places.
Private Sub Command1_Click()
ClipCursor WindowClipping  'this locks the mouse clipping to the coordenents of
                        'your window!
End Sub

Private Sub Command2_Click()
ClipCursor OldClipping 'This unlocks the clipping by restoring the old clipping
End Sub

Private Sub Form_Load() 'This Gets the current screen clipping so you can restore
                  'it as soon as you are done.
GetClipCursor OldClipping
GetWindowRect Me.hwnd, WindowClipping 'this gets the screen coordenents of your
End Sub                              'form that you are going to restrict

Private Sub Timer1_Timer() 'This continualy makes sure that the only window on top is
AppActivate "Form1"            ' your window
End Sub

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts


This seems to be a more (aesthetically) elegant way to do it (I haven't tried it, but I understand the jist of it...).
Is the timer really necessary though? Can I not just use the same code I'm using now (i.e. when the form is first created, it puts itself on top. Then, when the focus changes etc. the form just puts itself on top again...).
I like this solution though because the form doesn't have to be made to take up the whole screen...


All you want to do is create a Password screen right. The key to this problem is not in modal screens. I have a program that will password protect win95 (no it doesn't hack into the win.com either! <g>). I just haven't gotten around to writing a setup program for it. I hate to be an ass but it seems like I am the only person with this solution and I am going to release this as shareware soon. If anyone is interested in the code or program, contact this webmaster or me directly.

I would like the code for this.  Thanks!
You can E-Mail it to D8aMan@prodigy.net.

Thanks again!
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.