Solved

Preventing the focus from ever leaving my program.

Posted on 1998-07-25
23
436 Views
Last Modified: 2013-11-20
Hello,

I am writing a security program, and was wondering if anyone could tell me how to prevent the input focus from ever leaving my program.

The program is dialog based, it is not an SDI or MDI.  It is not full screen, and I'd really like to keep it that way.

I have tried setting a timer (50ms) and seeing if the active window is ever NOT mine, but, to my dismay, the timer messages aren't sent when my main window isn't active.

Also, for some reason, the following doesn't work:
void CLockoutDlg::OnKillFocus (CWnd* pNewWnd)
{ //CDialog::OnKillFocus(pNewWnd);
  SetFocus ();
}

I wouldn't mind hearing any methods for preventing task switching.  So far, I've managed to disable ALT-TAB, but the user can still click on another program behind mine, thereby bringing it into focus.

Anyone have any ideas?

Note: If it turns out that the solution is more complex than it seems, I'll increase the number of points.

Thanks.
HelpMeAlot!
0
Comment
Question by:helpmealot
[X]
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
  • 10
  • 6
  • 3
  • +2
23 Comments
 

Author Comment

by:helpmealot
ID: 1319737
Edited text of question
0
 
LVL 7

Expert Comment

by:psdavis
ID: 1319738
Not an answer but maybe something to look at.  The MessageBox has a flag called SYSTEMMODAL that is doing what you want.  Here's the doc.

MB_SYSTEMMODAL   All applications are suspended until the user responds to the message box. System-modal message boxes are used to notify the user of serious, potentially damaging errors that require immediate attention and should be used sparingly.

If there was a way to apply it to a dialog instead of the message box (which is a dialog), then you have an answer!

Phillip

0
 

Author Comment

by:helpmealot
ID: 1319739
Hmm... There is something similar to the MB_SYSTEMMODAL, however it doesn't work in Windows 95 or NT, only in Windows 3.1.

Thanks for the help.
0
Industry Leaders: 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!

 

Author Comment

by:helpmealot
ID: 1319740
Adjusted points to 50
0
 
LVL 7

Expert Comment

by:psdavis
ID: 1319741
OK, no one else is suggesting anything so how about another shot in the dark.

How about OnNcActivate?

Description:
The framework calls this member function when the nonclient area needs to be changed to indicate an active or inactive state. The default implementation draws the title bar and title-bar text in their active colors if bActive is TRUE and in their inactive colors if bActive is FALSE.

Suggestion:
If OnNcActivate is executed, I believe your application is going to know that another program is about to become active.  Then the key is to override the de-activation of your program.  OnNcMouseMove was a more kludgy idea.

Speaking of kludgy, how about making your application full screen without resizing, and forcing to be top-most using the SetWindowPos and wndTopMost as it's pWndInsertAfter.  Any other application or window will fall behind yours.

I said it was kludgy :)

Phillip




0
 
LVL 2

Expert Comment

by:SamratAshok
ID: 1319742

This question is anything else but easy.

Read the MFC knowledge base article PSS ID Number: Q125614.

Article is is not exactly encouraging but it does say

"ALT+TAB and ALT+ESC may be disabled while a particular application is
running if that application registers hotkeys for those combinations with
Register HotKey()."

While I have not tried this, you can go ahead and try

Another alteranative suggested though not recommended is as follows

" CTRL+ESC may disabled on a system-wide basis by replacing the NT Task
Manager. " 
It points on further to article number

ARTICLE-ID:Q89373
TITLE     :Replacing the Windows NT Task Manager

I got access to this articles by searching phrase "task switching" in VC++ 4.1 compiler
Help Query box. Iam responding from Home and do not VC 5.0 at home. I DID NOT use quotes in the search string.

If needed, I can post the article from my office machine

0
 

Author Comment

by:helpmealot
ID: 1319743
Phillip: Does OnNcActivate work with dialog based applications?  That's what I'm using, but from what the documentation says, it sounds like that function would only work with an SDI or MDI based application.

About the "make the window full-screen always on top" idea... :-), a better way would be appreciated, but I would really like to figure out how to prevent the focus from ever leaving just so I can at least do it again in the future if need be.  If we can't figure this out, that's just what I might resort to.

SamratAshok:  I have already disabled alt-tab, ctrl-esc etc etc... by tricking the computer into thinking a screen saver is running (long story, point is, it works great).  I am trying to figure out how to prevent the focus from leaving the program by the user clicking to the side of it to activate another application.

I seemed to have figured something out, that works, somewhat.  I have overridden the OnActivateApp function with the following:

void CLockoutDlg::OnActivateApp (BOOL bActive, HTASK hTask)
{ if (bActive == FALSE)
  { if (GetFocus () != this)
    { SetFocus ();           // Do all this to make sure.... :-)
      SetActiveWindow ();
      SetForegroundWindow ();
    }
  }

  //CDialog::OnActivateApp (bActive, hTask);
}

There is an interesting side effect however.  If I click outside the program, the focus will still leave my program but whatever I click on will not gain the focus.  This basically makes everything out of focus.

Is there a way I can modify the code to make my program stay in focus?

Thanks.
0
 

Author Comment

by:helpmealot
ID: 1319744
Edited text of question
0
 
LVL 7

Expert Comment

by:psdavis
ID: 1319745
I'm not sure if OnNcActivate goes to a dialog.  Looking at class wizard, I didn't see an option for NcActivate appearing.  An alternative is to use the CFormView in a SDI application instead of the dialog.  Not much visual difference...

A third idea would be to implement a 'ScreenSaver' type approach to the application.  There are ways (not that I know of any great ones) that the screen saver would continue to run, a dialog box pops up and requests the password.  Once the password is corret, then the screen saver finishes and the background screen appears. ;)

Phillip

0
 
LVL 2

Expert Comment

by:duneram
ID: 1319746
You could make your dialog the size of the screen and a child of the desktop using the SetWindowPos API.  Additionally you can make it topmost (all using this api).

I don't know if you want it to be the whole screen.


0
 

Author Comment

by:helpmealot
ID: 1319747
Hi again,

I'm not really too keen on making the dialog box full screen.  Every dialog box looks bad full screen.  I would really like to just prevent the focus from being able to leave my application.

Any other ideas?
Thanks.
0
 

Author Comment

by:helpmealot
ID: 1319748
Hi again,

I'm not really too keen on making the dialog box full screen.  Every dialog box looks bad full screen.  I would really like to just prevent the focus from being able to leave my application.

Any other ideas?
Thanks.
0
 

Author Comment

by:helpmealot
ID: 1319749
Edited text of question
0
 
LVL 7

Expert Comment

by:psdavis
ID: 1319750
Did you investigate using the CFormView and the OnNcActivate?  What where your impressions?

Phillip

0
 
LVL 2

Expert Comment

by:duneram
ID: 1319751
Yeah I agree full page dialogs don't always look too hot.    Perhaps a hookproc would do the trick.

WM_MOUSEMOVES -- if you get one and its out of bounds of your window, change the attributes to be within your window, then let the message through and it will correct itself.

Stuff like that.
0
 
LVL 2

Expert Comment

by:duneram
ID: 1319752
Another shot in the dark, is to create a new desktop and make your dialog a child of that desktop.  The user will have no where to go except for your dialog...

But you need to trap ctl-alt-del... YOu don't want some user terminating your process...
0
 
LVL 1

Accepted Solution

by:
Musashi earned 70 total points
ID: 1319753
Helpmealot, with what you've already implemented, the following should solve your problem:

Rect myRect;  // may need to be global depending on your app

::GetWindowRect (m_hWnd, &gRect);// Get RECT of Dialog Box
BOOL result = ::ClipCursor(&gRect);// Confine mouse to Box

I too am working on a security program in a non-full screen dialog box.  I have a number of timers that work fine, but I have not yet implemented one of your features, perhaps you could show me how you did it, namely:

      Disable Alt-Tab, Ctrl-Esc, etc.

Hopefully you have a method that works in NT4.0SP3 as wells as Win95/98.  I have fooled with the SPI_SCREENSAVERRUNNING in NT, but have not gotten it to work yet.

Thanks.
Musashi



0
 
LVL 1

Expert Comment

by:Musashi
ID: 1319754
Sorry, those gRect's should be myRect's.
0
 
LVL 7

Expert Comment

by:psdavis
ID: 1319755
HelpMeALot,

DS_SYSMODAL
 Creates a system-modal dialog box. This style causes the dialog box to have the WS_EX_TOPMOST style, but otherwise has no effect on the dialog box or the behavior of other windows in the system when the dialog box is displayed.

