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。剩下的你自己也就应该知道了。

好了,看来要分章节了,后面还要很多要说的,拜拜

0 0
原创粉丝点击