GetActiveWindow 这个函数是干嘛的

2020-12-13 03:05

阅读:358

To get the handle to the foreground window, you can use GetForegroundWindow.

Windows 98/Me and Windows NT 4.0 SP3 and later: To get the window handle to the active window in the message queue for another thread, use GetGUIThreadInfo.

//如果要获取前台窗口的句柄,你应该使用  GetForegroundWindow 。

//如果要获取其它线程中的活动窗口,你应该使用  GetGUIThreadInfo。


好了,说了这么多,我们终于有点眉目了。

虽然编辑框也是窗口,但这个函数中说明的窗口是指

  • Overlapped Windows   重叠窗口

  • Pop-up Windows       弹出窗口

,而不是

  • Child Windows        子窗口

  其实窗口还有另外两种类型

  • Layered Windows      带透明效果的窗口

  • Message-Only Windows 仅消息窗口(不可见,没次序,仅允许收发消息)


好了,这样我们就明白了,编辑框是窗口不假,但是它是子窗口,而且在MFC对这个函数的说明不是太明确。


现在也就是 如果 我们再开一个工作线程,在这里来 用 GetActiveWindow  ,这是肯定不行的,因为我们的这个工作线程 自身 并没有创建窗口。当我们激活一个窗口时,就是在任务栏点击一个窗口程序,这个时候这个程序就拥有了输入焦点,它就是活动窗口。


还是之前的例子,我们在 程序的 标题栏上右击,选择关于 ,此时会再弹出一个模态对话框,如下图

soscw.com,搜素材


可以看出不再是主对框了,因为在没有弹出Test 那个对话框之前,About Test 才是 这个线程 中的 活动窗口。如果再等 几十秒(不要点确定),会发现 他还会弹出 提示框,而且每次的结果都不一样,

soscw.com,搜素材


这是因为当第一个提示框弹出后,它就变成了活动窗口了,第2个弹出的就是第一个的句柄了,第3个弹出的就是第二个的句柄了。


当我们一切到其它窗口的时候,程序会因为断言宏 的问题 而中断。


还有一个问题 就是,我们可以开一个线程,来获取 其它线程中的 活动窗口。


定义一个线程


UINT __cdecl Worker( LPVOID pParam )
{
    CTestDlg  * pDlg = (CTestDlg *)pParam;
    ASSERT(pDlg != NULL);
    DWORD  tid = GetWindowThreadProcessId(pDlg->m_hWnd,NULL);
    GUITHREADINFO   guiTI = {0};
    guiTI.cbSize = sizeof(GUITHREADINFO);
    GetGUIThreadInfo(tid,&guiTI);
    CString  str;
    str.Format("%x\n",guiTI.hwndActive);
    AfxMessageBox(str);
    return 0;
}


然后将 计时器  中 换成

    switch (nIDEvent)
    {
    case 1:
        {
            AfxBeginThread(Worker,(LPVOID)this);
        }
        break;


soscw.com,搜素材

这样子依旧可以获取 其 活动窗口,当然可以利用这种方式 来获取  其它 软件 的 活动窗口哦。


如果还有不明白的地方,那就是前台窗口 与 活动窗口 这两个概念的 区别了。


不妨来做个测试。

我们随便写个小按钮响应事件


//点击开始菜单,点击运行,,输入  notepad 回车即可

    HWND     hwndNotepad = ::FindWindow(NULL,"无标题 - 记事本");
    ASSERT(hwndNotepad != NULL);
    ::SetForegroundWindow(hwndNotepad);


功能就是将记事本  置成前台,我们发现 记事本  果然就 跑前面来了,而且也被激活了。


那么它们到底有什么区别吗?


1、设置都没有什么好说的

2、获取,一个是针对某一线程进行获取,一个是针对整个系统中的所有窗口进行获取

3、反上去,其它设置也是范围不同,一个针对线程,另一个针对系统。


什么时候应该哪个,要取决于你具体的目的是什么,然后再做一个判断。


其实说到这里应该结束了,但是其实还有一点,就是如何 在一个线程中,激活另一个线程中的 窗口,说白了就是 线程A 没有窗口,线程B有3个窗口,我想用A 激活B中的 2号窗口,怎么办。 获取是 使用的GetGUIThreadInfo ,设置 可没有  SetGUIThreadInfo 这个函数的,


这个时候 ,我们应该行看看MSDN中有没有办法


By using the AttachThreadInput function, a thread can attach its input processing to another thread. This allows a thread to call SetActiveWindow to activate a window attached to another thread‘s message queue.


可以看到 可以使用 AttachThreadInput 这个函数可以将 一个线程 的输入处理 关联到 另一个线程,进而 完成 设置 其它线程中的 活动窗口的 目的。


可能有的人还不清楚 一个程序到底有多少个窗口,哈哈,这个是初学者最不容易理解的地方,一个程序可以有多个窗口的,举一个例子吧,VS2008 等类似的软件有吧,,知道怎么设置行号吗,知道怎么改变字体大小吗,知道怎么新建工程吗,知道怎么添加文件吗,好吧,这些功能,每一个都是一个对话框哦,再比如,一个记事本程序,里面有搜索功能吧,这也是一个对话框,还有 最后一个例子,


直接上图

soscw.com,搜素材


好了,我想大家对活动窗口应该理解了吧。。。。


评论


亲,登录后才可以留言!