0

I've been reading posts all over and trying different approaches, but I can't make this work.

I want to be able to track the last window before the user clicks on my application. This way I can bring it to the front and send a copy command to retrieve whatever the user has selected.

I thought about using hooks to receive notifications of activated windows, but it is not working as expected. I'm using HSHELL_WINDOWACTIVATED global hook to keep track of the current and last active window, but I always get both handles to be the same, pointing to my application.

The code looks like:

#pragma data_seg("ASEG")  
  HWND lastWindow = 0;
  HWND currentWindow = 0;
#pragma data_seg()  
#pragma comment(linker, "/section:ASEG,RWS") 

HINSTANCE dllHandle;  

BOOL APIENTRY DllMain(    
         HINSTANCE hinstDLL,  
         DWORD fdwReason,  
         PVOID lpReserved )  
{ 
    switch( fdwReason )  
    {  
    case DLL_PROCESS_ATTACH:    
        dllHandle = hinstDLL;    
        return TRUE;  
        break;  
    }  
}  

LRESULT CALLBACK ShellHookProc(int nCode, WPARAM wParam, LPARAM lParam)   
{  
    if (nCode > 0)
    {
        switch (nCode)
        {
        case HSHELL_WINDOWACTIVATED: lastWindow = currentWindow;
                         currentWindow = (HWND)wParam;
                         break;
        }
    }

    return ::CallNextHookEx(NULL, nCode,wParam,lParam);
}

extern "C" {

__declspec(dllexport) void Init()
{   
    SetWindowsHookEx(WH_SHELL, ShellHookProc, dllHandle, 0);    
}

}

Later on I would use the lastWindow to bring that window to the front and send a Ctrl+C command.

If you call GetWindowTextA(..) for each handle, the first time you activate a different window and go back to the application, lastWindow retrieves blank and currentWindow my application name. Any consecutive activations retrieve always the name of my application for both lastWindow and currentWindow. I don't quite understand why this is happening. Any ideas?

Thanks!

eddie
  • 1,252
  • 3
  • 15
  • 20
Sebastian
  • 1,243
  • 1
  • 18
  • 34
  • You just want to find the previous application in the Z-Order? If so, there are more appropriate ways of doing so than a "global hook". – Chad Oct 31 '12 at 19:55

1 Answers1

1

I think you can use SetWinEventHook. This hook should allow you to capture the EVENT_SYSTEM_FOREGROUND message so that each time a window is brought to the foreground, you can capture the window handle. Then when your app window is activated, just look at the last value you captured.

See this: https://stackoverflow.com/a/4407715/1502289

Also, in your own code, you could simply do a comparison to see if the window handle is the handle to your own window. If not, save the handle.

Example:

...
case HSHELL_WINDOWACTIVATED: 
if (lastWindow != [your own window's handle])
{
    lastWindow = (HWND)wParam;
}
break;
...
Community
  • 1
  • 1
Ryan Griggs
  • 2,457
  • 2
  • 35
  • 58
  • Thanks a lot, does it actually working!! There only one more thing, using the flag WINEVENT_OUTOFCONTEXT doesnt guaranty that i'll receive the event instantly. So i can use WINEVENT_INCONTEXT, the problem here is that the dll is injected and when i try to save the handle and use it a couple of seconds later, it has 0s. Is there a way to be able to save that handle using hte INCONTEXT? – Sebastian Oct 31 '12 at 20:08
  • To clarify are you referring to the window handle or the DLL handle? – Ryan Griggs Oct 31 '12 at 20:12
  • I was referring to the window Handle that is sent with the HSHELL_WINDOWACTIVATED event. So i can bring that window to the front when needed. Since the dll's code is replicated in every process where is injected, i need to save the last active window handle and been able to acces it in my dll later on, so How can i share that global avariable(window handle) across all the places where the dll is injected? – Sebastian Oct 31 '12 at 20:59
  • Well i still dont understand that part of injecting dlls and sharing variables, but i got it working with the OUTOFCONTEXT flag, and is working great, so thanks a lot for your help! – Sebastian Nov 01 '12 at 15:09