轻轻的我走了,正如我轻轻的来——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等格式(左 ...
随机推荐
- PHP+MySQL中字符集问题分析
Character set顾名思义,就是字符.以及字符对应的编码的集合.例如简体中文字符集gb2312就包括简体中文中的所有规定汉字,以及每个汉字对应的代码. Collation,是指比较字符的规则的 ...
- 【洛谷】1972:[SDOI2009]HH的项链【莫队+树状数组】
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- web前端 -- onkeydown、onkeypress、onkeyup、onblur、onchange、oninput、onpropertychange的区别
FROM:http://www.cnblogs.com/svage/archive/2011/11/15/2249954.html onkeydown:按下任何键(字母.数字.系统.tab等)都能触发 ...
- Codeforces Round #194 (Div. 1) A. Secrets 数学
A. Secrets Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/333/problem/A ...
- PAT甲级1049. Counting Ones
PAT甲级1049. Counting Ones 题意: 任务很简单:给定任何正整数N,你应该计算从1到N的整数的十进制形式的1的总数.例如,给定N为12,在1,10, 11和12. 思路: < ...
- Added components improve switching-regulator stability
Added components improve switching-regulator stability
- HelloWorld 和相关设置
写这篇文章的初衷很简单,就是想再一次证明 IntelliJ IDEA 对于 Java 开发人员来说,确实比 eclipse 要好用得多,鉴于目前市面上关于 IntelliJ IDEA 的教程比较少,叙 ...
- java 日期工具类
import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; imp ...
- pytest文档10-命令行传参
前言 命令行参数是根据命令行选项将不同的值传递给测试函数,比如平常在cmd执行"pytest --html=report.html",这里面的"--html=report ...
- 8.volatile原子性
原子性 1.一个操作是不可中断的,即使多个线程在一起执行的时候,一旦操作执行开始,就不会被其他的线程干扰执行并导致执行中断. 2.对于静态变量int ,2个线程同时对它进行修改,线程a ...