windows编程中,如何让一个窗口实现真正的置顶

    也许你会说,很简单啊。用“::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);”这个函数不就一下子可以解决了。然而事实有时却没有这么容易。

        前几天做了一个项目,我们的软件是对接体重秤的,有的时候需要刷卡(刷卡器扫描二维码),刷卡的实质其实接收的是键盘上的消息。但是有的时候却会有广告弹出来,弹出来的广告会抢占当前刷卡的主界面,导致刷卡不成功。这个时候我们需要将我们的窗口再次置顶。可以使用一下两个函数。

SetForegroundWindow(m_hWnd);
SetFocus(m_hWnd);

        对于接收普通的消息,此时可能已经满足需求了。但是刷卡需要接收的是键盘的消息,光是上面的两个函数,还不足以将光标置顶。于是代码就变成了下面的这种:

AttachThreadInput(GetWindowThreadProcessId(::GetForegroundWindow(), NULL), GetCurrentThreadId(), TRUE);
SetForegroundWindow(m_hWnd);
SetFocus(m_hWnd);
AttachThreadInput(GetWindowThreadProcessId(::GetForegroundWindow(), NULL), GetCurrentThreadId(), FALSE);

重点就是AttachThreadInput这个函数的使用,这个函数中将当前应用程序中的当前线程连接到最前端的窗口中,就导致键盘输入的消息会最先本分发到当前的线程中。之后设置当前窗口的焦点之后,释放连接。

       为了使得代码达到最优,我们可以将线程的连接与消息的响应关联起来。其他进程消息的响应是WM_ACTIVATEAPP,但是我们不能将上面的代码写在这个消息里,不然会不起作用,于是我就设置了一个定时器。

else if (uMsg == WM_ACTIVATEAPP){
    m_bOutFocusFlag = true;
    SetTimer(m_hWnd, FOCUSE_OUT_ID, 60, NULL);
}

定时器中的代码如下:

else if (FOCUSE_OUT_ID == nIDEvent){
    AttachThreadInput(GetWindowThreadProcessId(::GetForegroundWindow(), NULL), GetCurrentThreadId(), TRUE);
    SetForegroundWindow(m_hWnd);
    SetFocus(m_hWnd);			    
    AttachThreadInput(GetWindowThreadProcessId(::GetForegroundWindow(), NULL), GetCurrentThreadId(), FALSE);
    m_bOutFocusFlag = false;
    KillTimer(m_hWnd, FOCUSE_OUT_ID);
}


另外有任何补充的地方,欢迎在下方评论或是留言。


 

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值