Find handle of previous active window (win32)

I'm trying to write a small win32 application (in C or C++)  that sends pre-cooked keystrokes to another application. The user experience should be this:

The user works with application X (which can be anything), then uses the mouse to click somewhere in the window belonging to application Y (written by me), which is visible on the screen. Application Y uses SendInput to send keystrokes to application X.

The problem is: SendInput sends keystrokes to the foreground window. How can application Y determine which window was the foreground window immediately before it received the mouse click?

Back in 1997, someone asked a similar question here (http://www.experts-exchange.com/Programming/System/Windows__Programming/Q_10010231.html), and the answer was to look at the wparam of the WM_SETFOCUS message. However,  the answer was later withdrawn (and in Vista that parameter appears to always be 0). One of the last comments on the question from 1997 says: "It seems there is no way to obtain handle of deactivated window."

Is that really true?
ctoAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

JohnGabyCommented:
You might try creating a window that does not take the focus in the first place.  That way you wouldn't need to determine where the focus originated  Check out the WS_EX_NOACTIVATE style:

http://msdn.microsoft.com/en-us/library/ms632680(VS.85).aspx
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jkrCommented:
If we believe MSDN, it should be WM_SETFOCUS (http://msdn.microsoft.com/en-us/library/ms646283(VS.85).aspx), where it says: "wParam - Handle to the window that has lost the keyboard focus. This parameter can be NULL."

However, if that does not work for you, you might want to consider setting a global hook (see http://msdn.microsoft.com/en-us/library/ms997537.aspx - "Win32 Hooks") that filters for WM_KILLFOCUS and sends the handle of the window that message was targetted at to your app. E.g.
LRESULT CALLBACK HookProc	(	int		nCode,	// hook code
                                WPARAM	wParam,	// removal flag 
                                LPARAM  lParam 	// address of structure with message 
                            )
{
    PMSG	pmsg	=	( PMSG)	lParam;
 
    if	(	0	>	nCode	||	PM_NOREMOVE	==	wParam)	
        {
            return	(	CallNextHookEx	(	g_hhk,
                                            nCode,
                                            wParam,
                                            lParam
                                        )
                    );
        }
 
    if	(WM_KILLFOCUS == pmsg->message)
        {
            /* this one is for us, so grab the window handle here */
        }
 
    return	(	CallNextHookEx	(	g_hhk,
                                    nCode,
                                    wParam,
                                    lParam
                                )
            );
}

Open in new window

0
ctoAuthor Commented:
Thank you, JohnGaby and jkr. Both solutions are useful, and I have split the points between you.

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.