The new type of MB_SYSTEMMODAL that we used in Win3.1.  Try it here instead.  That might just do what you want!

Phillip


0
 
LVL 7

Expert Comment

by:psdavis
ID: 1319756
You know, if I would just read the descriptions instead of assuming what it did, I could reduce these unnecessary postings.

Phillip

0
 

Author Comment

by:helpmealot
ID: 1319757
Musashi,

Thank you, your answer seems to work great.  One last thing, however, what class function would you recommend I put that code in?  I have tried putting it in the OnPaint function, but it has this weird side effect of occasionally stopping while I'm dragging the window around.  If I release the mouse button and then begin dragging the window around again, it will work fine.  It's almost like the window hits an invisible line which it cannot cross.

Then I tried putting it in the OnMouseMove function, but that has the unfortunate side effect of not working until the mouse is moved into the window.  This means that the user could simply keep the mouse out of the security box and continue doing whatever they wanted (of course, with my SetFocus and all that, it is very difficult to do anything behind the program).
Any ideas?

Also, try going to this address to find out about the SPI_SCREENSAVERRUNNING thing:
http://www.codeguru.com/misc/disable_alt_tab.shtml

But in the online documentation for Visual C++, it says that the SPI_SCREENSAVERRUNNING is not implemented at all in NT, sorry.

Thanks again!
0
 
LVL 1

Expert Comment

by:Musashi
ID: 1319758
Helpmealot, you are welcome and I am glad it solves your problem.

I assume that your security app, like mine, gets triggered (at user logon, browser startup, etc) and basically needs to own the system to get the user's attention.  The user now needs to attend to the dialog box somehow to get his system back.  The user does NOT need to move the box anywhere at this point, therefore the box does not need the title bar (drag point).  If you create the dialog box without the title bar style, all of the (Microsoft) problems associated with ClipCursor() go away.  You lose the System menu this way, but only the "About" choice is possibly relevant, and you can put an "About" button right on the dialog box if you really need it. So, to answer your question, you should place the ClipCursor() code right in the function that causes the Dialog Box to appear.  If your app is a one-time event at logon, it should occur in OnInitDialog().  If your app lurks in the background waiting for the user to start up a browser (like mine does), the code should occur in whatever function gets triggered to make the Dialog Box automagically appear on the screen.

Here is how my code *basically* works:

Rect gFullScreenRect; // Global!!! (use to undo clipping later)
CMyDlgBox *gMyDlgBox;  // Global!!! (use to call functions

BOOL CMyApp::InitInstance()
    {
    [...]
    // my code here to install a callback function that
    // gets triggered when a browser gets started
    // (see DDEInitialize())
    CMyDlgBox dlg;
    gMyDlgBox = &dlg;
    [...]
    }

BOOL CMyDlgBox::OnInitDialog()
    {
    ::GetClipCursor (&gFullScreenRect); // save to restore later
    // Init Dialog Box as needed here, but make it hidden
    }

MyTriggerFunction (/*parms*/)
    {
    if (NowIsTheTimeToDisplayDialogBox)
        gMyDlgBox->DisplayDialogBox();
    }

CMyDlgBox::DisplayDialogBox()
    {
    // code to unhide Dialog Box here
    Rect DialogBoxRect;
    ::GetWindowRect (m_hwnd, &DialogBoxRect);
    ::ClipCursor    (&DialogBoxRect);  // lock user in Box
    }

CMyDlgBox::OnUserAgreesToProperBrowserUsage()
    {
    ::ClipCursor (&gFullScreenRect); // Restore mouse
    // Hide Dialog Box Code here (goes back underground)
    }

CMyDlgBox::OnUserDoesNotAgreeToProperBrowserUsage()
    {
    ::ClipCursor (&gFullScreenRect); // Restore mouse
    // code to tell Browser to Shut Down here
    // code to Hide Dialog Box here (goes back underground)
    }

0
 

Author Comment

by:helpmealot
ID: 1319759
Thank you, you have been most helpful.  This solves my problems completely.  As it turns out, my security program is not a triggered event, although I can see why that would be useful.  My program was intended to be used if, say, you wanted to go away from your computer for awhile, and not want anyone else touching it unless they knew the password.

Thank you very much!
0

Featured Post

Ready to get started with anonymous questions?

It's easy! Check out this step-by-step guide for asking an anonymous question on Experts Exchange.

Question has a verified solution.

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

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…

617 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