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


    创建窗体,不抢夺焦点

    http://www.cnblogs.com/cartler/

    经过资料查找,发现可以设置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样式是没有效果的。

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

     

    1. 创建窗口时去掉WS_VISIBLE属性,加上WS_DISABLED属性。
    2. 创建窗口,得到窗口句柄。
    3. ::ShowWindow(m_hWnd,SW_SHOWNOACTIVATE)显示窗口,则不会抢夺焦点。
    4. 更进一步,可以屏蔽鼠标点击时获得焦点的行为,响应WM_MOUSEACTIVATE,返回MA_NOACTIVATE

    完美收工!

  • 相关阅读:
    库函数(汇总)
    IE jQuery ajax 请求缓存问题
    Jarvis OJ-level3
    在64位的linux中运行32位的应用程序
    ROP之linux_x64知识杂记
    2017年网络空间安全技术大赛部分writeup
    Sniper OJ部分writeup
    gdb插件使用方法
    pwntools学习
    linux虚拟机安装值得注意的几点
  • 原文地址:https://www.cnblogs.com/cartler/p/4537719.html
Copyright © 2020-2023  润新知