| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6359 人关注过本帖
标题:All about windows programming
只看楼主 加入收藏
kai
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:52
帖 子:3450
专家分:59
注 册:2004-4-25
收藏
得分:0 

菜单的创建过程 - 分为定义和加载两个步骤。

1)定义菜单

菜单的定义格式由四部分组成:

a) 菜单名 - 用来标识特定的菜单,应用程序通过菜单名加载指定菜单;

b) MENU 关键字 - 用来标识资源的性质;

c) 载入特性选项 - 用以标识菜单所具有的载入特性,常用的载入特性选项及其说明如下表所示:

选项 说明

DISCARDABLE 当不再需要菜单时可丢弃

FIXED 将菜单保存在内存中的固定位置

LOADONCALL 需要时加载菜单

MOVEABLE 菜单在内存中可移动

PRELOAD 立即加载菜单

d) 菜单项列表 - 应用程序在资源描述文件中使用关键字 POPUP和MENUITEM定义菜单项。

菜单在资源描述文件中的定义形式为:

菜单名 MENU [, 载入特性选项]

{

菜单项列表

}

(1) POPUP语句 - 定义弹出式菜单,其形式为:

POPUP "菜单项名"[,选项];

程序员还可以在菜单项名中加入符号 "&", 以定义该菜单项的热键。 例如定义弹出式菜单项"编辑"的形式为:

POPUP "编辑(&E)"; 该菜单项使用 Alt+ E键作为热键。

菜单项常用选项及其说明:

选项 说明

MENUBARBREAK 菜单项纵向分隔标志

CHECKED 显示选中标志

INACTIVE 禁止一个菜单项

GRAYED 禁止一个菜单项,并使其变灰

POPUP 定义的弹出式菜单项还包含子菜单。

(2) MENUITEM 语句 - 用于定义菜单项,其形式为:MENUITEM "菜单项名"菜单项标识(ID)[,选项]

其中 ID 为菜单项标识,应用程序通过菜单项的标识值唯一地确认每一个菜单项的消息,菜单项标识可为 0 到 65535 之间的任意一个整数,他通常在应用程序头文件中定义。在WM_COMMAND 消息中系统发送给应用程序的菜单标识值,WM_COMMAND消息中字参数 wParam 包含了选中菜单项的标识。此外,如果需要创建菜单中的水平分隔符,可以利用下面的语句:MENUITEM SEPARATOR

例如,应用程序需要在其名为 "MyMenu" 的窗口菜单中创建一个 "编辑"弹出式菜单。该菜单含有名称为"剪切", "复制", "粘贴", "全选", "清除"及 "退出" 等菜单项。 要求应用程序运行时系统可根据需要调整该菜单在内存中的位置,以提高内存的利用率; 菜单项均使用热键; 并且 "退出" 项与其他菜单项之间用分隔线分开。该菜单在资源描述文件中的定义如下:

#include <windows.h>

#include "Menu.h"

// 菜单定义

MyMenu MENU MOVEABLE // MyMenu 为窗口菜单的名称

{

POPUP "编辑(&E)" // 定义"编辑" 弹出式菜单

{

MENUITEM "剪切( &X)", IDM_CUT

MENUITEM "剪切( &X)", IDM_CUT

MENUITEM "复制( &C)", IDM_COPY

MENUITEM "粘贴( &V)", IDM_PASTE

MENUITEM "全选( &L)", IDM_SELECTALL

MENUITEM "清除( &X)", IDM_CLEAR

MENUITEM SEPARATOR // 分隔线

MENUITEM "退出( &X)", IDM_EXIT

}

}

Menu.h 文件中定义了菜单项标识所对应的数值:

。。。

#define IDM_CUT 20

#define IDM_COPY 21

#define IDM_PASTE 22

#define IDM_SELECTALL 23

#define IDM_CLEAR 24

#define IDM_EXIT 25

// to be continued


自由,民主,平等,博爱,进步.
中华民国,我的祖国,中华民国万岁!中华民国加油!
本人自愿加入中国国民党,为人的自由性,独立性和平等性而奋斗!
2004-09-29 23:33
kai
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:52
帖 子:3450
专家分:59
注 册:2004-4-25
收藏
得分:0 

2) 加载菜单资源

在 windows 应用程序中加载菜单的方法有如下3种:

(1)在窗口类中加载菜单 - 通过下列语句实现:

.......

