Solved

System modal windows part 2

Posted on 1997-03-15
16
406 Views
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?

Thanks...
0
Comment
Question by:DangerousDave
  • 6
  • 2
  • 2
  • +4
16 Comments
 
LVL 2

Expert Comment

by:dirkmartin
ID: 1424330
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.
0
 

Author Comment

by:DangerousDave
ID: 1424331
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...
0
 
LVL 1

Expert Comment

by:andyb013197
ID: 1424332
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.
0
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
LVL 2

Expert Comment

by:dirkmartin
ID: 1424333
Is it not possible to ship user.dll with your app?
0
 
LVL 1

Expert Comment

by:andyb013197
ID: 1424334
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 ...
0
 

Expert Comment

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

0
 

Expert Comment

by:hkan
ID: 1424336
Many of the dll in Windows 3.11 exists in 32 bit versions in Windows 95 (with the same name but containing 32.dll).
0
 

Author Comment

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

Author Comment

by:DangerousDave
ID: 1424338
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...
0
 

Expert Comment

by:jgacek
ID: 1424339
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...
0
 

Author Comment

by:DangerousDave
ID: 1424340
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).
0
 

Author Comment

by:DangerousDave
ID: 1424341
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.
0
 

Accepted Solution

by:
StarFieldSoftware earned 100 total points
ID: 1424342
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.
HERE IS SOME EXAMPLE CODE...

'DECLARE THE API CALLS
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

0
 

Author Comment

by:DangerousDave
ID: 1424343
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...

Thanks...
0
 

Expert Comment

by:bnunley
ID: 1424344
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.

Bill
0
 

Expert Comment

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

Thanks again!
0

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

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

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
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…

776 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