学院首页 软件应用 编程开发 创意设计 认证培训 软件论坛
ASP ASP.NET PHP JSP SQL MYSQL Java VB

您的位置:学院 >> 编程开发 >> Delphi >> 定制任务栏上的系统菜单


定制任务栏上的系统菜单


p align="JUSTIFY">  通常,当我们在特定的场合或是在多应用的环境运行自己或其他的应用程序时, 会在多窗口之间进行频繁的切换,以实施实时的交互得到所期望的结果,对于这样的“笨”办法,我们会不厌其烦地进行好多次,甚至是无数次。好在Win 9x 在任务栏上显示了我们所运行或期望的程序,并配备了相应的右键系统弹出菜单,使我们在使用时方便多了。问题是那些都是缺省的系统菜单(命令),对于我们来说没太大的帮助,下面我所介绍的就是利用Win9x 为我们设定的任务栏系统菜单来达到快速、简捷的获取信息(执行命令)的目的。提到系统菜单,就让我们联想到底层的 WIN32系统调用:AppendMenu、Inert- Menu、ModifyMenu。仅此三个函数,就足可以让我们对缺省的系统菜单进行定制,应用自如了。为简单起见,本文就 AppendMenu 进行一些介绍,其余的请朋友们参WIN32API 帮助文件。以下是: AppendMenu 函数原型:

BOOL AppendMenu(
HMENU hMenu, // 要定制的菜单句柄
UINT uFlags, // 怎样定制菜单项
UINT uIDNewItem, // 要定制的菜单项标识或子菜单句柄
LPCTSTR lpNewItem // 要定制的菜单项(字串)
);
在 AppendMenu 函数里,lpNewItem 和 uIDNewItem 参数依赖 uFlags 的不同
标志而有所变化,让我们来看一看 uFlags 到底有那一些定义值:

MF_BITMAP 指明该菜单项是一位图,在 lpNewItem 参数代表位图句柄
MF_CHECKED 在菜单项的前面放上一个“选中”标记
MF_DISABLED 屏蔽该菜单项,但不象平常那样变成灰色
MF_ENABLED 与 MF_DISABLED 相反
MF_GRAYED 除了有 MF_DISABLED 的作用以外,还把该菜单项变灰
MF_MENUBREAK 把该菜单与现有菜单并排放在一起
MF_MENUBARBREAK 与 MF_MENUBREAK 相同,除了在中间放一条竖线外
MF_OWNERDRAW 表明该菜单项为自绘菜单项,还必须处理一切的显示、更新问题
MF_POPUP 该菜单项为一子菜单,uIDNewItem 参数代表其句柄
MF_SEPARATOR 与上一菜单项画上一分割线,系统将忽略 lpNewItem 和
uIDNewItem 参数
MF_STRING 该菜单项是一文本字串,lpNewItem 是其内容
MF_UNCHECKED 取消该菜单项前面的“选中”标记

  我们看到,除了MF_POPUP,MF_BITMAP,MF_OWNERDRAW以外,MF_STRING是最常用的菜单? 义方法,uIDNewItem在这里是命令消息的wParam参数。朋友们还记得获取普通菜单的句柄用GetMenu,那么获取系统菜单的句柄就应该用GetSyst-emMenu。这时有一个问题:程序怎么知道该获取的系统菜单是窗口上的系统菜单,还是任务栏上的系统菜单呢?这就依靠传递给GetSystemMenu的是哪一个参数。因为我们当前考虑的是任栏,因此这个参数就必须是Application.Handle。如果这时候就着手编制一个Project检验一下,朋友们就会发现...“我”定义的菜单怎么没有反应!原来该菜单项根本没有在Application里处理过。显然,我们还得过滤一下传到Application的WM_SYSCOMMAND消息。为了加深了解,我们首先追加一个简单的任务栏系统菜单:

Unit AddMenuDemo;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,Menus;

type

TDemoForm = class(TForm)
procedure FormCreate(Sender: TObject);
...

private

{ Private declarations }
// 我的消息过滤器
procedure OnAppMessage(var Msg: TMsg; var Handled: Boolean);
...

public

{ Public declarations }
...

end;

var
DemoForm1: TDemoForm;
implementation
const

My_SimpleCMD1 = WM_USER + 1; // 定义三个用户消息,用来处理菜单项被点击
// 时相应的动作
My_SimpleCMD2 = WM_USER + 2;
My_SimpleCMD3 = WM_USER + 3;
...
procedure TDemoForm1.FormCreate(Sender: TObject);
begin

Application.OnMessage := OnAppMessage; //定义自己的消息处理过程
//定义了提交、反馈、处理三个菜单项
AppendMenu(GetSystemMenu(Application.Handle, FALSE),MF_STRING,
My_SimpleCMD1,提交);
AppendMenu(GetSystemMenu(Application.Handle, FALSE),MF_STRING,
My_SimpleCMD2,反馈);
AppendMenu(GetSystemMenu(Application.Handle, FALSE),MF_SEPARATOR,
0, ); // 定义一分割线
AppendMenu(GetSystemMenu(Application.Handle, FALSE),MF_STRING,
My_SimpleCMD3,处理);

end;

procedure TDemoForm1.OnAppMessage(var Msg: TMsg; var Handled: Boolean);
begin
// 定制自己的消息处理过程

if (Msg.message = WM_SYSCOMMAND) and (Msg.wParam = My_SimpleCMD1) then
begin

ShowMessage(正在提交...);
Handled := True;
...

end;
if (Msg.message = WM_SYSCOMMAND) and (Msg.wParam = My_SimpleCMD2) then
begin