WNDCLASS wndclass;

......

wndclass.lpszMenuName = lpszMenuName;

......

应用程序在窗口类中加载菜单后,该类窗口将使用此菜单作为默认菜单。

(2)在创建窗口时加载菜单

应用程序也可在调用函数 CreateWindow 创建窗口时加载窗口菜单。这时,应用程序需首先调用函数 LoadMenu 加载菜单。该函数的原型为: HMENU LoadMenu( hInstance, lpszMenuName)

其中 hInstance 为当前程序的实例handle, lpsyMenuName 为窗口菜单名

例如,应用程序希望在创建的窗口中加载名称为 MyMenu 的窗口菜单,其形式为:

HWND hwnd, hmenu;

...

hmenu = LoadMenu(hInstance, "MyMenu");

hwnd = CreateWindow(...,...,...,...,...,...,...,...,hmenu,...,...);

如果创建的窗口希望使用所属窗口类的默认菜单,则应设置函数 CreateWindow 的菜单handle 参数为NULL。

(3) 动态加载菜单

应用程序调用函数 LoadMenu 获取菜单handle 后,还可通过调用函数 SetMenu 动态地加载菜单,以提高应用程序的灵活性。该函数的原型为: BOOL SetMenu (HWND hwnd, HMENU hmenu) // hwnd 为窗口handle, hmenu 为菜单handle

动态加载菜单可在同一个应用程序中实现多种不同的菜单操作界面。 例如应用程序定义了两种菜单 Menu1 和 Menu2 及相应的两套菜单项,通过调用函数 SetMenu 在两个菜单之间切换,该应用程序可实现两种界面的操作及相应的菜单项功能,程序段如下:

HMENU hmenu1, hmenu2<

...

hmenu1 = LoadMenu(hInstance, "Menu1"); // 使用Menu1 为窗口初始菜单

hwnd = CreateWindow(...,...,...,...,...,...,...,..., hmenu1, ...,...);

...

hmenu2 = LoadMenu(hInstance, "Menu2"); // 将窗口菜单切换为 Menu2

SetMenu(hwnd, hmenu2);

...

// to be continued, 下次来讲对菜单项的操作。


自由,民主,平等,博爱,进步.
中华民国,我的祖国,中华民国万岁!中华民国加油!
本人自愿加入中国国民党,为人的自由性,独立性和平等性而奋斗!
2004-09-30 00:01
kai
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:52
帖 子:3450
专家分:59
注 册:2004-4-25
收藏
得分:0 

给大家上传一个小的应用程序,我暂时将我未来的公司命名为 kaisoft ,

当然,应用程序的 icon 用了 KAI 这个图标。

这是一个简单的看图应用程序。以后逐渐改进。

[attach]888[/attach]

自由,民主,平等,博爱,进步.
中华民国,我的祖国,中华民国万岁!中华民国加油!
本人自愿加入中国国民党,为人的自由性,独立性和平等性而奋斗!
2004-09-30 00:30
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 

完全支持kai的进度和方法,如果以上全部是原创,请受live41一拜!钦佩!

第22楼的代码运行不了,请修正! 是转移了位置后才出现的问题,我之前有备份网页,没转移版块之前可运行。

你上传的程序中菜单的exit按钮有问题,在XP下会提示运行错误。

[此贴子已经被作者于2004-10-03 13:11:30编辑过]

2004-10-03 11:58
kai
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:52
帖 子:3450
专家分:59
注 册:2004-4-25
收藏
得分:0 

22 楼,我编辑了几次都不行,干脆改为上传文件了。

前面的讲解以及讲解程序并非我的原创,摘录于各种书籍。如 Petzold 的 windows programming

windows programming 我是从两年前开始学的,上来的时候确实是举步艰难,很多专用名词不解,那么就看 MSDN ,并且自己写在本子上,慢慢积累,时间久了,就觉得那些词是理所当然的了。其实如果我将所有的细节写清楚,那就得一本书了。并且未必所有人会去看。当一样东西完完整整的放在你面前时,你的兴趣反而会高不起来的。所以我希望采取讨论的方式。我给个大概,一定附有例程,大家对不清楚的概念提出来,再来讨论。

至于那个上传的看图小程序,完全是我个人原创。

那个 exit 确实代码没写对,我忽略了。通常我是不点击 exit ,而是直接点击右上角的那个大叉,所以一直没有发现那个问题。谢谢 live41 的指出。


