我才接触消息机制,看了书后,觉得很迷茫!怎样使用自定义的消息!高手门能句个例子吗?举的例子如果通俗易懂的话!我还可以另外给分!我希望能在大家的帮助下解决这个问题!希望大家不要献我苯哦!
解决方案 »
- 下面这段vb语句如何改为delphi,虽然不完整我就是想学学delphi中case语句的用法。
- delphi 得idftp.put方法能否上传大于2G得文件?
- ActiveXForm如何创建事件?
- [迷惑]为什么自己定义的Function不能执行代码?大家帮忙看看,Thx
- delphi7安装后lib文件夹下怎么没有OpenGL.pas文件呀?
- 怎样从数据库中导出文本,又将文本导入数据库?
- 如何删除非空表?
- 在线等待!求visio 2000的安装软件!
- 如何实现输入和显示另一个表的数据?
- 请教dock问题,将一Form dock到一panel,怎么才能显示出标题栏(关闭按钮)??
- 請問有沒有涵數可得知系統的啟動資料夾路徑?
- 运行BDE administrator 出错
unit CIMain;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;const
SX_MYMESSAGE=WM_USER; //自定义消息值
MessString='%s message now in %s.'; //String to alert user of messagetype
TfrmMain = class(TForm)
GroupBox1: TGroupBox;
chkAppMsg: TCheckBox;
chkWinProc: TCheckBox;
chkMsgProc: TCheckBox;
chkDefHandler: TCheckBox;
chkEatMsg: TCheckBox;
btnPostMessage: TButton;
btnSendMessage: TButton;
grbEatMsg: TGroupBox;
rdbOnMsg: TRadioButton;
rdbWinProc: TRadioButton;
rdbMsgProc: TRadioButton;
rdbDefHandler: TRadioButton;
procedure FormCreate(Sender: TObject);
procedure btnPostMessageClick(Sender: TObject);
procedure btnSendMessageClick(Sender: TObject);
procedure chkAppMsgClick(Sender: TObject);
procedure chkEatMsgClick(Sender: TObject);
private
{ Private declarations }
{在应用程序层处理消息}
procedure OnAppMessage(var Msg:TMsg;var Handled:Boolean);
{在窗体过程层处理消息}
procedure WndProc(var Msg:TMessage);override;
{在消息分发(dispatch)后处理消息}
procedure SXMyMessage(var Msg:TMessage);message SX_MYMESSAGE;
{缺省的消息处理函数}
procedure DefaultHandler(var Msg);override;
public
{ Public declarations }
end;var
frmMain: TfrmMain;implementation{$R *.DFM}const
//用于显示消息是被sent还是被posted
SendPostString:array[0..1] of string=('Sent','Posted');procedure TfrmMain.FormCreate(Sender: TObject);
begin
//用OnAppMessage方法设置应用程序的OnMessage属性
Application.OnMessage:=OnAppMessage;
//使用CheckBox的Tag属性来存储与之相关的Radio按钮的引用
chkAppMsg.Tag:=Longint(rdbOnMsg);
chkWinProc.Tag:=Longint(rdbWinProc);
chkMsgProc.Tag:=Longint(rdbMsgProc);
chkDefHandler.Tag:=Longint(rdbDefHandler);
//使用Radio的Tag属性来存储与之相关的CheckBox按钮的引用
rdbOnMsg.Tag:=Longint(chkAppMsg);
rdbWinProc.Tag:=Longint(chkWinProc);
rdbMsgProc.Tag:=Longint(chkMsgProc);
rdbDefHandler.Tag:=Longint(chkDefHandler);
end;procedure TfrmMain.OnAppMessage(var Msg:TMsg;var Handled:Boolean);
{应用程序的OnMessage处理函数}
begin
//检查是否是用户自定义的消息
if Msg.message=SX_MYMESSAGE then
begin
if chkAppMsg.Checked then
begin
ShowMessage(Format(MessString,[SendPostString[Msg.WParam],
'Application.OnMessage']));
Handled:=rdbOnMsg.Checked;
end;
end;
end;procedure TfrmMain.WndProc(var Msg:TMessage);
{Form窗口过程的WndProc函数}
var
CallInherited:Boolean;
begin
CallInherited:=true; //假设我们已经调用了继承的处理
if Msg.Msg=SX_MYMESSAGE then //检查是否为用户自定义的消息
begin
if chkWinProc.Checked then
begin
ShowMessage(Format(MessString,[SendPostString[Msg.WParam],
'WndProc']));
CallInherited:=not rdbWinProc.Checked;
end;
end;
if CallInherited then
inherited WndProc(Msg);
end;procedure TfrmMain.SXMyMessage(var Msg:TMessage);
{用户自定义的消息处理函数}
var
CallInherited:Boolean;
begin
CallInherited:=true;
if chkMsgProc.Checked then
begin
ShowMessage(Format(MessString,[SendPostString[Msg.WParam],
'Message Procdure']));
CallInherited:=not rdbMsgProc.Checked;
end;
if CallInherited then
inherited;
end;procedure TfrmMain.DefaultHandler(var Msg);
{缺省的消息处理函数}
var
CallInherited:Boolean;
begin
CallInherited:=true;
if TMessage(Msg).Msg=SX_MYMESSAGE then
begin
if chkDefHandler.Checked then
begin
ShowMessage(Format(MessString,[SendPostString[TMessage(Msg).WParam],
'DefaultHandler']));
CallInherited:=not rdbDefHandler.checked;
end;
end;
if CallInherited then
inherited DefaultHandler(Msg);
end;procedure TfrmMain.btnPostMessageClick(Sender: TObject);
{向窗体Post消息}
begin
PostMessage(Handle,SX_MYMESSAGE,1,0);
end;procedure TfrmMain.btnSendMessageClick(Sender: TObject);
{向窗体发送消息}
begin
SendMessage(Handle,SX_MYMESSAGE,0,0);
end;procedure TfrmMain.chkAppMsgClick(Sender: TObject);
{当单击CheckBox时使适当的radio按钮有效或失效}
begin
if chkEatMsg.Checked then
begin
with TRadioButton((Sender as TCheckBox).Tag) do
begin
Enabled:=TCheckBox(Sender).Checked;
if not Enabled then
Checked:=false;
end;
end;end;procedure TfrmMain.chkEatMsgClick(Sender: TObject);
{在适当的时候使radio按钮有效或无效}
var
i:integer;
DoEnable, EatEnabled:Boolean;
begin
//获取有效/无效标志
EatEnabled:= chkEatMsg.Checked;
for i:=0 to grbEatMsg.ControlCount-1 do
begin
with grbEatMsg.Controls[i] as TRadioButton do
begin
DoEnable:=EatEnabled;
if DoEnable then
DoEnable:=TCheckBox(Tag).Checked;
if not DoEnable then Checked:=false;
Enabled:=DoEnable;
end;
end;
end;end.
Delphi自定义消息应用一例
现在很多的应用程序都有这样一种功能,当用户选择最小化窗口时,窗口不是象平常那样最小化到任务栏上,而是“最小化”成一个任务栏图标。象FoxMail 3.0 NetVampire 3.0等都提供了这样的功能。实现这样的功能实际上并不复杂,在窗口最小化时,窗口会发出WM_SYSCOMMAND消息,你只要需要截取Windows的WM_SYSCOMMAND消息,在窗口最小化时隐藏窗口并调用WindowsAPI函数Shell_NotifyIcon将定义的图标添加到任务栏上,Shell_NotifyIcon的函数定义是这样的:function Shell_NotifyIcon(dwMessage:DWORD; lpData: PNotifyIconData): BOOL; stdcall; 其中的参数dwMessage指定Shell_NotifyIcon函数的操作,可以是NIM_ADD NIM_DELETE NIM_MODIFY三个值中的一个,分别对应添加图标、删除图标、修改图标的动作。
参数lpData指向的PNotifyIconData结构的定义如下:
_NOTIFYICONDATAW = recordcbSize: DWORD;Wnd: HWND;uID: UINT;uFlags: UINT;uCallbackMessage: UINT;hIcon: HICON;szTip: array [0..63] of WideChar;end;
TNotifyIconData = _NOTIFYICONDATAW;
在这个结构中Wnd指明所属的窗口,UCallbackMessage指明回调消息,如果指明了Wnd和 uCallbackMessage,则当用户对任务栏图标有动作(如点击图标,在图标上移动光标等)。系统都会发送uCallbackMessage消息给Wnd指定的窗口。hIcon是要添加的图标的句柄,szTip 是图标的提示行(就是当移动光标到图标上,出现的一个小黄方框内出现的文字)。消息。实现上面的功能,最主要的是要处理WM_SYSCOMMAND消息和自定义的图标消息,这些消息在Delphi中并没有相应的事件。这里就需要使用到Delphi的自定义消息处理功能来截取并处理这些消息。
首先看下面的程序。在执行程序之前,首先要改变Form1的Icon属性,给Form1装入一个图标,否则在任务栏上会出现一块空白。
unit Unit1;interfaceusesWindowsMessagesSysUtils
ClassesGraphicsControlsForms
DialogsShellAPI;
constWM_BARICON=WM_USER+200;
typeTForm1 = class(TForm)privateprocedure WMSysCommand(varMessage: TMessage); message WM_SYSCOMMAND;procedure WMBarIcon(varMessage:TMessage);message WM_BARICON;{ Private declarations }public{ Public declarations }end;
varForm1: TForm1;
implementation
{$R *.DFM}procedure TForm1.WMSysCommand(var Message:TMessage);varlpData:PNotifyIconData;beginif Message.WParam = SC_ICON thenbegin//如果用户最小化窗口则将窗口隐藏并在任务栏上添加图标lpData := new(PNotifyIconDataA);lpData.cbSize := 88;//SizeOf(PNotifyIconDataA);lpData.Wnd := Form1.Handle;lpData.hIcon := Form1.Icon.Handle;lpData.uCallbackMessage := WM_BARICON;lpData.uID :=0;lpData.szTip := 'Samples';lpData.uFlags := NIF_ICONor NIF_MESSAGE or NIF_TIP;Shell_NotifyIcon(NIM_ADDlpData);dispose(lpData);Form1.Visible := False;endelsebegin//如果是其它的SystemCommand消息则调用系统缺省处理函数处理之。DefWindowProc(Form1.HandleMessage.MsgMessage.WParamMessage.LParam);end;//end;
procedure TForm1.WMBarIcon(var Message:TMessage);varlpData:PNotifyIconData;beginif (Message.LParam = WM_LBUTTONDOWN) thenbegin//如果用户点击任务栏图标则将图标删除并回复窗口。lpData := new(PNotifyIconDataA);lpData.cbSize := 88;//SizeOf(PNotifyIconDataA);lpData.Wnd := Form1.Handle;lpData.hIcon := Form1.Icon.Handle;lpData.uCallbackMessage := WM_BARICON;lpData.uID :=0;lpData.szTip := 'Samples';lpData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;Shell_NotifyIcon(NIM_DELETElpData);dispose(lpData);Form1.Visible := True;end;end;
end.
运行上面的程序,点击程序窗口标题栏上的最小化按钮,你就可以看到窗口被“最小化”成了一个任务栏图标,点击图标,窗口又会恢复原来的状态。
从上面的程序可以看到,Delphi的自定义消息处理功能的实现也是十分简单的,首先在Form类的Private定义中加入自定义消息处理函数的定义,定义的描述如下:
procedure UserPro(Var Message:TMessage):message WindowsMessage其中UserPro是用户自定义消息处理函数的名称,WindowsMessage是Windows消息常量或自定义消息常量。
然后在程序中加入消息处理函数,函数的一般格式如下:
Procedure UserClass.UserPro(Var Message:TMessage);var//加入定义Begin//加入程序语句End;其中UserClass是封装自定义消息处理函数的类的名称。
最后,Delphi的自定义消息处理函数要涉及到Windows的消息的结构,在这里我就不多说了,大家可以参考Windows API帮助和Delphi的相关帮助信息。相信大家如果掌握了Delphi的自定义消息处理函数,一定可以编写出象VB一样简洁,象C++一样功能强大的程序来的。
WM_MYMSG = WM_USER + $1001;在程序当中SendMessage或PostMessage就可以了
在一个系统中,如果都使用上述方法,多个程序之间难免会出现消息冲突。故
我个人觉得,应该使用RegisterWindowMessage函数,以保证消息的唯一性。
这一点很多资料中都忽视了。算是一个补充吧!