前言:从这学期开始就一直在学习自绘控件(mfc),目标是做出一款播放器界面,主要是为了打好基础,因为我基础实在是很烂....说说我自己心得体会以及自绘控件的方法吧,算是吐槽吧,说的不对和不全的地方,或者有更好的方法,请不吝赐教。

我的机器环境是:Windows7旗舰版 Service Pack 1,Visual studio 2005

1).重绘某个控件时,强烈推荐使用子类化方法,比如想自绘Button控件, 首先添加自己的类CMYButton 继承自 CButton ,声明一个CMYButton 对象,然后使用 SubclassDlgItem(UINT nID, CWnd* pParent ); // 第一个参数表示控件ID,第二个参数表示指向父窗口对象指针,一般用this表示(如果不想用SubclassDlgItem。那么可以使用CMYButton自身提供的Create方法 动态创建一个Button),这样子就可以在自己类中添加重写WindowProc()这个窗口过程函数了,非常,非常,重要 ,其他控件自绘都参考这一条.

2).我入手的第一个控件是 Button,我终于知道我的基础有多烂,很多基本的函数如GetDlgItem() , SubclassDlgItem() 都不知道,查资料,看源码 ,费了不少时间才基本完成Button的自绘,另外自绘

的按钮默认情况下是不能响应键盘按下Enter的,需要额外做一些处理。(关键词:BS_OWNERDRAW ,DrawItem),(在后期我仿造qq登陆的Button加了个效果,Hover和Leave时是渐变的,只在设置

对话框里面的Button使用了)

3).然后是 RadioButton ,CheckBox 其实和Button异曲同工的,推荐了解3个API函数CheckRadioButton(),SetCheck(),GetCheck().

4).另外对于不规则按钮实现需要掌握 SetWindowRgn(),CombineRgn(),SelectClipRgn() 3个API函数,其他不规则窗口,控件也可以参考这个方法。

5).然后是Edit控件自绘,不算是完全自绘,只重绘了非客户区(如果没特殊需要也没必要重绘客户区),和改变背景颜色,改变字体,不过后期我加了个效果,鼠标在Edit上和离开Edit时边框是渐变的(关

键词:CtlColor,WM_NCPAINT),RichEdit也可以用这个方法

6).然后是ToolTip(气泡提示控件),微软提供了NM_CUSTOMDRAW这个通告消息,以WM_NOTIFY形式发送,可以用MFC类向导添加到自己的派生类中,不过我推荐重写OnPaint函数,完全自绘(难点:

需要根据文本内容计算出控件的大小,显示位置等)
在后期我实现了,淡入,点击/超时 淡出的效果(需要映射TTN_POP 和TTN_SHOW两个通告消息),不过挪开淡出效果没能实现,求指导。

7).然后是Sliderctrl, 微软提供了NM_CUSTOMDRAW这个通告消息,以WM_NOTIFY形式发送,可以用MFC类向导添加到自己的派生类中,前期我是用的这种方法,不过后期发现这种方法局限性很大,

推荐重写OnPaint函数,完全自绘(关键点:在PreSubclassWindow 里面把 Thumb(拇指按钮),Channel(凹槽),以及整个控件大小保存起来,以便在OnPaint里面绘制)

8).然后是Staic控件,这个比较简单,重写OnPaint函数 画上文本,把DC设为透明模式就行了,有人会说直接在CtlColor直接SetBkMode(TRANSPARENT)就行了,不用在OnPaint处理,但这是有个问

题的, 如果要求文本一直变化,旧的文本没有擦除,新设置的文本又盖上了。所以根据这个控件的用途,自己选择适合的方法吧。

9).然后是Menu,这个较难,严格来说Menu 并不算控件,他是派生自CObject类的,微软提供了MeasureItem,DrawItem两个虚函数类供自绘 ,MeasureItem作用是计算出菜单的高度和宽度,系统

会自动根据文本内容最长那项来作为Menu的宽度。DrawItem作用顾名思义就是画了,但是有个致命的问题,自绘出来的Menu 有个系统默认的边框,十分邪恶和难看,(ModifyStyle和

SetWindowLong去不掉边界的)这时到自己派生的CMYMenu里面 发现微软只给咱们提供了仅仅5个虚函数,没有提供WindowProc()这个窗口过程函数,这不是坑爹嘛.......这时一般做法都是派生自

CWnd 自己实现菜单的功能.不过查了下资料任然可以自绘的:需要使用钩子 替换菜单的窗口过程,在WM_CREATE时 去掉边界Stytle 有兴趣的朋友可以Google一下。(难点:替换菜单窗口过程)

