Solved

Making a Form System Modal?

Posted on 1997-11-24
13
534 Views
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.

TIM
0
Comment
Question by:brockway
  • 5
  • 5
  • 2
  • +1
13 Comments
 
LVL 8

Expert Comment

by:MikeP090797
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.
0
 
LVL 8

Expert Comment

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

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

   Success% = SetSysModalWindow(hwnd)
0
 

Author Comment

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

For MikeP.

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

Thanks a million
Cordially
Tim

0
 
LVL 8

Expert Comment

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

Author Comment

by:brockway
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

Tim.

0
 
LVL 8

Expert Comment

by:MikeP090797
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.

or

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.
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 8

Expert Comment

by:mrmick
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.

mrmick



Public Const WH_KEYBOARD = 2
Public Const WH_MOUSE = 7

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

Type MOUSEHOOKSTRUCT
        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)
   Else
      'Setting MouseProc to non-zero effectively removes
      'it form further processing.  To handle yourself,
      'exit here and don't forward to CallNextHookEx

      'Testing
      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


0
 

Author Comment

by:brockway
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

Tim

0
 
LVL 8

Accepted Solution

by:
mrmick earned 200 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.
0
 

Author Comment

by:brockway
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.

Cordially.
Tim
0
 
LVL 8

Expert Comment

by:mrmick
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.

0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1442308
Bought This Question.
0
 

Author Comment

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

Keep up the good work

TIM
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

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…
Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

747 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

11 Experts available now in Live!

Get 1:1 Help Now