自由,民主,平等,博爱,进步.
中华民国,我的祖国,中华民国万岁!中华民国加油!
本人自愿加入中国国民党,为人的自由性,独立性和平等性而奋斗!
2004-10-03 16:37
kai
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:52
帖 子:3450
专家分:59
注 册:2004-4-25
收藏
得分:0 

接着32楼,继续来讲对菜单项的操作

创建菜单后,程序可调用相关函数对菜单项进行操作,如禁止或激活菜单项,设置或取消选中标志,增加菜单项,删除菜单项,修改菜单项。

我们先来讲禁止或激活菜单项:(两种方式)

方法1。通过在资源描述文件中设定菜单项的选项以指定该菜单项的初始状态为禁止或激活

或方法2。调用函数 DWORD EnableMenuItem(HMENU hmenu, UINT wIDEnableItem, UINT dwEnable) 来改变其初始状态。

hmenu 为菜单handle ( 请注意,我对handle 不做翻译,中文书上会将这个词翻译为句柄,什么乱七八糟的,句子还有把柄吗?这个最初的对这个单词的蹩脚的翻译,使得理解上更为困难。我对当初将这个单词翻译为句柄的人表示严重抗议!!! 请大家将 handle 理解为操作识别符 )

wIDEnableItem 为 被禁止或激活的菜单项标识, dwEnable 为 菜单项操作标识的取值, 可能为该菜单项的 ID 数值, 也可能为该菜单项在菜单中的位置,

dwEnable 参数的常用标识及其说明:

MF_BYCOMMAND 表明以ID 来标识菜单项 MF_BYPOSITION 表明以位置来标识菜单项 MF_DISABLED 表明禁止菜单项 MF_ENABLED 表明激活菜单项 MF_GRAYED 表明禁止菜单项,并使其变灰

举例来讲, 禁止弹出式菜单 "编辑"中的"复制"项的形式如下:

EnableMenuItem(hmenu, IDM_COPY, MF_BYCOMMAND | MF_DISABLED );

// 其余4种操作,下次继续


自由,民主,平等,博爱,进步.
中华民国,我的祖国,中华民国万岁!中华民国加油!
本人自愿加入中国国民党,为人的自由性,独立性和平等性而奋斗!
2004-10-03 17:17
kai
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:52
帖 子:3450
专家分:59
注 册:2004-4-25
收藏
得分:0 

第二种操作:设置或取消选中标志

通常在菜单旁 以打钩标志,表示该菜单项被选中。我们可以在资源描述文件中设置菜单项为 CHECKED 来选中某菜单项,也可以通过调用函数 DWORD CheckMenuItem( HMENU hmenu, UINT wIDCheckItem, UINT dwCheck) wIDCheckItem 为设置或取消选中标志的菜单项标识, dwCheck 为操作标识,

dwCheck 参数的常用标识及其说明:

MF_BYCOMMAND 表明以ID值标识菜单项

MF_BYCOMMAND 表明以位置标识菜单项

MF_CHECKED 添加选中标志

MF_UNCHECKED 删除选中标志

第三种操作:增加菜单项(两种动态增加菜单项的方法)

1) 调用函数 BOOL AppendMenu( HMENU hmenu, UINT dwFlags, UINT dwIDNewItem, LPCTSTR lpNewItem)

例如在弹出式菜单"帮助"的末尾增加一项"版本说明"的形式如下:

AppendMenu(hmenu, MF_ENABLED, IDM_VERSION, "帮助(&H)");

2) 调用函数 BOOL InsertMenu(HMENU hmenu, UINT wPosition, UINT dwFlags, UINT dwIDNewItem, LPCTSTR lpNewItem) 在菜单中插入菜单项

wPosition 由参数 dwFlags 来解释其意义, 如果dwFlags 为 MF_BYCOMMAND, 则该参数为插入位置的下一个菜单项的 ID值, 如果 dwFlags 为 MF_BYPOSITION, 则该参数为插入的位置号,菜单的第一个菜单项的位置为 0。dwIDNewItem 一般为插入项的 ID值。 如果加入的是一个弹出式菜单, 则该参数为弹出式菜单的 handle. lpNewItem 取决于 dwFlags 参数,一般情况下为新插入菜单项的标识, 如果 dwFlags 为 FM_BITMAP, 则该参数包含一个位图handle.

在弹出式菜单"编辑"的"复制"项之前加入新的菜单项"粘贴"的语句如下:

InsertMenu(hmenu, IDM_COPY, MF_BYCOMMAND | MF_ENABLED, IDM_PASTE, "粘贴(&V)");

// to be continued


自由,民主,平等,博爱,进步.
中华民国,我的祖国,中华民国万岁!中华民国加油!
本人自愿加入中国国民党,为人的自由性,独立性和平等性而奋斗!
2004-10-05 00:26
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 

HWND hwnd; MSG Msg; WNDCLASS wndclass;

解释一下上面三句好吗?大写的是类吗?包含在windows.h里面的类吗?

UpdateWindow(hwnd);

这个函数在我API查询中找不到,虽然大概猜到它的作用。

[此贴子已经被作者于2004-10-05 16:42:37编辑过]

2004-10-05 16:40
kai
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:52
帖 子:3450
专家分:59
注 册:2004-4-25
收藏
得分:0 

解释你的第一个问题,HWND hwnd; 其实在解释 这个问题之前, 先要解释什么是 handle. 往往当你看到一个变量名前有 h 这个字母,那么意味着,它是一个handle. 那么究竟什么是 handle 呢? handle 是一个4字节长的整数值,用于标识应用程序中不同的对象和同类对象中不同的实例,比如一个窗口,按钮,图标,滚动条,输出设备,等。通过 handle 标示了某一唯一的对象,那么应用程序通过 handle 来访问相应的对象信息。

你这里提出的 HWND 即为窗口 handle,

HWND hwnd; 则表明这是一个窗口 handle, 它具体以 hwnd 这个变量来接受数值。

回答你的第二个问题, MSG Msg; 是什么? MSG 是一个结构体,具体定义如下:

typedef struct tagMSG

{

HWND hwnd;

UINT message;

WPARAM wParam;

LPARAM lParam;

DWORD time;

POINT pt;

}MSG;

hwnd 为获取消息的窗口handle, 如果此参数为 null, 则可检索所有驻留在消息队列中的消息。

message 是代表一个消息的消息编号,每个Windows消息都有一个消息编号

wParam 和 lParam 是包含有关消息的附加信息

time 指定消息发送至消息队列的时间。

pt 指定消息发送时,屏幕光标的位置。pt 的数据类型 POINT也是一个结构体, POINT的定义如下:

typedef struct tagPOINT

{

LONG x; //屏幕的横坐标

LONG y; //屏幕的纵坐标

}POINT;

参看下面连接

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_msg_structure.asp

回答你第三个问题 WNDCLASS wndclass;

WNDCLASS 是一个结构体,其包含一个窗口类的全部信息, // 不要误会,这里所说的类,并非 C++ 中的类,而是指具体的一类物体,如窗口。 窗口类或者称为窗口结构的定义如下:

typedef struct {    UINT style;            // 窗口类的样式,一般设置为0    WNDPROC lpfnWndProc;   // 指向窗口函数的指针    int cbClsExtra;        // 分配在窗口类结构后的字节数    int cbWndExtra;        // 分配在窗口实例后的字节数    HINSTANCE hInstance;   // 定义窗口类的应用程序的实例 handle    HICON hIcon;           // 窗口类的图标    HCURSOR hCursor;       // 窗口类的光标    HBRUSH hbrBackground;  // 窗口类的背景刷    LPCTSTR lpszMenuName;  // 窗口类的菜单资源名    LPCTSTR lpszClassName; // 窗口类名} WNDCLASS, *PWNDCLASS;
回答你的第四个问题 UpdateWindow(hwnd);
应用程序通过调用 该函数更新并绘制用户区,并发出 WM_PAINT 消息,如果更新区域为空,就不发送任何消息。
请参看下面连接:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_4zef.asp

自由,民主,平等,博爱,进步.
中华民国,我的祖国,中华民国万岁!中华民国加油!
本人自愿加入中国国民党,为人的自由性,独立性和平等性而奋斗!
2004-10-06 01:56
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 
很清楚啊!!!建议你做这里的版主算了,实在是老师的材料,我们学校的老师看了你的帖子应该去金贸大厦跳,在学校里骗钱的教授多的是。不好意思说远了,概叹中国教育啊,毕竟自己也是师范的。以后有问题再上来问。
2004-10-06 02:03
快速回复:All about windows programming
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017386 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved