mfc自绘按钮,mfc绘图教程
我从这学期开始学习mfc。目标是做一个播放器界面,主要是打好基础,因为我的基础真的很差.说说我自己的经验和自画控件的方法。让我们把它吐出来。如有错误或不完整之处或更好的方法,请不吝赐教。
我的机器环境是:Windows7旗舰版Service Pack 1,Visual studio 2005。
1).重绘控件时,强烈建议使用子类化方法。比如你想自己画一个按钮控件,先添加自己继承自CButton的类CMYButton,声明一个CMYButton对象,然后使用subclassDLGitem (uinnid,cwnd * p parent);//第一个参数表示控件ID,第二个参数表示指向父窗口对象的指针,一般用这个表示(如果不想用SubclassDlgItem。然后就可以使用CMYButton本身提供的Create方法动态创建按钮了。这样就可以在自己的类中添加重写WindowProc()的窗口过程函数。非常非常重要,其他自绘控件参考这个。
2).我入手的第一个控件是Button,我终于知道我的基础有多差了。getDLGitem()和subclassDLGitem()等很多基本函数我都不知道。我花了很多时间,通过查资料,看源代码,基本完成了Button的自绘。另外,自画
默认情况下,按钮不能响应键盘按Enter,所以需要一些额外的处理。(关键词:BS_OWNERDRAW,DrawItem),(后期通过模仿qq登录按钮添加了一个效果。悬停和离开是渐进的,只是在设定中。
使用对话框中的按钮)
3).然后是单选按钮。实际上,复选框类似于按钮。建议了解三个API函数check单选按钮()、setcheck()和getcheck()。
4).另外,不规则按钮的实现需要掌握三个API函数,setWindowRGN()、CombinerRGN()和SelectClipRGN()。其他不规则的窗口和控件也可以参考这个方法。
5).然后编辑控件自绘,不完全自绘,只重绘非工作区(如无特殊需要,无需重绘工作区),改变背景颜色和字体。不过我后期加了一个效果。当鼠标处于编辑状态和离开编辑状态时,边框逐渐变化(关闭
关键词:CtlColor,WM_NCPAINT),RichEdit也可以用这个方法
6).然后就是工具提示(气泡提示控件)。微软提供了通知消息NM_CUSTOMDRAW,以WM_NOTIFY的形式发送。您可以使用MFC类向导将其添加到您自己的派生类中。不过我建议重写OnPaint函数,完全自己画(难度:
需要根据文本内容计算控件的大小和显示位置。)后期实现了淡入、点击/超时的效果(TTN_POP和TTN_SHOW两个公告消息需要贴图),移出和淡出的效果未能实现。请指导。
7).然后就是Sliderctrl。微软提供了通知消息NM_CUSTOMDRAW,以WM_NOTIFY的形式发送。您可以使用MFC类向导将其添加到您的派生类中。我前期用过这个方法,后来发现这个方法有很大的局限性。
推荐重写OnPaint函数,完全自绘(重点:在PreSubclassWindow中保存Thumb(拇指按钮)、Channel(凹槽)和整个控件大小,以便在OnPaint中绘制)
8).然后是静态控制。这个比较简单。重写OnPaint函数来绘制文本,并将DC设置为透明模式。有人会说直接在CtlColor中设置bKMode(透明)就可以了,不用在OnPaint中处理,但是有一个问题。
是的,如果要求文本一直改变,旧的文本不被擦除,新设置的文本再次被覆盖。所以要根据这个控制的目的来选择合适的方法。
9).然后是菜单,这个比较难。严格来说,Menu不是一个控件,但它是从CObject类派生出来的。微软为自绘提供了MeasureItem和DrawItem虚函数类。MeasureItem用于计算菜单的高度和宽度。该系统
菜单的宽度将自动基于最长的文本内容。DrawItem,顾名思义就是绘图,但是有一个致命的问题。自画菜单有系统默认边框,很邪门很丑,(ModifyStyle和
SetWindowLong无法脱离边界)这时我在自己的CMYMenu中发现,微软只给我们提供了仅有的五个虚函数,而没有提供WindowProc(),即窗口过程函数。这不是诡计吗.这时,一般的做法是从
CWnd自己实现菜单的功能。不过查了资料,还是可以自己画:需要用钩子替换菜单的窗口进程,在WM_CREATE的时候去掉边界Stytle。感兴趣的朋友可以谷歌一下。(难点:更换菜单窗口的过程)
10).然后是Combobox控件,难度比较大。微软提供了四个虚函数,CompareItem,DeleteItem,DrawItem,measure item,用于自绘。我只用了后两个,(如果只加了CBS_SORT,我得重写CompareItem。
函数,除非使用CBS_HASSTRINGS CBS_SORT,否则不能重写CompareItem()。不要以为这样就完了。运行后,Combobox显示的列表具有系统的默认边框!ModifyStyle和SetWindowLong
不要放弃界限。老规矩,查资料,不看,不了解,一看就吓一跳。Combobox由三个控件组成(难怪叫组合框),即编辑、列表框和组合本身(除了编辑和列表框的其余部分)。当时我很震惊,也很迷茫。
加油!此时需要添加OnCtlColor函数,使用SubclassWindow () API函数子类化ListBox和Edit(在此之前需要准备自画ListBox控件和Edit控件)。Combobox有三种样式。
CBS_SIMPLE,CBS_DROPDOWNLIST,CBS_DROPDOWN,第一个不常用,第二个是不能输入但要点击选择,第三个可以输入并点击选择。我的程序使用CBS_DROPDOWNLIST样式。
11).Windows7下的Combobox比较混乱:关闭滑动打开组合框效果,自画的combo box可以去除边界,剪切窗口(圆角矩形)。如果开启了滑开组合框效果,系统会添加一个边框,切掉的圆角会
已经变成直角了。跟踪调试发现是WM_WINDOWPOSCHANGING消息中的鬼。有兴趣的朋友可以对比看看,暂时找到解决办法。打开/关闭滑动打开组合框效果:电脑-右键属性-高级系统设置-高级-性能设置-视觉效果
12).然后就是TabCtrl。微软提供了两个虚拟函数,DrawItem和MeasureItem,用于自绘制。TCS _ OWNERDRAWFIXED的Stytle需要添加,说明这个控件需要自绘。不过我没有用这个方法,直接重写了OnPaint函数。
完成自绘(难度:需要计算每个标签的大小和位置,以及与之绑定的对话框的显示位置)13)。最后,表单框架(非客户区)的绘制比较困难。阅读很多例子的源代码要花很多时间。WM_MOVE、WM_PAINT、WM_NCPAINT、WM _ NCACTIVATE是自绘成功的关键。
计算边框/标题栏的大小和位置(Win7和Xp下GetSystemMetrics()的返回值不同)。//给出框架图的关键代码,不闪烁,完全原创。if(message==WM _ n activate!wParam) //wParam=0,deactivate { return 1;//必须返回1才能处理默认消息(如果不返回1,所有弹出窗口(模态和非模态)都无法点击)} if(message==WM _ n activate wparam)//wparam=1,active { return 0;//这只是返回(0和1都可以)} if(message==WM _ NC paint){ return 0;//屏蔽默认的框架图(某应用处理此消息返回零取自MSDN)}这种方式保留了边界和标题栏,实际上覆盖了原图本身,只要不闪就成功了。当然你也可以去掉系统默认的边界和标题栏,在客户区计算一个边界和标题栏,处理一些消息,可以达到更好的效果。
框架自绘,制作更美观的界面。
14)也许我有点令人讨厌。我在想,既然做了播放器界面,为什么不给他一个播放功能?微软提供了MCI—媒体控制接口,自己封装了一个回放类,实现了一些基本的回放功能。像这样,第一个
假设版本完成了。
-测试环境:6 Win7和2 Xp -接口测试:Win7和Xp运行正常(一个缺陷见第11条)-播放测试:我可以在电脑上播放rmvb、RM、AVI、MP4、WMV、FLV。一些测试的Win7电脑可以播放所有六种格式,但一些测试的Win7电脑只能播放AVI和MP4。解决办法.)-此外,WMV格式似乎不可能提高回放速度和降低回放速度。-XP系统下,可以打开视频文件,但是只能听到声音,看不到图像。求解答?结果真的很痛苦。可以测试一下,看看接口是否正常,播放功能是否正常。
15)鉴于MCI版本播放测试不理想,我再次蛋疼,因为有个学长说让我用Activex控件试试。嗯,花了两天时间研究Activex控件,用OleView研究控件图层。APlayer_001.dll是ActiveX控件的一个播放器(Activex控件必须注册后才能使用。如果代码中只注册了一个APlayer_001.dll,程序可以运行但文件不能播放,因为播放文件时,
Aplayer控件还会根据播放文件的类型加载一些DLL文件和AX文件。这些文件加起来超过8000万,也就是.)其实一个播放器就是迅雷的一个组件。如果安装了Thunderbolt,会安装在C:\
\程序文件\ \常用文件\ \迅雷网可以找到文件夹Aplayer,没有迅雷或者Aplayer程序就无法运行。注意:这个播放器本身有缺陷。播放Rmvb和mkv文件时,点击定位不准确。对于大文件,很难发现这个缺陷。可以找一个一两分钟的短视频文件,用迅雷看看。单击并找到它。缺陷非常明显。由于Aplayer的流程与MCI不同,制作第二版花了一些时间。
-测试环境:6 Win7和2 Xp -接口测试:Win7和Xp运行正常(一个缺陷见第十一条)-播放测试:RMVB、RM、AVI、MP4、WMV、FLV、MKV、MP3、WMA、WAV可以在Win7上做一个播放器-Xp系统下打开文件,)。-另外,程序还有一个缺陷:第一次点击Aplayer控件时会收缩。调试发现根本没有进入WM_LBUTTONDOWN。直接就是WM_WINDOWPOSCHANGING,WM_WINDOWPOSCHANGED,WM_SIZE。我不知道这条消息是从哪里来的.(我用了一个不太好的方法解决了,由于它只会在我第一次点击的时候收缩,我在PreSubclassWindow:PostMessage(WM _ lbuttondown,MK _ lbutton,
(LPARAM)user down);PostMessage(WM_LBUTTONUP,MK_LBUTTON,(LPARAM)user down);)这两条消息好像没有再缩小,但是昨天我跑步的时候又出现了这个问题,出现的概率很低。
无语)
16)程序的测试都是我自己做的,很多功能没有及时测试,所以程序可能会出现一些问题。这件事一个人做不了。希望是温柔的。程序热键,做的不好,不是全局和后台,窗口必须得到焦点才能响应。后期增加了托盘功能。增加了播放列表功能,最多支持10个文件。如果超过10个文件覆盖了第10个文件,请双击列表中的文件名来播放该文件。但是,我没有为播放列表单独制作一个窗口。它位于“设置”对话框的第三个选项卡上。在同学的强烈要求下,我增加了拖拽打开文件的功能(我过滤了一些文件扩展名,但是拖拽并不是对每个文件类型都有效。mci版和Activex版支持的格式不同,过滤情况也不同。)这个程序本来叫IKAN播放器,但是我发现PPLive已经用了这个名字,改成了ICAN播放器。
注:大三在读,现在处于实习找工作阶段。当我在上次面试中向面试官展示这个程序时,他说,“你可以在网上搜索很多这个程序”.我很能理解他的想法。如果我是面试官,我也会持怀疑态度。所以现在不方便给出源代码。希望大家能理解我,以后给项目源码。
我不知道如何上传帖子的附件。该程序位于CSDN资源区,因此不需要资源共享。我们下去看看吧。给链接:http://download..net/source/3428958
论坛上还有我的帖子:3358 topic . . net/u/2011 07 10/19/5209 f358-31 c8-4057-B108-02155 a 417 FD 0 . html?61362
让我们运行它,看看是否有任何问题或异常。欢迎回复。既然论坛不让我开300分的帖子,我打算以后开两个100分的。只要回复这个帖子的朋友都可以获得积分。
来自:http://blog . . net/xiexiyvv/article/details/6596411
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。