10). 然后是Combobox控件,这个较难, 微软提供了CompareItem,DeleteItem,DrawItem,MeasureItem 4个虚函数供自绘。我只用了后2个,(如果只加了 CBS_SORT 必须重写CompareItem这个

函数,除非使用了CBS_HASSTRINGS | CBS_SORT就可以不重写CompareItem()), 别以为这样子就完了,运行后,打开Combobox 显示的 List 有系统默认的边框!!!ModifyStyle和SetWindowLong

去不掉边界.老规矩查资料去,不看不知道,一看吓一跳,Combobox 是由3个控件组合成成的(难怪叫组合框),分别是Edit,Listbox,和combo本身(除去Edit ,Listbox剩下那部分),当时我就震惊了,迷茫

了! 这时需要添加OnCtlColor这个函数,在里面 使用SubclassWindow()这个API函数子类化 ListBox 和 Edit(在这之前 你还需要准备自绘好的 ListBox控件 和Edit控件)Combobox 有3种样式

CBS_SIMPLE, CBS_DROPDOWNLIST,CBS_DROPDOWN,第一种不说了不常用,第二种是不能输入只能点击选择,第三种可以输入可点击选择. 我的程序里面使用的是CBS_DROPDOWNLIST样式

11).Combobox 在 Windows7 下疑惑:关闭滑动打开组合框特效 ,自绘Combobox是可以去掉边界并进行窗口剪切的(圆角矩形) , 如果是 开启滑动打开组合框特效,系统会加上边框, 剪切的圆角又

变成直角了, 跟踪调试发现是在WM_WINDOWPOSCHANGING 消息里面搞的鬼 ,有兴趣的朋友可以对比看看,暂时为找到解决方案。。。
开启/关闭 滑动打开组合框特效 :计算机-右键属性-高级系统设置-高级-性能设置-视觉效果

12).然后是 TabCtrl ,微软提供了DrawItem,MeasureItem 2 个虚函数供自绘,需要加 TCS_OWNERDRAWFIXED这个Stytle,表明这个控件需要自绘,不过我没有用这种方式,我直接重写了OnPaint函数

完全自绘(难点:需要自己计算每个标签大小,位置,以及与之绑定的Dialog显示位置)
 
13).最后是窗体框架绘制(非客户区),这个较难,看了很多例子源码,也花了不少时间,WM_MOVE,WM_PAINT ,WM_NCPAINT,WM_NCACTIVATE,这4个消息自绘成功的关键 , 在绘制时候还需要

计算出边框/标题栏的大小和位置(Win7 和Xp 下 GetSystemMetrics()返回值是不同的)。
// 给出框架绘制不闪烁的关键代码 ,完全原创。 
if(message == WM_NCACTIVATE && !wParam) // wParam=0, deactive
{
return 1; // 必须返回1,处理默认消息(如果不返回1,一切弹出的窗口(模态,非模态)不能点击) 
}
if(message == WM_NCACTIVATE && wParam) // wParam =1, active
{
return 0; // 这个随便返回(0和1都行)
}
if(message==WM_NCPAINT)  
{
return 0; // 阻止默认框架绘制(An application returns zero if it processes this message 摘自MSDN)
}
这种方式是保留了边界和标题栏,其实就是盖住了原来的画上自己的,只要不闪烁就是成功的。当然也可以去掉系统默认的边界 和 标题栏,在客户区算出一个边界和标题栏,处理一些消息,能实现更好

的框架自绘,做出更漂亮的界面。

14)可能是我这个人比较蛋疼吧,想着既然做了个播放器界面为什么不给他实现一个播放的功能呢,微软提供了 MCI—媒体控制接口,自己封装了一个播放类,实现了一些播放基本功能。这样子第一个

版本就算完成了吧。

---测试环境: 6台Win7 和 2台Xp
---界面测试:Win7 和 Xp 运行均正常(有个缺陷见第11条)
---播放测试: 我的电脑上可以 播放rmvb,RM ,AVI,MP4,WMV,FLV ,部分测试Win7电脑6个格式全部能播放,但部分测试的Win7电脑只能播放 AVI 和MP4,WMV格式(为什么?求解答...).
---另外WMV格式增加播放速度和减少播放速度,貌似是不行的。
---在XP系统 下能打开视频文件但只能听见声音看不见图像,求解答?
这结果确实比较蛋疼,大家可以测试下看看界面是否正常,播放功能是否正常

