一、当需要激活的窗口是其他程序的窗口时,很简单,如下:
HWND hWnd=::FindWindow("Notepad",NULL);
::ShowWindow(hWnd,SW_RESTORE);
::SetForegroundWindow(hWnd);
二、当需要设置的窗口是自己程序的窗口,上面的代码就无效了。原因如下:
Windows 9x/2000中SetForegroundWindow函数当用户正在操作其他窗口时是不能强制某个窗口为前景窗口的,而是激活窗口并调用FlashWindowEx函数来通知用户。
三、解决方法:
方法一、(最理想的)
/****************************************************************************
将窗口设置为前景窗口。
关键API的使用::AttachThreadInput,这个API是连接两个线程的,使其共享输入焦点,键盘状态等等。
通常,系统内的每个线程都有自己的输入队列。本函数(既“连接线程输入函数”)允许线程和进程共享输入队列。连接了线程后,输入焦点、窗口激活、鼠标捕获、键盘状态以及输入队列状态都会进入共享状态调用这个函数时,会重设键盘状态。参数类型前的IN表示这个参数是输入参数,可以当它没有。
****************************************************************************/
void MySetForegroundWnd(HWND hWnd)
{
HWND hCurWnd = NULL;
DWORD dwMyID;
DWORD dwCurID;
hCurWnd = ::GetForegroundWindow();
dwMyID = ::GetCurrentThreadId();
dwCurID = ::GetWindowThreadProcessId(hCurWnd, NULL);
::AttachThreadInput(dwCurID, dwMyID, TRUE);
::SetForegroundWindow(hWnd);
::AttachThreadInput(dwCurID, dwMyID, FALSE);
if (IsIconic(hWnd)) //最小化时还原它
::ShowWindow(hWnd,SW_RESTORE);
}
方法二、(不是很理想)
/****************************************************************************
如何激活指定的窗口事件
我们知道,Windows 9x/2000中SetForegroundWindow函数当用户正在操作其他窗口
时是不能强制某个窗口为前景窗口的,而是激活窗口并调用FlashWindowEx函数来通知用户。
但是很多实际情况要求将激活窗口的同时将创建这个窗口的线程置为前景状态。碰到这种
情况我们可以使用USER32.DLL中的几个未公开API函数。
void SwitchToThisWindow (
HWND hWnd, // 被激活的窗口句柄
BOOL bRestore // 如果被极小化,则恢复窗口
);
****************************************************************************/
void MySetForegroundWnd2(HWND hWnd)
{
//必须动态加载这个函数
HMODULE hUser32=GetModuleHandle("user32");
if (hUser32)
{
void (WINAPI*SwitchToThisWindow)(HWND,BOOL)=
(void(WINAPI*)(HWND,BOOL))GetProcAddress(hUser32,"SwitchToThisWindow");
if (SwitchToThisWindow)
{
::SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
SwitchToThisWindow(hWnd,true);
::SetWindowPos(hWnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
FreeLibrary(hUser32); //释放调模块句柄
}
}
}