Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

switching windows by titlebar text/name

12 views
Skip to first unread message

John Doe

unread,
Feb 20, 2014, 8:09:45 PM2/20/14
to
[For the record]

I meant to implement this but then got wrapped up in adapting my
macro recorder to Age of Empires. Found on the web, it makes a lot
of sense. Activating another process's window just requires pressing
the alt key first. That disarms Windows' lockout of
SetForegroundWindow(). I implemented it briefly and it did work. The
last part releases the alt key. But do not check whether releasing
the key is okay (releasing a key doesn't hurt anything, just do it).
Also... MFC includes a function to check whether the window is
iconic. Check that first and you will also successfully pull up
minimized windows from the taskbar. I did use the code below
"keybd_event", but it probably works with SendInput() as well.

void SetForegroundWindowInternal(HWND hWnd)
{
if(!::IsWindow(hWnd)) return;
BYTE keyState[256]={0};
//to unlock SetForegroundWindow we need to imitate Alt pressing
if(::GetKeyboardState((LPBYTE)&keyState))
{
if(!(keyState[VK_MENU]&0x80))
{
::keybd_event(VK_MENU,0,KEYEVENTF_EXTENDEDKEY|0,0);
}
}
::SetForegroundWindow(hWnd);
if(::GetKeyboardState((LPBYTE)&keyState))
{
if(!(keyState[VK_MENU]&0x80))
{
::keybd_event
(VK_MENU,0,KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP,0);
}
}
}

John Doe

unread,
Feb 24, 2014, 12:32:16 AM2/24/14
to
[So I don't misplace the thing]

BOOL CALLBACK EnumWinHandle(HWND hWnd,LPARAM lparam)
{//list all Windows
if(IsWindowVisible(hWnd))
{//ALL, only normal windows
GetWindowText(hWnd,buffer,400);
if(wcsstr(buffer,L"Xnews"))
{//ALL-NRM, activate the window
//to unlock SetForegroundWindow we need to imitate Alt pressing
if(GetKeyboardState((LPBYTE)&keyState))
{//ALL-NRM-ACT, get keyboard state
if(!(keyState[VK_MENU]&0x80))
{//ALL-NRM-ACT-KBD, press alt key
keybd_event(VK_MENU,0,KEYEVENTF_EXTENDEDKEY|0,0);
}//ALL-NRM-ACT-KBD, press alt key
}//ALL-NRM-ACT, get keyboard state
if(IsIconic(hWnd))
{//ALL-NRM-ACT, restore if minimized
OpenIcon((hWnd));
}//ALL-NRM-ACT, restore if minimized
else
{//ALL-NRM-ACT, switch to window
SetForegroundWindow(hWnd);
}//ALL-NRM-ACT, switch to window
//ALL-NRM-ACT, release alt key
keybd_event(VK_MENU,0,KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP,0);
return FALSE;//stop enumerating
}//ALL-NRM, activate the window
}//ALL, only normal windows
return TRUE;//continue enumerating
}

if(KeyUp)
{//K-IDL-ENUM, upstroke
EnumWindows(EnumWinHandle,NULL);
}//K-IDL-ENUM, upstroke

John Doe

unread,
Mar 4, 2014, 12:18:54 PM3/4/14
to
Taking time out from AoE2 to implement it. Current progress.
Apparently just finished reading the Vocola 2 titlebar string that
looks something like this...

"^Destination Window Title^"

The carrot symbols are ignored, the titlebar text is between them.

Below... First is the updated but preliminary window switching
code. It's going in the DLL because it is systemwide (window
switching is usable in all programs). An exact window titlebar
match will have priority, after that it will search for partial
matches, and maybe then for a case insensitive match. I have no
plans to start applications with it, the window must be open or
minimized to the taskbar. Following that is the just finished
input reading code. EnumWinHandle() is before the keyboard hook in
the DLL file.



BOOL CALLBACK EnumWinHandle(HWND hWnd,LPARAM lparam)
{//look for matching window titlebar
if(IsWindowVisible(hWnd))
{//FND, normal window titles
GetWindowText(hWnd,TitleBar1,256);
if(strstr(TitleBar1,TitleText))
{//FND-NRM, activate the destination window
//FND-NRM-ACT, press alt key
ZeroMemory(SI,sizeof(INPUT));
SI[0].type=INPUT_KEYBOARD;
SI[0].ki.wVk=VK_MENU;
SI[0].ki.dwFlags=0;//press
SendInput(1,SI,sizeof(INPUT));
if(IsIconic(hWnd))
{//FND-NRM-ACT, restore destination window if minimized
OpenIcon((hWnd));
}//FND-NRM-ACT, restore destination window if minimized
else
{//FND-NRM-ACT, switch to destination window
SetForegroundWindow(hWnd);
}//FND-NRM-ACT, switch to destination window
//FND-NRM-ACT, release alt key
SI[0].ki.dwFlags=KEYEVENTF_KEYUP;
SendInput(1,SI,sizeof(INPUT));
return FALSE;//stop enumerating
}//FND-NRM, activate the destination window
}//FND, normal window titles
return TRUE;//continue enumerating
}//look for matching window titlebar



char TitleText[280]={};
BYTE KeyboardState[256]={};
char KeyInput[32]={};

if(GetTitle)
{//K, reading input for window switching
if((wParam==VK_6)&&(GetKeyState(VK_SHIFT)&0x8000))
{//K-IN, switch windows
if(KeyUp)
{//K-IN-SWITCH, upstroke
//EnumWindows(EnumWinHandle,NULL);
OutputDebugString(TitleText);
GetTitle=false;
*TitleText='\0';
}//K-IN-SWITCH, upstroke
return 1;
}//K-IN, switch windows
else
{//K-IN, add characters to titlebar search string
if(wParam!=VK_SHIFT)
{//K-IN-ADD, reject shift key
if(KeyUp)
{//K-IN-ADD-NIFT, upstroke
GetKeyboardState(KeyboardState);
ToAscii(wParam,MapVirtualKey(wParam,0),KeyboardState,(LPWORD)KeyInput,0);
strcat(TitleText,KeyInput);
}//K-IN-ADD-NIFT, upstroke
}//K-IN-ADD, reject shift key
return 1;
}//K-IN, add characters to titlebar search string
}//K, reading input for window switching
else
{//K
if((wParam==VK_6)&&(GetKeyState(VK_SHIFT)&0x8000))
{//K, begin reading titlebar text for window switching
if(KeyUp)
{//K-IN, upstroke
OutputDebugString("First ^, Start recording\n");
GetTitle=true;
}//K-IN, upstroke
return 1;
}//K, begin reading titlebar text for window switching
}//K

John Doe

unread,
Mar 7, 2014, 8:40:55 PM3/7/14
to
I just noticed that in Windows 7 at least one program "EditPad Lite"
when minimized to the taskbar has a different pop-up title that
doesn't match the title bar when the window is visible. And
apparently consequently it isn't pulled out of the taskbar unless the
window search text matches the (different) minimized window title
text. That could be a reason for occasional failure. In which case
the search text would have to be shortened so that it matches both
minimized and visible window title text.
0 new messages