关于消息的发送及接收(100分)

  • 主题发起人 主题发起人 fjnnz
  • 开始时间 开始时间
F

fjnnz

Unregistered / Unconfirmed
GUEST, unregistred user!
我在project1中自定义了一个消息:
const
WM_HintShow = WM_User + 2000;

在button1中的事件

var
Hd: HWND;
C: PChar;
Str : string ;
begin
Str := 'this is just a test!' ;
GetMem(C, 254) ;
StrCopy(C, PChar(Str)) ;
Hd := FindWindow(nil,'Form1');
SendMessage(Hd,WM_HintShow,0,Integer(@C)) ;
FreeMem(C);
end;

目的是发送该消息

然后,我在project2中定义了一个函数
procedure WMHintShow(var Message:TMessage); message WM_HintShow;
实现:
ShowMessage(PChar(Message.LParam));
目的是想取出刚才的‘this is just a test’,可是取出来的总是乱码,那儿错了?
 
进程之间的地址是不能互相识别的!你把不同进程间的字符串地址拿来用是不行的!

Windows消息WM_SetText,WM_Gettext,LB_ADDSTRING能够用是因为操作系统提供了内存

转换功能,也就是间接用了共享内存区,否则不行!
 
CreateFileMapping ,MapViewOfFile,UnmapViewOfFile,OpenFileMapping
自己揣摩吧!
 
学习~~~~~~~~~~~~~~~~~~~~
 
为什么在两个项目中交叉调用!!!
可以看一下帮助!!!!!
 
涉及到了进程间通信的问题,除了用内存映射文件实现外,
最简单的办法是用WM_COPYDATA消息:
发送:
procedure TForm1.BtnSendCopyDataClick(Sender: TObject);
var
Cds: TCopyDataStruct;
Hwnd: THandle;
begin
// small data (32 bits): top of form
Cds.dwData := Top;
// size of data
Cds.cbData := Length (Caption) + 1;
// allocate memory for the large block and fill it
GetMem (Cds.lpData, Cds.cbData );
StrCopy (Cds.lpData, PChar (Caption));
// get the handle of the target window
Hwnd := FindWindow ('TFormGetData', 'GetData');
if Hwnd <> 0 then
begin
// send the message
if SendMessage (
Hwnd, WM_COPYDATA, Handle, Cardinal(@Cds)) = 1 then
// received
Beep;
end
else
// target not found
ShowMessage ('GetData window not found.');
FreeMem (Cds.lpData);
end;

接收:
procedure TFormGetData.GetCopyData (var Msg: TWmCopyData);
var
FromTitle: string;
begin
Memo1.Clear;
SetLength (FromTitle, 100);
GetWindowText (Msg.From, PChar(FromTitle), 100);
FromTitle := pChar (FromTitle);
Memo1.Lines.Add ('Message from: ' + FromTitle);
with Memo1.Lines, Msg.CopyDataStruct^ do
begin
Add ('Small data: ' + IntToStr (dwData));
Add ('Large block size: ' + IntToStr (cbData));
Add ('String: ' + PChar (lpData));
end;
// received (true)
Msg.Result := 1;
end;
 
SendMessage(Hd,WM_HintShow,255,Integer(@C))
 
如果想简单又只是传字符串的话,一个简单方法:

发送方不带消息参数(0,0),而往剪贴版写

接受方收到消息往剪贴板查询内容或干脆监视剪贴板消息得了!WM_DRAWCLIPBOARD消息!
 
如果字符串小于255,你发送 GlobalAddAtom 得到的原子(word值),
接收方 GlobalGetAtomName 得到字符串,然后接收方GlobalDeleteAtom 删除之
 
WM_COPYDATA是可以的,我试过了.我只是想用一下自定义消息.除了用共享
内存块之外没有别的方法吗?
 
真是佩服你們
 
你现在是要进行进程间通信
用自定义消息Windows不会帮你做任何额外的事,所以这是行不通的。
 
我学习、学习、再学习!
 
进程间共享信息最有效的方法就是内存映射文件
弄明白这几个api:CreateFile
createfilemaping
OpenFileMapping
MapViewOfFile
CloseHandle
 
进程间可使用OLE SERVER,不同机器间可使用DCOM 或 SOCKET
研究这个没用,使用不当后果严重,
WINDOWS的消息机制不是干这个的
 
同意楼上
 
多人接受答案了。
 
后退
顶部