当前位置:首页 > Windows程序 > 正文

创建窗体不抢夺焦点的方法

2023-05-23 Windows程序

创建窗体,不抢夺焦点

 

经过资料查找,发现可以设置WS_EX_NOACTIVATE

?

界面编程里面,经常碰到焦点问题,以下几点可注意:

1. Create时指定 WS_EX_NOACTIVATE属性,注意同时去掉WS_VISIBLE,这样创建窗口时不会抢焦点。

2.响应 WM_MOUSEACTIVATE 消息,返回 MA_NOACTIVATE,这样鼠标在其上操作时不会抢焦点,在popup窗口上做这条即可,对其子窗口一并有效。?

3.可以用 GetGUIThreadInfo() 取得当前焦点相应信息,用于查看焦点抢占情况。

经过这样设置的窗口,基本上解决不了我的问题。原因如下:

WINDOWS为每一个线程创建一个数据结构称为"线程本地输入状态",里面记录了该线程创建的窗口中哪个是活动窗口,哪个具有输入焦点,以及光标等信息(由操作系统维护)。
根据以上原理,如果是一个线程创建的两个窗口,用户是无法控制输入焦点的。因此要想在激活另一个窗口时,同时不能改变输入焦点,只能让这两个窗口分属于不同的线程(不必是不同的进程)。
看了你的问题后,我有个方案觉得很适合你的要求:
1)Frame1始终让edit控件具有输入焦点;
2)Frame2由另一个线程来创建;
3)使用WIN32?API的AttachThreadInput(Thread1ID,?Thread2ID,?TRUE)将Frame1和Frame2两个窗口的线程本地状态关联起来;

说得通俗点,Frame1和Frame2共享一个输入焦点,且两个窗口共享所有的鼠标,键盘操作。这或许是AttachThreadInput这个API的命名又来。具体使用情况楼主看下MSDN,自己码下代码!

也就是说同一个线程创建的窗口用WS_EX_NOACTIVATE样式是没有效果的。

问题还是需要解决,经过查证已找到正确方法:

?

 

创建窗口时去掉WS_VISIBLE属性,,加上WS_DISABLED属性。

 

 

创建窗口,得到窗口句柄。

 

 

::ShowWindow(m_hWnd,SW_SHOWNOACTIVATE)显示窗口,则不会抢夺焦点。

 

 

更进一步,可以屏蔽鼠标点击时获得焦点的行为,响应WM_MOUSEACTIVATE,返回MA_NOACTIVATE

 

完美收工!

创建窗体不抢夺焦点的方法

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/71578.html

Jm-杰米博客Jamie
草根站长的技术交流乐园!IT不会不要紧快来好好学习吧!
  • 20786文章总数
  • 7470952访问次数
  • 建站天数
  • 友情链接