15)鉴于MCI版本播放测试不是很令人满意,我又再一次蛋疼了,因为一个前辈说让我用Activex 控件试试。好吧,花了2天时间,研究了下Activex 控件, 用OleView研究了Aplayer这个控件,
APlayer_001.dll 这个DLL文件就是Aplayer Activex控件(Activex 控件使用前必须先注册,如果只是在代码里面注册了APlayer_001.dll,程序可以运行但是播放不了文件,因为在播放文件的时候

Aplayer控件 还会根据播放文件类型 再加载 一些DLL文件和AX文件,那些文件加起来有80多M,坑爹啊这是....)其实Aplaer 是迅雷看看播放器的一个组件, 如果安装了迅雷的话,在 C:\

\Program Files\\Common Files\\Thunder Network 可以找到 Aplaer 这个文件夹,如果没有安装迅雷或者没有Aplayer这个组件程序是不能运行的。
备注:这个APlayer本身有个缺陷,在播放 Rmvb和mkv文件时,点击定位不准确。对于大的文件,很难发现这个缺陷,可以找个 一两分钟的短视频文件用迅雷看看打开 点击定位试试,缺陷非常明显。
由于Aplayer 流程 和MCI不太一样,所以花了点时间做了第二个版本。

---测试环境:6台Win7 和 2台Xp
---界面测试:Win7 和 Xp 运行均正常(有个缺陷见第11条)
---播放测试:Win7上可以播放RMVB,RM, AVI,MP4,WMV,FLV ,MKV, MP3, WMA, WAV
---在XP系统下 打开文件任然只能听见声音看不见图像,对于XP系统这个播放问题,还未找到解决方案,求指导(难道是因为我注册的是Win7的APlayer?)。
---另外程序有个缺陷 :在第一次 点击Aplayer控件的时候会缩小,调试发现根本没有进入 WM_LBUTTONDOWN,直接 WM_WINDOWPOSCHANGING,WM_WINDOWPOSCHANGED,WM_SIZE
,不知道这个消息从哪里发过来的....(我用了个不是很好的方法解决了,既然是在第一次点击的时候才会缩小,我在PreSubclassWindow里面 :PostMessage(WM_LBUTTONDOWN,MK_LBUTTON,

(LPARAM)&UserDown);PostMessage(WM_LBUTTONUP,MK_LBUTTON,(LPARAM)&UserDown);)这2个消息,貌似没再出现了缩小情况了,但昨天我运行的时候又出现这个问题了,出现的概率很低....

无语啊)

16) 
程序的测试全部由自己完成,很多功能没来得及测试,所以程序可能会出现这样那样的问题,一个人力不从心啊,希望拍砖温柔点啊。
程序热键,做的不好,不是全局和后台的,必须窗口获得焦点才能响应.
在后期增加了托盘功能。
增加了播放列表功能,最多支持10个文件,大于10个覆盖第10个,双击列表中的文件名,就可以播放这个文件。不过播放列表我没有单独做个窗口是放在设置对话框第3个标签的。
应同学的强烈要求增加了拖拽打开文件功能(我过滤了一些文件扩展名,不是每个文件类型拖拽都有效,mci版本和Activex版本支持的格式不同 ,过滤情况也不一样)
程序最初叫IKAN Player 但是发现 PPLive 已经用了这个名字, 改成了ICAN Player....

附加说明:我现在大3在读,现在正在实习找工作阶段,上次面试的时候把程序给面试官演示的时候,他说了句“这种程序网上随便一搜一大把”.....他这个想法我很能理解,如果我是面试官,我也会持怀疑态度的. 所以现在不方便给出源码,希望大家理解我,以后一定会给出项目源码的.

帖子不知道怎么上传附件,程序放在CSDN 资源区内,不需要资源分的,大家下下来看下吧。
给出链接: http://download.csdn.net/source/3428958

论坛上也有我的帖子:http://topic.csdn.net/u/20110710/19/5209f358-31c8-4057-b108-02155a417fd0.html?61362

大家运行下,看看有没有什么问题和异常啊,欢迎回帖,既然论坛不让我开300分的帖子,打算后面在开2个100分帖子,只要回复了这个帖子的朋友都可以去领分

