CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Oct 2008
    Posts
    68

    SetActiveWindow() failing

    Here is the complete source code for my, uh, C++ desktop organizer program for windows.

    Code:
    #include <windows.h>
    #include <iostream>
    
    using namespace std;
     
     void SetActiveWND(HWND WND)
     {
            AttachThreadInput(GetCurrentThreadId(),GetWindowThreadProcessId(WND,NULL),true);
            SetActiveWindow(WND);
            AttachThreadInput(GetCurrentThreadId(),GetWindowThreadProcessId(WND,NULL),false);
            }
    
     int main()
    
     {  RegisterHotKey(NULL,1,MOD_ALT ,VK_F3);
        RegisterHotKey(NULL,2,MOD_ALT ,VK_F2);
        MSG msg = {0};
    	HWND * hwnd,*temp,next;
    	char i=-1,size,TEMP;
    	size=10;
    	hwnd=new HWND[size];    
    	
        while (GetMessage(&msg, NULL, 0, 0) != 0)
        {   if(msg.lParam==7471105)
            {
                 if(i>=(size-1))
                 {
                 temp=new HWND[size];
                 for(TEMP=0;TEMP<size;TEMP++)
                      {temp[TEMP]=hwnd[TEMP];}
                 delete [] hwnd;
                 size+=5;
                 hwnd=new HWND[size];
                 TEMP=size-5;
                 for(TEMP=0;TEMP<size;TEMP++)
                      {hwnd[TEMP]=temp[TEMP];}
                 delete [] temp;}
                                   
            i++;
            hwnd[i]=GetForegroundWindow();
            next=GetWindow(hwnd[i],GW_HWNDNEXT);
            ShowWindow(hwnd[i],SW_HIDE);
            SetActiveWND(next);                            }
            if((msg.lParam==7405569)&&(i>=0))
            {ShowWindow(hwnd[i],SW_SHOWDEFAULT);
            SetActiveWND(hwnd[i]);
            i--;}
        
        } 
        UnregisterHotKey(NULL,1);
        UnregisterHotKey(NULL,2);
        return 0;
    }
    The part I want to focus on is the function SetActiveWND() at the top of my code. According to http://msdn.microsoft.com/en-us/libr...11(VS.85).aspx,
    The SetActiveWindow function activates a window. The window must be attached to the calling thread's message queue.
    I have done that with the function AttachThreadInput(http://msdn.microsoft.com/en-us/library/cc429027.aspx) that is mentioned by the MSDN documentation. However, if you compile the source, the SetActiveWND() always fails, and the window that gets unhidden is never set as the active window, just the foreground window. Any advice?

  2. #2
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: SetActiveWindow() failing

    Try something like:
    Code:
    void SwitchTo(HWND hWnd)
    {
    	HWND hPopup = GetWindow(hWnd, GW_ENABLEDPOPUP);
    	if (hPopup)
    		hWnd = hPopup;
    
    	if (!IsWindow(hWnd) || IsHungAppWindow(hWnd))
    		return;
    
    	if (IsIconic(hWnd))
    	{
    		PostMessage(hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
    		return;
    	}
    
    	HWND hForeground = GetForegroundWindow();
    	if (hWnd != hForeground)
    	{
    		BringWindowToTop(hWnd);
    		SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    		// Try SetForegroundWindow
    		if (!SetForegroundWindow(hWnd))
    		{
    			// SetForegroundWindow failed, try with attaching input threads
    			if (!hForeground)
    				hForeground = FindWindow(_T("Shell_TrayWnd"), NULL);
    
    			DWORD idForeground = GetWindowThreadProcessId(hForeground, NULL);
    			DWORD idTarget = GetWindowThreadProcessId(hWnd, NULL);
    
    			AttachThreadInput(idForeground, idTarget, TRUE);
    
    			// Try SetForegroundWindow again
    			if (!SetForegroundWindow(hWnd))
    			{
    				// Still not working...
    				// Simulate two single ALT keystrokes, See LockSetForegroundWindow
    				INPUT inp[4];
    				ZeroMemory(&inp, sizeof(inp));
    				inp[0].type = inp[1].type = inp[2].type = inp[3].type = INPUT_KEYBOARD;
    				inp[0].ki.wVk = inp[1].ki.wVk = inp[2].ki.wVk = inp[3].ki.wVk = VK_MENU;
    				inp[0].ki.dwFlags = inp[2].ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
    				inp[1].ki.dwFlags = inp[3].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
    				SendInput(4, inp, sizeof(INPUT));
    
    				SetForegroundWindow(hWnd);
    			}
    
    			AttachThreadInput(idForeground, idTarget, FALSE);
    		}
    	}
    	Sleep(50);
    }
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  3. #3
    Join Date
    Oct 2008
    Posts
    68

    Re: SetActiveWindow() failing

    Thank you for your reply. I integrated your code into mine:
    Code:
    #include "stdafx.h"
    #include "hwnd.no.console.h"
    
    HWND hForeground;
    
    void SetActiveWND(HWND hWnd)
    {
    	HWND hPopup = GetWindow(hWnd, GW_ENABLEDPOPUP);
    	if (hPopup)
    		hWnd = hPopup;
    
    	if (!IsWindow(hWnd) || IsHungAppWindow(hWnd))
    		return;
    
    	if (IsIconic(hWnd))
    	{
    		PostMessage(hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
    		return;
    	}
    
    	hForeground = GetForegroundWindow();
    	if (hWnd != hForeground)
    	{
    		BringWindowToTop(hWnd);
    		SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    		// Try SetForegroundWindow
    		if (!SetForegroundWindow(hWnd))
    		{
    			// SetForegroundWindow failed, try with attaching input threads
    			if (!hForeground)
    				hForeground = FindWindow(_T("Shell_TrayWnd"), NULL);
    
    			DWORD idForeground = GetWindowThreadProcessId(hForeground, NULL);
    			DWORD idTarget = GetWindowThreadProcessId(hWnd, NULL);
    
    			AttachThreadInput(idForeground, idTarget, TRUE);
    
    			// Try SetForegroundWindow again
    			if (!SetForegroundWindow(hWnd))
    			{
    				// Still not working...
    				// Simulate two single ALT keystrokes, See LockSetForegroundWindow
    				INPUT inp[4];
    				ZeroMemory(&inp, sizeof(inp));
    				inp[0].type = inp[1].type = inp[2].type = inp[3].type = INPUT_KEYBOARD;
    				inp[0].ki.wVk = inp[1].ki.wVk = inp[2].ki.wVk = inp[3].ki.wVk = VK_MENU;
    				inp[0].ki.dwFlags = inp[2].ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
    				inp[1].ki.dwFlags = inp[3].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
    				SendInput(4, inp, sizeof(INPUT));
    
    				SetForegroundWindow(hWnd);
    			}
    
    			AttachThreadInput(idForeground, idTarget, FALSE);
    		}
    	}
    	Sleep(50);
    }
    int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
    	{RegisterHotKey(NULL,1,MOD_ALT ,VK_F3);
        RegisterHotKey(NULL,2,MOD_ALT ,VK_F2);
        MSG msg = {0};
    	HWND * hwnd,*temp,next;
    	char i=-1,size,TEMP;
    	size=10;
    	hwnd=new HWND[size];    
    	
        while (GetMessage(&msg, NULL, 0, 0) != 0)
        {   if(msg.lParam==7471105)
            {
                 if(i>=(size-1))
                 {
                 temp=new HWND[size];
                 for(TEMP=0;TEMP<size;TEMP++)
                      {temp[TEMP]=hwnd[TEMP];}
                 delete [] hwnd;
                 size+=5;
                 hwnd=new HWND[size];
                 TEMP=size-5;
                 for(TEMP=0;TEMP<size;TEMP++)
                      {hwnd[TEMP]=temp[TEMP];}
                 delete [] temp;}
                                   
            i++;
            hwnd[i]=GetForegroundWindow();
            next=GetWindow(hwnd[i],GW_HWNDNEXT);
    		ShowWindow(hwnd[i],SW_HIDE);
    		SetActiveWND(next);
    		
    													}
    
    
            if((msg.lParam==7405569)&&(i>=0))
            {ShowWindow(hwnd[i],SW_SHOWDEFAULT);
            SetActiveWND(hwnd[i]);
            i--;}
        
        } 
        UnregisterHotKey(NULL,1);
        UnregisterHotKey(NULL,2);
    	}
    However, your function only works for unhiding the windows, right here:
    Code:
    if((msg.lParam==7405569)&&(i>=0))
            {ShowWindow(hwnd[i],SW_SHOWDEFAULT);
            SetActiveWND(hwnd[i]);
            i--;}
    It doesn't work here:
    Code:
     hwnd[i]=GetForegroundWindow();
            next=GetWindow(hwnd[i],GW_HWNDNEXT);
    		ShowWindow(hwnd[i],SW_HIDE);
    		SetActiveWND(next);
    I have no idea why, the variable "next" isn't null, but if I try to do anything with it, it doesn't work. I tried using ShowWindow(next,SW_HIDE); just to see if it would work, and it didn't. But when I inserted an If statement under next=GetWindow(hwnd[i],GW_HWNDNEXT); to check if "next" is null, it said it wasn't.

    Any other ideas?

  4. #4
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: SetActiveWindow() failing

    I would suggest to use Spy++. Put a breakpoint or a message after the GetWindow statement. Check the value of next and use Spy++ to find out which window that exactly is and whether it's the correct window that you actually really want.
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  5. #5
    Join Date
    Oct 2008
    Posts
    68

    Re: SetActiveWindow() failing

    I just tried using Spy++, and the handles GetWindow() returns cannot be found with their finder tool, but by searching I see the handles belong to the same process as the next window, so I believe those are child windows. The window caption of the hwnd returned by GetWindow is "M", and is owned by "Default IME", according to Spy++. What is this window? I see many instances of this window called "M," and is used in many different classes and applications, and includes classes like scroll bar. How can I find the whole entire next window, not just the scroll bar?
    Last edited by shadowx360; April 9th, 2009 at 06:26 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured