轻轻的我走了,正如我轻轻的来——Duilib无焦点窗体的实现
在Windows编程中,我们已经习惯了一个窗体从创建到显示并获得焦点。
我们总感觉一个窗体创建出来获得焦点是理所理所当然的。一个窗体仅仅要显示就必须获得焦点。一个新窗体显示时。会收到到WM_SETFOCUS消息。然后旧的窗体会收到WM_KILLFOCUS消息。可能我们并不关心焦点的切换,由于从视觉角度来看,没有不论什么影响,可是键盘类的消息却在焦点变化时不断切换响应窗体。我们都知道,鼠标消息到来时,决定哪个窗体响应的是鼠标的坐标点。指哪里打哪里。键盘消息到来时,是谁来决定这个消息由哪个窗体响应呢?答案就是焦点。焦点是键盘消息的“舞台”,不论什么一个窗体仅仅要登上焦点这个“舞台”,全部的键盘类消息自然会分配到该窗体的窗体过程函数。
只是话又说回来了,在什么情况下的窗体不须要获得焦点呢?我总结了一下。有两种情况:1.提示类窗体,像我们常见的tooltipWindow,酷狗的音乐列表上的提示窗体,还有我们每天都在使用的QQ,把鼠标移到你的头像上,出现的提示信息窗体,当QQ收到消息时,鼠标指到QQ的任务栏图标上时出现的消息列表提示窗体,等等。当然,你有可能会问了,提示窗体和焦点有什么关系,提示窗体获得焦点又如何?事实上表面上影响不是非常大,可是细致想想这是不符合原生的Window控件机制的,WM_MOUSEMOVE消息仅仅是个过客,键盘消息的“舞台”不能受鼠标移动干扰。比方我们打开QQ正在聊天时,或者正在填写一个比較繁琐的表格时。就晃了晃鼠标,光标没了。是不是非常蛋疼?我们还得又一次找到原来的编辑区,点一下刚才输入的位置让光标又一次出现才干继续输入。提示类窗体的创建和销毁往往是由WM_MOUSEMOVE来控制。所以呢这类窗体不能获得焦点。2.菜单窗体,Windows原生菜单是不获取焦点的,可能你还不信,事实上測试一下非常easy就能看出来。用Visual
Studio建一个带有菜单的Win32项目。在窗体过程函数中捕获WM_KILLFOCUS消息。当菜单弹出时,WM_KILLFOCUS是不会响应的。
这里肯定你还会问,菜单的弹出和焦点有毛关系,谁规定了菜单必须是无焦点的?当然没有人规定这些。可是遵循原生的机制绝对是没错的。首先,在自己使用窗体模拟菜单时,焦点的切换是一个非常大的障碍,当然。有人还利用了这个特性,用WM_KILLFOCUS消息来控制菜单的窗体的销毁,这点在仅仅有一级的菜单中还能体现出优势,可是在做级联菜单时,问题又来了。子菜单出来。主菜单就会失去焦点。这无形其中增添了不少麻烦。各级菜单的耦合度变高,维护起来相当复杂。其次,焦点的不断切换会影响美观,我一提这个,肯定还会有不少人产生疑问。这从何说起啊?焦点在菜单上看不见摸不着,怎么能影响外观?之前有人用Duilib写过一个MenuDemo,应该非常多人都在用,效果看起来也不错。可是我个人认为还是有问题。可能大家也不会把这个当成问题。当鼠标在主菜单上滑行时,子菜单会轮流弹出,假设这时碰巧你在这个窗体的某个编辑里开启输入法输完东西时,输入法的工具框还保留当前窗体,因为子菜单的切换显示。会导致输入法的工具框不断闪烁。我个人感觉是影响美观,不知道大家的看法。原因是因为焦点的切换。导致输入法消息的响应窗体不断切换。从而导致其闪烁。
酷我音乐盒应该大家都用过。假设没猜错的话,用的就是Duilib的MenuDemo来实现的菜单。
你能够试一下。切换成中文在搜索框里输入几个字,然后右击弹出菜单,用鼠标在主菜单上滑行。让子菜单轮流弹出,看看那个输入法工具框是不是在不停闪烁。还有酷我音乐盒的全部提示框都是带焦点的。在菜单弹出时。不得不屏蔽某些控件的MouseHover事件,防止提示框的弹出抢走焦点。导致菜单销毁。
我想这应该是因为Duilib眼下不支持无焦点窗体的原因,为了解决问题。Skilla在Duilib的菜单上花了不少时间,因为网上这方面的资料真心太少了。还好最后有了成果,所以还有机会和大家一起分享。
事实上,弄一个无焦点的窗体还是比較简单的。1.在窗体显示时,使用ShowWindow(SW_SHOWNOACTIVE),这样窗体显示时就不会获得焦点了。可是不能点击,点击完还是会获得焦点。 2.在窗体过程中截获WM_MOUSEACTIVATE消息,返回MA_NOACTIVE,这样就完美了,这时在客户区任凭你把鼠标左键右键全点烂了这个窗体也不会获得焦点。可是不能点标题栏,这也无妨,在Duilib中我们的窗体通常是不带原生标题栏的,把标题栏去掉就是了,这时仅仅要你不主动去SetFocus,窗体是永远不会获得焦点的。
假设仅用Win32或者MFC编程,上面两步就够了。但我们还使用了Duilib框架,关于窗体焦点的控制參与的不不过CWindowWnd。CPaintManagerUI也做了大量的::SetFocus操作,假设不做处理窗体还是照样会获得焦点。
这时我们须要对源代码做一下小小的改动。1.给CPaintManagerUI加入一个布尔类型属性bool m_bUnfocusPaintWindow;来区分所绘制窗体是否为无焦点窗体,在构造时初始化为false。并加入Get、Set方法。让外界能訪问到。2.在CPaintManagerUI的cpp文件里查找全部的::SetFocus操作(注意前面的两个点),给全部的::SetFocus操作加上if(!m_bUnfocusPaintWindow)的推断。这时我们仅须要在将m_bUnfocusPaintWindow设置为true就可以防止CPaintManager抢走焦点。这样既不影响原来的功能,又达到了我们想要的效果。3.为了方便使用在CDialogBuilder的cpp文件的219行加上一个推断
else if(_tcscmp(pstrName, _T("unfocus")) == 0)
{
if(_tcscmp(pstrName,_T("true")))
pManager->SetUnfocusPaintWindow(true);
}
这样,我们就能够在xml里面设置窗体是否为无焦点窗体了,仅仅需在Window标签上加一个unfocus="true"的属性就能够了。比如
<Window size="400,240" caption="0,0,0,40" roundcorner="5,5" unfocus="true">
这仅仅是无焦点窗体在TipWindow上的应用,关于菜单的实现我会尽快写好Demo来和大家一起分享。
假设大家还有什么不明确的地方。或者对我的改动有什么意见或的法的,能够直接留言,或者联系QQ:848861075(Skilla)
轻轻的我走了,正如我轻轻的来——Duilib无焦点窗体的实现的更多相关文章
- shell 4注释
单行注释 每一行加一个#号. #shell #!/bin/sh echo "#" #轻轻的我走了 #正如我轻轻的来 #我挥一挥衣袖 #不带走一片云彩 echo "#&qu ...
- UILabel 常见问题总结
写在前面:笔者在iOS软件开发中发现UILabel控件有些问题反复出现,所以在这里做点总结,方便自己查阅,也能给大家提供相关问题的解决方案. 一:当label里的内容显示满了的时候,能够自动将字体变小 ...
- Learn day1 变量/数据类型
1.Python 简介 (1) 1989年开发的语言,创始人范罗苏姆(Guido van Rossum),别称:龟叔(Guido). (2) python具有非常多并且强大的第三方库,使得程序开发起来 ...
- 新版本MenuDemo——使用Duilib模拟Windows本机菜单
相信玩Duilib朋友已经开始期待一个很长的文章.由于我的文章在一周前公布--"无焦点窗体的实现"里面提到了无焦点窗体在菜单里面的应用,并承诺大家,写一个关于Menu实现的Demo ...
- Markdown
1. 斜体和粗体 代码: *斜体*或_斜体_ **粗体** ***加粗斜体*** ~~删除线~~ 显示效果: 这是一段斜体 这是一段粗体 这是一段加粗斜体 这是一段删除线 2. 分级标题 第一种写法: ...
- TCP同步传送数据示例(简洁、清楚)
转自:http://www.2cto.com/kf/201206/134841.html 本例子写了个简单的TCP数据传送功能.没有使用BinaryWriter,BinaryReader,而是使用Ne ...
- WPF中的Style
一.Style基础知识 构成Style最重要的两种元素是Setter和Trigger Setter类帮助我们设置控件的静态外观风格 Trigger类帮助我们设置控件的行为风格 Setter类的Prop ...
- 分享几个python小脚本
by 梁凯 今天我想给大家分享几个python脚本,分别是: 1.公司访问外网认证脚本(最初有同事写过,我优化了一下). 2.统计周报系统所有同事的最近一篇周报. 3.统计测试技术分享里指定一个月所有 ...
- Markdown几个简单的例子
定义型列表 语法说明: 定义型列表由名词和解释组成.一行写上定义,紧跟一行写上解释. 解释的写法:紧跟一个缩进(Tab) Markdown : 轻量级文本标记语言,可以转换成html,pdf等格式(左 ...
随机推荐
- px,dp,sp以及像素密度
px px(pixel): 像素,是指在由一个数字序列表示的图像中的一个最小单位.在Android中,无论屏幕密度多少,一个像素单位对应一个屏幕像素单位,不会根据屏幕密度自动缩放,因此一般不推荐使用p ...
- Windows下Apache2.2+PHP5安装步骤
Windows下Apache2.2+PHP5安装 初学者在学习PHP的时候可能都会遇到安装Apache和PHP不成功的问题,于是很多开发者便选择了集成包,一键安装好Apache+PHP+MySQL.但 ...
- CDOJ 1292 卿学姐种花 暴力 分块 线段树
卿学姐种花 题目连接: http://acm.uestc.edu.cn/#/problem/show/1292 Description 众所周知,在喵哈哈村,有一个温柔善良的卿学姐. 卿学姐喜欢和她一 ...
- java 高并发 订单编号递增(解决方案)
业务描述: 首先从数据中查找最近的一条订单数据,然后将之前的订单号码+1作为新的订单号码,插入到数据库当中.(需求不能改变) 当出现并发操作时,A从数据库中获取最近一条订单的订单号为N,这是A还没有完 ...
- Java 常用远程调用协议比较
一.综述本文比较了RMI,Hessian,Burlap,Httpinvoker,web service等5种通讯协议的在不同的数据结构和不同数据量时的传输性能.RMI是java语言本身提供的远程通讯协 ...
- object-c语言的nonatomic,assign,copy,retain的区别
nonatomic: 非原子性访问,不加同步,多线程并发访问会提高性能.如果不加此属性,则默认是两个访问方法都为原子型事务访问. (atomic是Objc使用的一 ...
- Spring自动装配Beans
在Spring框架,可以用 auto-wiring 功能会自动装配Bean.要启用它,只需要在 <bean>定义“autowire”属性. <bean id="custom ...
- 介绍:一款Mathematica的替代开源软件Mathetics
Mathetics软件 1 以Python语言实现该系统 2 软件使用的语法与Mathematica同样 3 下载:http://www.mathics.org/ 4 手冊:http://www.ma ...
- 周赛 POJ 3934 Queue
Description Linda is a teacher in ACM kindergarten. She is in charge of n kids. Because the dinning ...
- Android 4.0 x86安装教程 附带联网参数详细设置
Android 4.0 x86是一个可以支持在电脑上运行的Android 4.0系统.没有手机一样也可以体验Android 4.0.这对玩机爱好者们来说也算得上是一个不大不小的好消息.不过目前的And ...