我对 delphi 不太熟悉,今天看了有关发送自定义消息的内容,有一个问题不明白,
大家帮我看看吧 !如果要发送一个自定义消息,可以这样做:1.定义消息常量
const
WM_MESSAGETEST = WM_USER + 100;2 在 Form1 的 public 中定义消息处理过程:
procedure WM_MessageTest(var AMessage : TMessage); message WM_MYMSG;
procedure TForm1.WM_MessageTest(var AMessage: TMessage);
begin
ShowMessage('收到消息!');
//这里继续做一个需要10秒种的事情
end;3 在需要发送消息的地方:
PostMessage(Form1.Handle, WM_MYMSG ,0, 0);问题: 要发送自定义消息,就必须知道窗口的句柄,既然知道了窗口的句柄,那么
就应该存在窗口实例的,我不通过发送消息也可以做到,比如这样:
Form1.WM_MessageTest;
我原来以为 PostMessage 发送了消息立刻返回,继续执行发送消息后的的代码,
但是我做了一个测试,发现,必须等到消息处理过程执行完了之后才会执行发送消息代码 PostMessage(..) 后面的代码.我用 SendMessage(...) 测试也是这样。 procedure TForm1.Button1Click(Sender: TObject);
begin
PostMessage(Form1.Handle, WM_MYMSG ,0, 0);
ShowMessage('测试'); //为什么到消息过程执行完成后才执行这里???
end; 发送消息和直接调用方法有什么区别?
发送自定义消息有什么好处呢?
大家帮我看看吧 !如果要发送一个自定义消息,可以这样做:1.定义消息常量
const
WM_MESSAGETEST = WM_USER + 100;2 在 Form1 的 public 中定义消息处理过程:
procedure WM_MessageTest(var AMessage : TMessage); message WM_MYMSG;
procedure TForm1.WM_MessageTest(var AMessage: TMessage);
begin
ShowMessage('收到消息!');
//这里继续做一个需要10秒种的事情
end;3 在需要发送消息的地方:
PostMessage(Form1.Handle, WM_MYMSG ,0, 0);问题: 要发送自定义消息,就必须知道窗口的句柄,既然知道了窗口的句柄,那么
就应该存在窗口实例的,我不通过发送消息也可以做到,比如这样:
Form1.WM_MessageTest;
我原来以为 PostMessage 发送了消息立刻返回,继续执行发送消息后的的代码,
但是我做了一个测试,发现,必须等到消息处理过程执行完了之后才会执行发送消息代码 PostMessage(..) 后面的代码.我用 SendMessage(...) 测试也是这样。 procedure TForm1.Button1Click(Sender: TObject);
begin
PostMessage(Form1.Handle, WM_MYMSG ,0, 0);
ShowMessage('测试'); //为什么到消息过程执行完成后才执行这里???
end; 发送消息和直接调用方法有什么区别?
发送自定义消息有什么好处呢?
解决方案 »
- 如何把DBGrid导出为csv文档?
- combobox的一个小问题
- Ord什么意思?怎么用?谢谢
- 有人手头有delphi6的安装程序吗?100分急求,在线等!!!!!!!!!!!
- 如何判断窗体(form)是否处于开启状态!!!
- [SOS]在DELPHI中如何引用一个开发包,如ADO之类的
- 要从Oracle导出表数据(包括表结构)到Access文件,两者都是用ADO连接数据库,怎么办?
- 如何写一个自己的Button能够改变字体颜色
- 谁有Delphi 7写的FTP服务器能给我一份吗?
- 窗口执行顺序问题,请多帮助,谢谢
- 请问大家关于delphi的问题要到哪里提问?
- 键盘中的向下键的ascii码是多少?
// 但如果发送消息的话,可以不必等返回结果
// 直接运行发送消息这句下面的程序可是我做了一个测试,发现是等到消息处理过程执行完了才执行下一句的。
procedure TForm1.Button1Click(Sender: TObject);
begin
PostMessage(Form1.Handle, WM_MYMSG ,0, 0);
ShowMessage('测试'); //上面的消息过程执行完成后才执行???
end;你可以试试看,发送完消息后并不会立即执行下面的ShowMessage('测试');
而是执行完了消息处理过程后才执行的。
begin
tag:=1;
s:='2222';
postmessage(self.handle,wm_paint,0,0);
showmessage(s);
end;procedure TForm1.FormPaint(Sender: TObject);
begin
if tag=1 then
begin
s:='1111';
tag:=0;
end;
end;
请你试试这个过程
结果是2222
这是因为ShowMessage实质调用了Application.HandleMessage
HandleMessage先检查消息队列里有没有消息,有的话就执行
所以限执行消息处理过程
我试用MessageBox也是一样,估计也差不多
这样就能看出差别了unit tt;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;const
WM_MYMSG = WM_USER + 100;type
TMainForm = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure WM_MessageTest(var AMessage : TMessage); message WM_MYMSG;
public
{ Public declarations }
end;var
MainForm: TMainForm;implementation{$R *.dfm}procedure TMainForm.WM_MessageTest(var AMessage: TMessage);
begin
Memo1.Lines.Add('收到消息');end;procedure TMainForm.Button1Click(Sender: TObject);
begin
PostMessage(Handle, WM_MYMSG ,0, 0);
Memo1.Lines.Add('单击');
end;end.可以看到Memo1里出现的是
单击
收到消息
PostMessage()发送了消息后就返回,结果自然是 2222
如果SendMessage()则是等消息处理完了再返回,那么结果就是 1111
你是怎么知道“ShowMessage实质调用了Application.HandleMessage”? 之所以我上面会出现那种情况,是因为我上面的 Button1Click
我是在另一个线程中做的。
begin
ShowMessagePos(Msg, -1, -1);
end;procedure ShowMessagePos(const Msg: string; X, Y: Integer);
begin
MessageDlgPos(Msg, mtCustom, [mbOK], 0, X, Y);
end;function MessageDlgPos(const Msg: string; DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer): Integer;
begin
Result := MessageDlgPosHelp(Msg, DlgType, Buttons, HelpCtx, X, Y, '');
end;
function MessageDlgPosHelp(const Msg: string; DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer;
const HelpFileName: string): Integer;
begin
with CreateMessageDialog(Msg, DlgType, Buttons) do
try
HelpContext := HelpCtx;
HelpFile := HelpFileName;
if X >= 0 then Left := X;
if Y >= 0 then Top := Y;
if (Y < 0) and (X < 0) then Position := poScreenCenter;
Result := ShowModal;
finally
Free;
end;
end;然后注意ShowModalfunction TCustomForm.ShowModal: Integer;
var
WindowList: Pointer;
SaveFocusCount: Integer;
SaveCursor: TCursor;
SaveCount: Integer;
ActiveWindow: HWnd;
begin
CancelDrag;
if Visible or not Enabled or (fsModal in FFormState) or
(FormStyle = fsMDIChild) then
raise EInvalidOperation.Create(SCannotShowModal);
if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
ReleaseCapture;
Include(FFormState, fsModal);
ActiveWindow := GetActiveWindow;
SaveFocusCount := FocusCount;
Screen.FSaveFocusedList.Insert(0, Screen.FFocusedForm);
Screen.FFocusedForm := Self;
SaveCursor := Screen.Cursor;
Screen.Cursor := crDefault;
SaveCount := Screen.FCursorCount;
WindowList := DisableTaskWindows(0);
try
Show;
try
SendMessage(Handle, CM_ACTIVATE, 0, 0);
ModalResult := 0;
repeat
Application.HandleMessage;
if Application.FTerminate then ModalResult := mrCancel else
if ModalResult <> 0 then CloseModal;
until ModalResult <> 0;
Result := ModalResult;
SendMessage(Handle, CM_DEACTIVATE, 0, 0);
if GetActiveWindow <> Handle then ActiveWindow := 0;
finally
Hide;
end;
finally
if Screen.FCursorCount = SaveCount then
Screen.Cursor := SaveCursor
else Screen.Cursor := crDefault;
EnableTaskWindows(WindowList);
if Screen.FSaveFocusedList.Count > 0 then
begin
Screen.FFocusedForm := Screen.FSaveFocusedList.First;
Screen.FSaveFocusedList.Remove(Screen.FFocusedForm);
end else Screen.FFocusedForm := nil;
if ActiveWindow <> 0 then SetActiveWindow(ActiveWindow);
FocusCount := SaveFocusCount;
Exclude(FFormState, fsModal);
end;
end;然后Application.HandleMessage调用ProcessMessage
function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
Handled: Boolean;
begin
Result := False;
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
Result := True;
if Msg.Message <> WM_QUIT then
begin
Handled := False;
if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end
else
FTerminate := True;
end;
end;
就是这样,不知对不
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AppEvnts, StdCtrls;const
WM_MYMSG = WM_USER + 100;type
TMainForm = class(TForm)
Memo1: TMemo;
Button1: TButton;
ApplicationEvents1: TApplicationEvents;
procedure Button1Click(Sender: TObject);
procedure ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
private
{ Private declarations }
procedure WM_MessageTest(var AMessage : TMessage); message WM_MYMSG;
public
{ Public declarations }
end;var
MainForm: TMainForm;implementation{$R *.dfm}procedure TMainForm.Button1Click(Sender: TObject);
begin
PostMessage(Handle, WM_MYMSG ,0, 0);
ShowMessage('单击消息');
Memo1.Lines.Add('单击');
end;procedure TMainForm.WM_MessageTest(var AMessage: TMessage);
begin
Memo1.Lines.Add('收到消息');
end;procedure TMainForm.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
if Msg.message = WM_MYMSG then
Memo1.Lines.Add(IntToStr(WM_MYMSG));
end;end.
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type Twowmessage = record
msg:cardinal;
wowstr:string;
end; TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations } public
{ Public declarations }
end; Tdog = class
private
procedure wow(var message:Twowmessage); message 100;
end;
var
Form1: TForm1;implementationprocedure Tdog.wow(var message:Twowmessage);
begin
showmessage(message.wowstr);
end;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
msg:Twowmessage;
begin
with Tdog.Create do
try
msg.msg:=100;
msg.wowstr:='minjianq is here';
dispatch(msg);
finally
free;
end;end;
end.
看关键的地方就可,其他没关的不用去看
真正遇到问题的在去看
其实,我是想做一个多线程的查询,里面就要用到发送消息,我也是刚刚学写的,我不知道怎么写那个那个 execute,才会最合理,因为从数据库服务器上取数据时,可能时间会很长,如果用单线程,查询时是无法点击界面的,如果查询时间超过了5秒钟,那几乎是很难忍受的,我测试了一下,从数据库上取数据和把查询到的数据显示在界面上最耗时间,你说怎么写那个 Execute方法比较合理?我查询主要要做 4 件事情:var
ClientDataset1: TClientDataset;
List1: TList; //用来存放记录(先将记录转换为指针)1 OpenDataSet; //ClientDataset1.open;
2 GetOneRecord; //将ClientDataset1中的一条记录(转为指针)存放到 List1 中。
3 MoveDataSet; //处理下一条 ClientDataset1.Next;
4 DisPlayResult; //将查询结果显示在 ListView 上。
//ListView.OwnerData := True 处理 OnData() 事件来显示
不好意思,没有弄过,不怎么懂
呵呵,不用客气