Keep A Window in Focus (SetFocus)
I know that you can give a window focus by using the SetFocus function.
But what if you want to give the window focus, AND PREVENT other windows from reclaiming that focus until you are ready to relinquish focus. Is there any way to do this?
Thanks,
Johnny
Re: Keep A Window in Focus (SetFocus)
Re: Keep A Window in Focus (SetFocus)
THE METHOD DESCRIBED IN THIS POST DOES NOT WORK AT ALL!
This behaviour is not very nice for other applications.
But, i can see a solution idea:
Disable all other windows.
For that:
call EnumWindows and call EnableWindow(hWnd,FALSE) on each window passed to the callback except the top-level window containing the control you want to focus.
Be sure to save the return value of EnableWindow which is non-zero if the window was already disabled.
So when you want to relinquish the control's focus, you must call EnableWindow(hWnd,TRUE) on each window whose saved value corresponds to an already disabled window.
To save this value, you can call the SetProp function with an improbable property name to don't interfere with existing properties.
This property name can be a GUID appended to a human-readable value, like "EnableState5494D652-B304-49c9-BDD1-6516F179E5BA".
Save the value ((HANDLE)1) to indicate a window that was enabled, and ((HANDLE)2) to indicate a window that was disabled.
But, new windows could be created during the period you want to have the exclusive focus.
In that case, you can handle windows creations with SetWindowsHookEx with idHook=WH_SHELL
And you need to call the same procedure that you called in the EnumWindows callback on each created window ( the HSHELL_WINDOWCREATED code is sent to the ShellProc).
Because it does not really handle window creation, but window apparitions (i mean that hidden windows that are shown are considered to be "created"), you must test for the presence of your property using GetProp, and if it returns NULL, that means that it is really a new window, and in that case, and only in that case, you must call the disabling procedure which also save the state of the window.
There is always a problem : What to do, if the enabled state of some windows change during the period you want to have the exclusive focus ?
For windows that must finally be enabled, there is no problem, because if they were disabled at the first time, no functions will be called on them, and if they were initially enabled, your pogram will just call EnabledWindow(hWnd,TRUE), and so will not modify their state.
Re: Keep A Window in Focus (SetFocus)
If all you actually want is for the appication to stay on top of all others then you could try using SetWindowPos with the first parameter set to &wndTopMost
Re: Keep A Window in Focus (SetFocus)
Excuse me JohnnyBGood, but my solution does not work at all.
Because clicking on a disabled window does not set the focus on it, but remove the focus from the currently selected window.
When i posted it, i was on a computer without any programming language, so i had not tested it at all.
Re: Keep A Window in Focus (SetFocus)
I have not found any solution, but i can say what does not work:
treating the WM_ACTIVATEAPP or WM_ACTIVATE messages by activating the window when it is deactivated does not work.
Idem for WM_KILLFOCUS.
The SetCapture function does not capture the mouse if the mouse button is down, so it is impossible to use it to avoid that the user click on an other window (moreover, it cannot stop the user from using the keyboard to move from one application to another).
Re: Keep A Window in Focus (SetFocus)
1) set a timer (search for SetTimer & WM_TIMER) with a tiny gap and check whether your application lost focus or not
2) set a hook to your window and reply to a WM_KILLFOCUS message with a WM_SETFOCUS message (dunno if it will work, you may get the same problem that SuperKoko had)
of course with the first method your app will lose focus, but just until you check it has the focus again (= the gap you set in SetTimer)
Re: Keep A Window in Focus (SetFocus)
Why not using SetWindowPo() and affecting SWP_TOPMOST on your window. This will cause that your window will always be on top. The just handle WM_ACTIVATE and lookup for WA_INACTIVE through the LOWORD() of WPARAM parameter through your window procedure. If so call SetFocus() on your window.
That should do the job.
Re: Keep A Window in Focus (SetFocus)
I know this thread is expired for a long time, but since I have searched the internet for this topic and did not find a proper solution I thought to write down the method I found. This solution is very simple, fully working, easy to control and based on the win32 api. So it's applicable in many languages, sample code in VB6.
TO KEEP A WINDOW IN FOCUS, RETURN 1 TO WM_NCACTIVATE:
hPreviousProc = SetWindowLong(hWndKeepFocus, GWL_WNDPROC, AddressOf KeepFocusProc)
function KeepFocusProc&(ByVal hWnd&, ByVal wMsg&, ByVal wParam&, ByVal lParam&)
select case wMsg
Case WM_NCACTIVATE
KeepFocusProc = 1
Exit Function
End Select
KeepFocusProc = CallWindowProc(hPreviousProc, hwnd, wMsg, wParam, lParam)
End function