Making a Form System Modal?

Posted on 1997-11-24
Medium Priority
Last Modified: 2008-03-10
Making a Form System Modal?
From: Tim Brockway   Email: BROCKWAYJT&AOL.COM    (860) 242-3947

(VB 5,  Win 95)
I should like to display a vb5 Form in System Modal form thus preventing input anywhere but that form. I should also like to detect all attempts to click or type in another area and redirect that input to the modal form. (By example MS Bob does this when asking for, say, a password).

Now the knowledge base has an example of setting System modal but this does not apply to VB5 Win32. (The SetSysModalWindow api is deleted). Quoting the knowledge base :

 "The SetSysModalWindow function is obsolete. This function is provided only for compatibility with 16-bit versions of Windows. The new input model does not allow for System Modal windows."

Anybody know how System modal can be achieved using VB5 Win 95?

Additionally is there any way to detect mouse/keyboard clicks outside a regular modally halted window?  I messed around with SetCapture etc but can't seem to code a routine that works. Anybody have an example of preventing mouse clicks outside a modal display and redirecting them to the modal form?

All suggestions gratefully received.

Question by:brockway
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 5
  • 2
  • +1

Expert Comment

ID: 1442297
You can monitor events outside your window by using the SetWindowsHookEx function. You can simulate a system modal form by detecting when it looses focus, and then setting the focus back to it again.

Expert Comment

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

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

   Success% = SetSysModalWindow(hwnd)

Author Comment

ID: 1442299
For MrMick
Oops. Thanks for the effort but check the question regarding SetSysModalWindow. Thanks again.

For MikeP.

Looks good let me check it out and I'll send in the points.

Thanks a million

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 1442300
Oops, I didn't read it carefully...  Good job MikeP

Author Comment

ID: 1442301
Dear MikeP,

Regarding: SetWindowsHook.
This requires a CallBack to notify the VB proc when the message (event) occurs. So far as I can figure out even VB5 can't handle this. The AddressOf keyword will pass a call back procedures address to an api but I don't see how that procedure can work. (I get the principles here but I can't find a single example on the details What thread do I specify?, which message am I intercepting? how does my callback proc pick up the callback message? and so on?). So unless you know how this might be done it's a dead end.

Regarding: Detecting  Lost Focus using simple VB events.
This seems like an obvious choice I agree but the Form lostfocus event only triggers (essentially) if there are no controls on the form. I tried this before and its virtually useless for knowing when a form loses focus to another form or app.

Sorry to be so dumb but I don't quite following the advice. If we can solve this one I'll go to all 400 points I have and my herd of camels !!!

Many thanks



Expert Comment

ID: 1442302
I realy haven't tried doing this myself, but I think you should pass App.ThreadID as the thread Id. If you want to entersept the keyboard commands, i think WH_KEYBOARD hook will be just fine. If oyu want to intersept all messages, you need the WH_CALLWNDPROC hook. So your call should look something like this:

hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KeyboardProc, vbNull, App.ThreadID)

Function KeyBoardProc(Code as integer, wParam as long, lParam as long)
'Catch the messahe here.
End Fucntion

Regarding the _LostFocus event:
You can create a flag, which will be set to false on every _LostFocus event on every control on the form, and set to True with the _GotFocus event on every control. Then, using a timer chech the value of the flag.


Call GetForegroundWindow inside a timer event, and compare it to form's hwnd property. if it's equal, your form is active. If not - make it active.

Hope it helps.

Expert Comment

ID: 1442303
Here's some sample code I wrote for hooking the mouse messages.  The same can be used with minor changes for the keyboard.  Hook both by changing the hHook to hKeyHook and dim hMouseHook as long.  You'll have to keep them seperate.

To play with this, create a new project, add a module to the project and add the code below, and then place two command buttons on Form1, and then set captions to "Hook" and "UnHook".  Place in the click events calls to the respective procedure calls.  WARNING, do not exit or stop while running without clicking the unhook button!

Also, make sure your immediate window is visible so you can see the results as the mouse moves within the VB IDE workspace.

To Brockway: Don't up the points, save them for questions you'll want to ask in the future.  200 is very fair for questions of this difficulty.  If you have trouble with this code, comment and I'll respond.  PS: The below code must be in a basic module, can't be in the form module (rules of AddressOf statement).

To MikeP: Go ahead and click answer so brockway can give you points once this issue is closed.  Note: int and uint are LONG Integer Values in 32 bit API Programming.


Public Const WH_KEYBOARD = 2
Public Const WH_MOUSE = 7

'These will be need to examine and use data returned in MouseProc
        x As Long
        y As Long
End Type

        pt As POINTAPI
        hwnd As Long
        wHitTestCode As Long
        dwExtraInfo As Long
End Type

Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long

Dim hHook As Long

Public Sub Hook()

   hHook = SetWindowsHookEx(WH_MOUSE, AddressOf MouseProc, vbNull, 0)

End Sub
Public Sub UnHook()

   hHook = UnhookWindowsHookEx(hHook)

End Sub
Function MouseProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

   If nCode < 0 Then
      MouseProc = CallNextHookEx(hHook, nCode, wParam, lParam)
      'Setting MouseProc to non-zero effectively removes
      'it form further processing.  To handle yourself,
      'exit here and don't forward to CallNextHookEx

      Debug.Print nCode; wParam; lParam; Now

      'Just a demo, do you're own thing here.

      'Pass it on if you're not going to handle it.
      MouseProc = CallNextHookEx(hHook, nCode, wParam, lParam)
   End If

End Function


Author Comment

ID: 1442304
Thanks guys. Give me a while to integrate all this and i'll post back the final version.

I'll post the points asap. I'm not getting the "Scoring" screen come up with the answers so I'll have to email the admin to allocate the points.

Keep up the good work. I think we all learning here.

Thanks again



Accepted Solution

mrmick earned 800 total points
ID: 1442305
You can't assign points because answer hasn't been selected by either of us.  I'll check answer, but if you wish to give these points to MikeP, that's fine, just reject this as the proposed answer and wait until MikeP to selects the Answer Option.

Author Comment

ID: 1442306
I have asked the admin folks to award you both 200 points. If they do not show up please let me know.

I am still struggling but you've set me off in the right direction.

One final point.

Where do I get the values for API contstants etc. For example I'm looking for the value of WM_Help and dozens of others.  The VB API text viewer only has a subset and my SDK (Ms Developer Network) cd refers to the constant names but not there values. (Unless I'm just missing it).

Hope you all had a nice holiday.


Expert Comment

ID: 1442307
Tim, you can find these values in the Win32 SDK.  The SDK includes C language header files that contain the definitions.  Look in the include directory (sub-directory of MSTools).

The SDK has a quick info button associated with each API function.  The quick info button displays information about the function including what header file to refer to for constant and structure definitions.

Specifically, WM_Help is defined in winuser.h and has a value of 0x0053 which is 83 in decimal.

LVL 13

Expert Comment

ID: 1442308
Bought This Question.

Author Comment

ID: 1442309
What does "Bought this question mean".?

Keep up the good work


Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
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…
Suggested Courses
Course of the Month13 days, 14 hours left to enroll

801 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