ShowMessage(正在反馈...);
Handled := True;
...

end;

if (Msg.message = WM_SYSCOMMAND) and (Msg.wParam = My_SimpleCMD3) then
begin

ShowMessage(正在处理...);
Handled := True;
...

end;

end;
....

   当我们处理的事务比较多并且可分组,以上的做法就比较烦琐,这时就应该定义成多个 MF_POPUP ,其各个子菜单除了uIDNewItem 传递这个子菜单的句柄外,另外独特之处在于消息过滤器的 Msg.wParam 是各个菜单项的 Command。这个Command是在构建 TPopupMenu 时就定义了。无论是否是 MenuItem 或 PopupMenu,其Command的值都是顺序递增的。以下是一范例:
unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, Menus;
type

TForm1 = class(TForm)
PopupMenu1: TPopupMenu;
N1: TMenuItem; // Caption := 范例一;
N2: TMenuItem; // Caption := 范例二;
N3: TMenuItem; // Caption := 范例三;
procedure FormCreate(Sender: TObject);
...
private

{ Private declarations }
// 我的消息过滤器
procedure OnAppMessage(var Msg: TMsg; var Handled: Boolean);
...

public

{ Public declarations }
...

end;
...

var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin

Application.OnMessage := OnAppMessage; //定义自己的消息处理过程
// 定义一分割线
AppendMenu(GetSystemMenu(Application.Handle, FALSE), MF_SEPARATOR, 0, );
// 定义提交子菜单
AppendMenu(GetSystemMenu(Application.Handle, FALSE), MF_POPUP,
PopupMenu1.Handle,提交);

end;

procedure TForm1.OnAppMessage(var Msg: TMsg; var Handled: Boolean);
begin
// 定制自己的消息处理过程
if (Msg.message = WM_SYSCOMMAND) AND (Msg.wParam $#@60; WM_USER) then
begin

Case Msg.wParam of
// N1.Command = 1
1:ShowMessage(范例一 Command:+ IntToStr(N1.Command));
// N1.Command = 2
2:ShowMessage(范例二 Command:+ IntToStr(N2.Command));
// N1.Command = 3
3:ShowMessage(范例三 Command:+ IntToStr(N3.Command));

end;
Handled := True;

end;
...

end;
...

  可以看出,MF_STRING 与 MF_POPUP 在消息处理机制上是稍微有点不同的,另外,如果要在菜单前面加上图标的话,这在Delphi 4.x、Delphi 5.x 版本下是不成问题,如果是在 Delphi 3.x 下的话,只要定义成自绘 MenuItem即可,不过稍许复杂了一点。在应用过程中,需要提醒的是,这几组定义不能一起使用:

A. MF_DISABLED, MF_ENABLED, 和 MF_GRAYED
B. MF_BITMAP, MF_STRING, 和 MF_OWNERDRAW
C. MF_MENUBARBREAK 和 MF_MENUBREAK
D. MF_CHECKED 和 MF_UNCHECKED



技术文章快速查找

栏目导航
软件应用
·操作系统 ·杀毒防黑 ·应用软件
·聊天软件 ·网络软件  
Web开发
·ASP ·JavaScript ·CGI
·JSP ·VbScript ·Web服务器
·PHP ·XML  
开发语言
·VB ·VC ·ASP.NET
·Java ·C/C++ ·Delphi
数据库开发
·MySQL ·SQL/Access ·PowerBuilder
·Oracle ·DB2  
网站设计
·Flash ·Dreamweaver ·HTML/CSS
·Fireworks ·FrontPage  
平面设计
·Photoshop ·CorelDraw ·AutoCAD
·FreeHand ·Illustrator ·3DsMAX
媒体动画
·Director ·Authorware ·Maya
·视频处理    


相关软件 产品库推荐
·笔记本 ·台式机 ·服务器
·数码相机 ·手机 ·GPS
·DV摄像机 ·MP3 ·MP4
·CPU ·硬盘 ·内存
·主板 ·显卡 ·显示器
·打印机 ·投影机 ·路由器

QQ群:26020580
delphi技术联盟
拯救神奇的delphi时代!
让我们共同努力!<...
游客 发表于2008-7-29 13:58:40
对"定制任务栏上的系统菜单"的评论 - 快速回贴
内容:
  [完成后可按Ctrl+Enter发布]

百度中 定制任务栏上的系统菜单 相关内容
Google搜索中 定制任务栏上的系统菜单 相关内容
雅虎中 定制任务栏上的系统菜单 相关内容
Sogou搜索中 定制任务栏上的系统菜单 相关内容

相关软件 最新回复帖子:

·定制任务栏上的系统菜单
·用Delphi实现自定义颜色对话框及其构件
·熊猫烧香核心源码(Delphi模仿版本)
·Delphi中数据的自动录入
·基于Delphi的屏幕抓图技术的实现
·通过查询分析器对比SQL语句执行效率
·如何禁止产生Thumbs.db文件和删除方法
·输入法设置导致CAD界面中显示“?”问题
·Fireworks轻松打造下拉导航条
·Oracle Job任务异常原因分析及其解决


  相关软件 定制任务栏上的系统菜单相关文章
活用 SetSelTextBuf 捕捉来自 Thread 的异常
在DEPHI 4.0中实现动画功能 修改与克隆对象属性
控制系统菜单 怎样建立简单的任务栏应用程序
用修改文件时间的方法来加密文件 用Dephi程序维护Paradox 数据表的索引
有“背景”的窗体 自定义快速报表的打印预览窗口
用Delphi实现自定义颜色对话框及其构件 Delphi实用编程经验二则