|
-
April 4th, 2009, 04:17 PM
#1
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?
-
April 5th, 2009, 03:49 AM
#2
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);
}
-
April 5th, 2009, 05:12 PM
#3
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?
-
April 6th, 2009, 02:05 AM
#4
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.
-
April 9th, 2009, 05:43 PM
#5
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|