windows程序设计POPPAD3的关键难点详解(一)
来源:互联网 发布:哪个软件看书好 编辑:程序博客网 时间:2024/05/02 02:31
windows程序设计中POPPAD3也是一个非常麻烦的程序,其中让人不好理解的地方很多。所以也做一下详解,不过只是就一些难点做详解,那些基本的东西不做解释,另外如果篇幅过长,可能会为篇或做续。另外本文看着长,但是语言很简练,读起来应该非常容易,所以不要看着长就害怕不读了,长的文章不一定难读,短的文章也不一定好读,还要看语言简练不简练,废话多不多。好了,讲正事:
case WM_INITMENUPOPUP:
switch (lParam)
{case 1:
EnableMenuItem ((HMENU) wParam, IDM_EDIT_UNDO,SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?MF_ENABLED : MF_GRAYED) ;
首先看WM_INITMENUPOPUP,在原文的菜单那一章里对它有这样一段:
当Windows准备显示一个弹出式菜单时,它给窗口消息处理程序发送一个WM_INITMENUPOPUP消息,参数如下:
wParam: 弹出式菜单句柄
LOWORD (lParam):弹出式菜单索引
HIWORD (lParam): 系统菜单为1,其它为0
何为弹出式菜单呢:也在原文的菜单那一章里:
窗口的菜单列紧接在标题列的下方显示,这个菜单列有时被称为「主菜单」或「顶层菜单」。列在顶层菜单的项目通常是下拉式菜单,也叫做「弹出式菜单」或「子菜单」。您也可以定义多重嵌套的弹出式菜单,也就是说,在弹出式菜单上的项目可以存取另一个弹出式菜单。有时弹出式菜单上的项目呼叫对话框以获得更多的信息(对话框在下一章介绍)。在标题列的最左端,很多父窗口都显示程序的小图标,这个图标可以启动系统菜单。它实际上是另一个弹出式菜单。
您还可以在没有顶层菜单列的情况下使用菜单,也就是说,您可以使弹出式菜单出现在屏幕顶层的任何位置。一种方法是使用鼠标右键来启动弹出式菜单
以上是原文中找出的两段,也就是说,弹出式菜单既包含这样的:
也包括这样的:
还包括这样的:
再继续看菜单那一章,有这么一段话:
窗口消息处理程序的工作包括启用和无效化「Edit」菜单中的选项,这项工作在处理WM_INITMENUPOPUP时完成。首先,程序检查是否要显示「Edit」弹出式菜单。因为菜单里「Edit」的位置索引(「File」从0开始)是1,因此如果即将显示「Edit」弹出式菜单,那么lParam应该等于1。
注意,最后那句:因为菜单里「Edit」的位置索引(「File」从0开始)是1,因此如果即将显示「Edit」弹出式菜单,那么lParam应该等于1,也就是说下面的弹出式菜单的位置索引从左到右依次是:0,1,2,3,4
好了,这下就可以明白了这段代码了,首先当你点一个弹出式菜单时,就是上图中的从File到Help的那五个选项,会产生case WM_INITMENUPOPUP:,然后通过switch (lParam)来确定是选了上图中的那一个弹出式菜单,上面的那五个弹出式菜单的位置索引依次为0、1、2、4、5,也就是说他们的lParam依次为0、1、2、4、5,当case 1:时,就是说点了它们中的Edit那个弹出式菜单。
再来看EnableMenuItem ((HMENU) wParam, IDM_EDIT_UNDO,SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?MF_ENABLED : MF_GRAYED) ;这一句,显然SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?MF_ENABLED : MF_GRAYED是一个参数,SendMessage向编辑窗口发送一个EM_CANUNDO,然后编辑窗口的窗口处理程序将检测编辑窗口撤消缓冲区是否为空,通常控件把最后一次在控件的编辑操作保存在一个撤消缓冲区,如果缓冲区非空则返回TRUE表示上次操作可以撤消,否则返回FALSE,也就是说编辑窗口有一个撤消缓冲区,只要你在编辑区里运行操作,就会把你的操作保存在那个撤消缓冲区,再有操作,新的操作会覆盖上一次操作,但只要你有操作,这个撤消缓冲区就不会为空,这时SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) 返回TRUE,但是没有操作,这个撤消缓冲区就为空,此时SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) 返回FALSE,当SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) 返回TRUE,则SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?MF_ENABLED : MF_GRAYED为MF_ENABLED,相反则为 MF_GRAYED。
这时的EnableMenuItem,看看它的定义:
BOOL EnableMenuItem(
HMENU hMenu, // handle to menu
UINT uIDEnableItem, // menu item to enable, disable, or gray
UINT wEnable // menu item flags
);
其中第一个参数为菜单句柄。第二个参数为欲允许或禁止的一个菜单条目的标识符。如果在wEnable参数中设置了MF_BYCOMMAND标志,这个参数就代表欲改变菜单条目的命令ID。如设置的是MF_BYPOSITION,则这个参数代表菜单条目在菜单中的位置(第一个条目肯定是零),第三个参数wEnable ,参考ModifyMenu函数中的菜单常数标志定义表,其中列出了允许使用的所有常数。对于这个函数,只能指定下述常数:MF_BYCOMMAND,MF_BYPOSITION,MF_ENABLED,MF_DISABLED以及MF_GRAYED。
所以EnableMenuItem ((HMENU) wParam, IDM_EDIT_UNDO,SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?MF_ENABLED : MF_GRAYED) ;就是给一个ID为IDM_EDIT_UNDO的菜单项发送一个MF_ENABLED 或是MF_GRAYED,至于是哪个要看SendMessage的返回值。当发送MF_ENABLED时,菜单有效,相发送MF_GRAYED时,菜单项无效。
但这里你可能要问(HMENU) wParam,为什么这个wParam前面要加个(HMENU) ,这个问题嘛,我觉的可能是为了把wParam转换为类型吧,毕竟EnableMenuItem第一个参数要的是菜单句柄,但wParam前面说了也是弹出式菜单句柄,这个嘛,我做了实验把那个(HMENU) 去掉,也能运行,但是两个警告,说是类型不对,所以我觉的可能是WM_INITMENUPOPUP带的wParam参数,虽然也是菜单的句柄,但它应该不是HMENU型,而EnableMenuItem的第一个参数不仅要求是菜单的句柄还要求为HMENU型,所以要转换为HMENU型。
还有下面的EnableMenuItem ((HMENU) wParam, IDM_EDIT_PASTE,IsClipboardFormatAvailable (CF_TEXT) ?MF_ENABLED : MF_GRAYED) ;情况差不多,就不细讲了,本文只是就一些难点讲讲,不是每一个地方都讲,这里只说说IsClipboardFormatAvailable(CF_TEXT)判断剪贴板上的数据,如果当前剪切板包含的是以NULL结尾的ASCII字符的文本格式,则该函数返回值为true,否则为false。剩下的你自己也就应该知道了。
好了,看来要分章节了,后面还要很多要说的,拜拜
- windows程序设计POPPAD3的关键难点详解(一)
- windows程序设计POPPAD3的关键难点详解(二)
- windows程序设计POPPAD3的关键难点详解(三)
- windows程序设计POPPAD3的关键难点详解(四)
- windows程序设计 「PopPad3」范例分析笔记
- 消息处理机制-WINDOWS程序设计的难点(摘自Windows程序设计开发指南)
- windows程序设计中的HEXCALC.c 程序的一些难点指导
- windows程序设计 「PopPad3」之 POPPRNT.C 打印范例分析 笔记
- Windows程序设计(一)
- windows程序设计(一)
- Windows程序设计--设置滚动条详解一
- 难点--关键路径实例(必须掌握)
- 多线程程序设计的关键
- JavaScript难点(一)
- Windows程序设计笔记(一)
- 《windows程序设计》(一)-------MessageBox
- windows程序设计复习(一)
- Windows程序设计学习(一)
- 【C】【笔记】《C语言深度剖析》第三章 预处理
- noip2015广东 普及组coin
- smarty学习笔记(02)——
- lightOJ 1297 - Largest Box 【数学题】
- <mvc:annotation-driven/>、<context:component-scan base-package=""/>、<context:annotation-config/>的用法
- windows程序设计POPPAD3的关键难点详解(一)
- R语言安装NLP自然语言分析包
- HDU 4939 Stupid Tower Defense(贪心+动态规划)
- scanf 与 gets HDU1062
- 【C】【笔记】《C语言深度剖析》第四章 指针和数组
- 【C】【笔记】《C语言深度剖析》第五章 内存管理
- finish/onDestroy/System.exit()的区别
- 下拉列表Spinner 、自动补齐AutoCompleteTextView、
- mean shift 图像分割