MFC基础,MFC自绘控件学习总结.---转的更多相关文章

  1. MFC自绘控件学习总结

    前言:从这学期开始就一直在学习自绘控件(mfc),目标是做出一款播放器界面,主要是为了打好基础,因为我基础实在是很烂....说说我自己心得体会以及自绘控件的方法吧,算是吐槽吧,说的不对和不全的地方,或 ...

  2. MFC自绘控件学习总结第二贴---转

    首先感谢大家对第一帖的支持,应一些网友烈要求下面我在关于上一贴的一些补充和说明(老鸟可以无视)这一贴是实战+理论不知道第一帖的先看第一帖:http://topic.csdn.net/u/2011071 ...

  3. MFC自绘控件学习总结第二贴

    首先感谢大家对第一帖的支持,应一些网友烈要求下面我在关于上一贴的一些补充和说明(老鸟可以无视)这一贴是实战+理论不知道第一帖的先看第一帖:http://topic.csdn.net/u/2011071 ...

  4. MFC之自绘控件

    在描绘MFC界面时,MFC自带的控件样式是绝对不满足界面的需求的. 所以我们就要在MFC自带控件基础上对控件样式进行重绘. 在采用自绘前界面样式 采用自绘后界面样式 是不是自绘控件后看起来正常了很多? ...

  5. 笨重的mfc还在基于系统控件,熟练的mfc工程师还比不过学习Qt一个月的学生开发效率高(比较精彩,韦易笑)

    作者:韦易笑链接:https://www.zhihu.com/question/29636221/answer/45102191来源:知乎著作权归作者所有,转载请联系作者获得授权. 更新:擦,本来只有 ...

  6. MFC 对话框Picture Control(图片控件)中静态和动态显示Bmp图片

    版权声明:本文为博主原创文章,转载请注明CSDN博客源地址! 共同学习,一起进步~ https://blog.csdn.net/Eastmount/article/details/26404733   ...

  7. VC/MFC 当鼠标移到控件上时显示提示信息

    VC/MFC 当鼠标移到控件上时显示提示信息 ToolTip是Win32中一个通用控件,MFC中为其生成了一个类CToolTipCtrl,总的说来其使用方法是较简单的,下面讲一下它的一般用法和高级用法 ...

  8. [转]MFC子线程中更新控件内容的两种办法

    一.概述 每个系统中都有线程(至少都有一个主线程),而线程最重要的作用就是并行处理,提高软件的并发率.针对界面来说,还能提高界面的响应能力.一般的,为了应用的稳定性,在数据处理等耗时操作会单独在一个线 ...

  9. 【VS开发】使用MFC创建并调用ActiveX控件

    使用MFC创建并调用ActiveX控件 今天做了一下ActiveX的使用测试,总结一下: 首先使用MFC创建一个activeX的控件譬如ActiveXTest,编译成ocx并注册,然后另外编写一个测试 ...

随机推荐

  1. 不是技术牛人,如何拿到国内IT巨头的Offer(1)

    转自:http://developer.51cto.com/art/201404/436685.htm 不久前,byvoid面阿里星计划的面试结果截图泄漏,引起无数IT屌丝的羡慕敬仰.看看这些牛人,N ...

  2. 关于iOS8上本地通知接收不到的问题

    在iOS8系统开发使用本地通知时,会出现如下的相关提示语: 1 Attempting to schedule a local notification2 with an alert but haven ...

  3. SMACSS:一个关于CSS的最佳实践-1.Overview

    什么是SMACSS? SMACSS(发音"smacks"),全称Scalable and Modular Architecture for CSS.顾名思义,SMACSS是一个可扩 ...

  4. 关于SQL Server数据表的五中约束

    1.主键约束(PRIMARY KEY) 主键约束可以在表中定义一个主键值,它可以唯一确定表中每一条记录,每个表中只能有一个主键约束(只能有一个主键约束的意思并不是说受主键约束的列只能有一个),并且受主 ...

  5. 【MFC相关】MFC入门相关

    1.MFC的“匈牙利标识符命名法”,这是一个约定,可以增加代码的可读性: 声明或定义了一个类,那么这个类可以以“C”(class)为前缀,如CHelloWorldDlg类: 定义一个无符号型的局部变量 ...

  6. 腾讯云部署Flask应用

    由于新浪云现在不免费了.而且云豆也用完了.所以去腾讯云申请了个学生云主机,一元一个月. 不过部署开发环境还是有点麻烦的,搞了好几天,终于部署成功了! 下面说部署过程: 我云主机用的是 Ubuntu 1 ...

  7. Hibernate学习之映射关系

    一.Hibernate多对一关联映射:就是在“多”的一端加外键,指向“一”的一端. 比如多个学生对应一个班级,多个用户对应一个级别等等,都是多对一关系. 1.“多”端实体加入引用“一”端实体的变量及g ...

  8. PrintWriter与outputStream区别

    网上截取: printWriter:我们一般用来传的是对像 而outputStream用来传的是二进制,故上传文件时,一定要使用此. PrintWriter以字符为单位,支持汉字,OutputStre ...

  9. Cyclomatic complexity

    Cyclomatic Code Complexity was first introduced by Thomas McCabe in 1976. In 1976, Thomas McCabe pub ...

  10. (Problem 62)Cubic permutations(待续)

    The cube, 41063625 (3453), can be permuted to produce two other cubes: 56623104 (3843) and 66430125 ...