急问:怎样在两个应用程序之间发送数据? 现有两个应用程序,一个是常驻内存的程序a,另一个是要经常打开的程序b,常驻内存的程序a需要在运行b程序时需要b程序的参数来实现自己的操作,问?这个问题在delphi中怎么样来实现?? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 在B程序运行的时候,把参数保存下来然后用下面的方法传递给A转贴的,没找到出处----------------------------------------------用Delphi实现程序间的数据传递在实际应用中,我们经常需要多个程序相互配合来完成某些特定功能。例如两个应用程序间的同步、互斥;应用程序在起第二份实例时的参数自动传递…。要实现这些功能,就必须能实现程序间的数据传递。有些特殊的高级技术可在不同的程序间传递数据,如剪贴板、动态数据交换以及OLE自动化,但有条件限制并且相对较复杂。这里,我介绍三种有效的底层技术,希望对编程爱好者有所帮助。利用WM_COPYDATA消息 使用该消息涉及一个TcopyDataStruct结构类型的指针。该结构中有三个成员:dwData 是一个32位的附加参数cbData 表示要传递的数据区的大小lpData 表示要传递的数据区的指针下面举个例子。该例子由两个程序构成,分别为SendData和GetData。SendData程序向GetData程序发送消息,并传递edit1中的字符串;GetData在收到消息后,把SendData发送的字符串接受下来,并显示在相应的edit1中。SendData程序: ……varForm1: TForm1;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);vards: TCopyDataStruct;hd: THandle;beginds.cbData := Length (Edit1.Text) + 1;GetMem (ds.lpData, ds.cbData ); //为传递的数据区分配内存StrCopy (ds.lpData, PChar (Edit1.Text));Hd := FindWindow (nil, 'Form2'); // 获得接受窗口的句柄if Hd <> 0 thenSendMessage (Hd, WM_COPYDATA, Handle,Cardinal(@ds)) // 发送WM_COPYDATA消息elseShowMessage ('目标窗口没找到!');FreeMem (ds.lpData); //释放资源end;GetData程序: TForm2 = class(TForm)Edit1: TEdit;private{ Private declarations }publicprocedure Mymessage(var t:TWmCopyData);message WM_COPYDATA;{ Public declarations }end;varForm2: TForm2;implementationprocedure TForm2.Mymessage(var t:TWmCopyData);beginEdit1.text:=StrPas(t.CopyDataStruct^.lpData);//接受数据并显示。end;使用这种方法是WIN32应用程序进行交互的最简单的方法。使用全局原子 Win32系统中,为了实现信息共享,系统维护了一张全局原子表。每个原子中存放了一些共享数据。关于对原子的操作,有一组专门的API函数:GlobalAddAtom 在表中增加全局原子GlobalDeleteAtom 在表中删除全局原子GlobalFindAtom 在表中搜索全局原子GlobalGetAtomName 从表中获取全局原子笔者用这种方法实现了避免程序二次启动,但把第二次启动所带的参数传到第一个实例中以进行相应的处理的程序。基本处理如下:在工程文件中:program Pvdde;usesForms,shellapi,Windows,dialogs,dde in 'dde.pas' {Form1};{$R *.RES}beginif GlobalFindAtom(PChar('PDDE_IS_RUNNING')) = 0 then//避免二次启动beginK:=GlobalAddAtom(PChar('PDDE_IS_RUNNING'));Application.Initialize;Application.CreateForm(TForm1, Form1);Application.Run;endelsebegin//传递二次启动时的参数到第一个实例H := FindWindow(PChar('TForm1'), PChar('资料保密 严禁外传'));if ParamCount > 0 thenbeginL := GlobalAddAtom(PChar(ParamStr(1)));if H<>0 thenSendMessage(H, WM_MYMESSAGE, 0, L); { 传递原子句柄 }GlobalDeleteAtom(L); { 使用后释放 }end;Application.Terminate;end;end.在相应的窗口单元dde.pas增加对自定义消息WM_MYMESSAGE的处理:procedure TForm1.MyMessage(var T:TMessage); {对 WM_MYMESSAGE消息进行处理 }varP:Array [0..255] of char;beginGlobalGetAtomName(T.LParam, P,255); { 接受数据到p数组中 }end;使用存储映象文件 这种方法相对较复杂一些。当Win95与Winows Nt向内存中装载文件时,使用了特殊的全局内存区。在该区域内,应用程序的虚拟内存地址和文件中的相应位置一一对应。由于所有进程共享了一个用于存储映象文件的全局内存区域,因而当两个进程装载相同模块(应用程序或DLL文件)时,它们实际可以在内存中共享其执行代码。笔者通过调用一个带有特殊参数的CreateFileMapping函数,来间接达到程序间共享内存的目的。下面简要解释一下该函数。HANDLE CreateFileMapping(HANDLE hFile, //文件句柄 LPSECURITY_ATTRIBUTES lpFileMappingAttributes, // 可选安全属性DWORD flProtect, // 映象文件保护方式 DWORD dwMaximumSizeHigh, // 映象文件区域的底值 DWORD dwMaximumSizeLow, // 映象文件区域的顶值 LPCTSTR lpName // 映象文件的名字); 如果hFile是0xFFFFFFFF,在调用程序中必须指定dwMaximumSizeHigh 和dwMaximumSizeLow参数的值以确定映象文件的大小。通过这样的参数指定,该函数就创建了一个由操作系统页文件支持的特殊逻辑映象文件,而不是由实际操作系统的文件支持的逻辑映象文件。这个逻辑映象文件可以通过复制、继承或者按名字来达到共享。至于其它参数的详细说明,请参看在线帮助。在建立了映象文件之后,我们可以通过调用另外一个API函数MapViewOfFile来访问它的内存,该函数会返回一个指向共享内存块的特定指针。LPVOID MapViewOfFile(HANDLE hFileMappingObject, // 映象文件句柄 DWORD dwDesiredAccess, // 访问方式 DWORD dwFileOffsetHigh, // 映象文件区域的底值 DWORD dwFileOffsetLow, // 映象文件区域的顶值DWORD dwNumberOfBytesToMap // 映射字节数);如果 dwNumberOfBytesToMap 是0,映射整个文件。以下举例说明:privatehMapFile: THandle;MapFilePointer: Pointer;public{ Public declarations }end;varForm1: TForm1;implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);beginhMapFile := CreateFileMapping ($FFFFFFFF, // 特殊内存映射句柄nil, page_ReadWrite, 0,10000, 'DdhDemoMappedFile'); // 文件名if hMapFile <> 0 thenMapFilePointer := MapViewOfFile (hMapFile, // 上面映象文件的句柄File_Map_All_Access, 0, 0, 0) // 访问整个映象文件elseShowMessage ('hMapFile = 0');if MapFilePointer = nil thenShowMessage ('MapFilePointer = nil');end; procedure TForm1.BtnWriteClick(Sender: TObject);beginStrCopy (PChar (MapFilePointer),PChar (EditWrite.Text));//把内容写入共享内存end; procedure TForm1.BtnReadClick(Sender: TObject);varS: string;beginS := PChar (MapFilePointer);//从共享内存读出内容EditRead.Text := S;end;用这种方法,不但可以在不同的程序之间共享数据,还可以在同一程序的不同实例间共享数据。为了及时通知其它进程共享数据的变化,可以自定义一条用户消息,通过发消息来实现,这里不再赘述。利用以上三种方法均可以有效地实现数据传递、共享,所有的例子程序均在Delphi 3.0,4.0下调试通过。如需源码,写信至[email protected]索 一般都是共享内存或数据消息来实现通讯的_____________________http://lysoft.7u7.net //收消息unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm) Edit1: TEdit; procedure WndProc( var msg: TMessage ); override; procedure Mymessage(var t:TWmCopyData);message WM_COPYDATA; private { Private declarations } public { Public declarations } end;var Form1: TForm1;const WM_SHAKEHAND = WM_USER + 3333;implementation{$R *.dfm}procedure TForm1.WndProc(var msg: TMessage);begin case msg.msg of WM_SHAKEHAND : begin //YourReceiveProc( msg.LParam, msg.WParam ); SendMessage(msg.LParam,WM_SHAKEHAND,0,Self.Handle); showMessage('接受到了'); end; end; inherited WndProc(msg);end;procedure TForm1.Mymessage(var t:TWmCopyData);begin Edit1.text:=StrPas(t.CopyDataStruct^.lpData);//接受数据并显示。end;end. //发消息unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ShellAPI;type TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Button2: TButton; procedure Button1Click(Sender: TObject); procedure WndProc( var msg: TMessage ); override; procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;const WM_SHAKEHAND = WM_USER + 3333;implementation{$R *.dfm}procedure TForm1.WndProc(var msg: TMessage);begin case msg.msg of WM_SHAKEHAND : begin //YourReceiveProc( msg.LParam, msg.WParam ); showMessage('接受到了,关闭'); SendMessage (msg.LParam ,WM_CLOSE ,0,0); close; end; end; inherited WndProc(msg);end;procedure TForm1.Button1Click(Sender: TObject);var HChild: Hwnd; ds: TCopyDataStruct;begin ds.cbData := Length (Edit1.Text) + 1; GetMem (ds.lpData, ds.cbData ); //为传递的数据区分配内存 StrCopy (ds.lpData, PChar (Edit1.Text)); HChild := FindWindow(nil,PChar('商贸通')); if HChild <>0 then begin SendMessage (HChild, WM_COPYDATA, Handle ,Cardinal(@ds)); // 发送WM_COPYDATA消息 //PostMessage(HChild ,WM_SHAKEHAND,0,0); //ShowMessage('发送消息了!'); end; FreeMem (ds.lpData); //释放资源 //SendMessage(HChild,WM_SHAKEHAND,0,0);end;procedure TForm1.Button2Click(Sender: TObject);var HChild: Hwnd;begin HChild := FindWindow(nil,PChar('商贸通')); if HChild <>0 then begin //SendMessage (HChild, WM_COPYDATA, Handle ,Cardinal(@ds)); // 发送WM_COPYDATA消息 PostMessage(HChild ,WM_SHAKEHAND,0,self.Handle ); //ShowMessage('发送消息了!'); end;end;end. 在一个treeview的node没有子节点了,该node有超链接功能 我的QReport在预览的时候进行打印机设置,为什么没有效果呢, 一个EDIT的问题。。。在线求救呀呀!! 访问XML 文件拷贝问题。急!!在线等待 对DBGridEH双击实现保存,新增,修改 请问:如何得到ListBox控件某一选定项的值 delphi图象编程网站 http://lianwm.nease.com 修改IE浏览器 数箭连发给的好一起送!如何在delphi中定制浏览器,功能类似于腾讯或者轻骑兵,最好有源代码,用于学习, 数据包结构定义问题,急急... 关于数据库多人同时访问的问题
然后用下面的方法传递给A转贴的,没找到出处----------------------------------------------用Delphi实现程序间的数据传递在实际应用中,我们经常需要多个程序相互配合来完成某些特定功能。例如两个应用程序间的同步、互斥;应用程序在起第二份实例时的参数自动传递…。要实现这些功能,就必须能实现程序间的数据传递。有些特殊的高级技术可在不同的程序间传递数据,如剪贴板、动态数据交换以及OLE自动化,但有条件限制并且相对较复杂。这里,我介绍三种有效的底层技术,希望对编程爱好者有所帮助。利用WM_COPYDATA消息
使用该消息涉及一个TcopyDataStruct结构类型的指针。该结构中有三个成员:dwData 是一个32位的附加参数cbData 表示要传递的数据区的大小lpData 表示要传递的数据区的指针下面举个例子。该例子由两个程序构成,分别为SendData和GetData。SendData程序向GetData程序发送消息,并传递edit1中的字符串;GetData在收到消息后,把SendData发送的字符串接受下来,并显示在相应的edit1中。SendData程序:
……varForm1: TForm1;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);vards: TCopyDataStruct;hd: THandle;beginds.cbData := Length (Edit1.Text) + 1;GetMem (ds.lpData, ds.cbData ); //为传递的数据区分配内存StrCopy (ds.lpData, PChar (Edit1.Text));Hd := FindWindow (nil, 'Form2'); // 获得接受窗口的句柄if Hd <> 0 thenSendMessage (Hd, WM_COPYDATA, Handle,Cardinal(@ds)) // 发送WM_COPYDATA消息elseShowMessage ('目标窗口没找到!');FreeMem (ds.lpData); //释放资源end;GetData程序:
TForm2 = class(TForm)Edit1: TEdit;private{ Private declarations }publicprocedure Mymessage(var t:TWmCopyData);message WM_COPYDATA;{ Public declarations }end;varForm2: TForm2;implementationprocedure TForm2.Mymessage(var t:TWmCopyData);beginEdit1.text:=StrPas(t.CopyDataStruct^.lpData);//接受数据并显示。end;使用这种方法是WIN32应用程序进行交互的最简单的方法。使用全局原子
Win32系统中,为了实现信息共享,系统维护了一张全局原子表。每个原子中存放了一些共享数据。关于对原子的操作,有一组专门的API函数:GlobalAddAtom 在表中增加全局原子GlobalDeleteAtom 在表中删除全局原子GlobalFindAtom 在表中搜索全局原子GlobalGetAtomName 从表中获取全局原子笔者用这种方法实现了避免程序二次启动,但把第二次启动所带的参数传到第一个实例中以进行相应的处理的程序。基本处理如下:在工程文件中:program Pvdde;usesForms,shellapi,Windows,dialogs,dde in 'dde.pas' {Form1};{$R *.RES}beginif GlobalFindAtom(PChar('PDDE_IS_RUNNING')) = 0 then//避免二次启动beginK:=GlobalAddAtom(PChar('PDDE_IS_RUNNING'));Application.Initialize;Application.CreateForm(TForm1, Form1);Application.Run;endelsebegin//传递二次启动时的参数到第一个实例H := FindWindow(PChar('TForm1'), PChar('资料保密 严禁外传'));if ParamCount > 0 thenbeginL := GlobalAddAtom(PChar(ParamStr(1)));if H<>0 thenSendMessage(H, WM_MYMESSAGE, 0, L); { 传递原子句柄 }GlobalDeleteAtom(L); { 使用后释放 }end;Application.Terminate;end;end.在相应的窗口单元dde.pas增加对自定义消息WM_MYMESSAGE的处理:procedure TForm1.MyMessage(var T:TMessage); {对 WM_MYMESSAGE消息进行处理 }varP:Array [0..255] of char;beginGlobalGetAtomName(T.LParam, P,255); { 接受数据到p数组中 }end;使用存储映象文件
这种方法相对较复杂一些。当Win95与Winows Nt向内存中装载文件时,使用了特殊的全局内存区。在该区域内,应用程序的虚拟内存地址和文件中的相应位置一一对应。由于所有进程共享了一个用于存储映象文件的全局内存区域,因而当两个进程装载相同模块(应用程序或DLL文件)时,它们实际可以在内存中共享其执行代码。笔者通过调用一个带有特殊参数的CreateFileMapping函数,来间接达到程序间共享内存的目的。下面简要解释一下该函数。HANDLE CreateFileMapping(HANDLE hFile, //文件句柄 LPSECURITY_ATTRIBUTES lpFileMappingAttributes, // 可选安全属性DWORD flProtect, // 映象文件保护方式 DWORD dwMaximumSizeHigh, // 映象文件区域的底值 DWORD dwMaximumSizeLow, // 映象文件区域的顶值 LPCTSTR lpName // 映象文件的名字); 如果hFile是0xFFFFFFFF,在调用程序中必须指定dwMaximumSizeHigh 和dwMaximumSizeLow参数的值以确定映象文件的大小。通过这样的参数指定,该函数就创建了一个由操作系统页文件支持的特殊逻辑映象文件,而不是由实际操作系统的文件支持的逻辑映象文件。这个逻辑映象文件可以通过复制、继承或者按名字来达到共享。至于其它参数的详细说明,请参看在线帮助。在建立了映象文件之后,我们可以通过调用另外一个API函数MapViewOfFile来访问它的内存,该函数会返回一个指向共享内存块的特定指针。LPVOID MapViewOfFile(HANDLE hFileMappingObject, // 映象文件句柄 DWORD dwDesiredAccess, // 访问方式 DWORD dwFileOffsetHigh, // 映象文件区域的底值 DWORD dwFileOffsetLow, // 映象文件区域的顶值DWORD dwNumberOfBytesToMap // 映射字节数);如果 dwNumberOfBytesToMap 是0,映射整个文件。以下举例说明:privatehMapFile: THandle;MapFilePointer: Pointer;public{ Public declarations }end;varForm1: TForm1;implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);beginhMapFile := CreateFileMapping ($FFFFFFFF, // 特殊内存映射句柄nil, page_ReadWrite, 0,10000, 'DdhDemoMappedFile'); // 文件名if hMapFile <> 0 thenMapFilePointer := MapViewOfFile (hMapFile, // 上面映象文件的句柄File_Map_All_Access, 0, 0, 0) // 访问整个映象文件elseShowMessage ('hMapFile = 0');if MapFilePointer = nil thenShowMessage ('MapFilePointer = nil');end; procedure TForm1.BtnWriteClick(Sender: TObject);beginStrCopy (PChar (MapFilePointer),PChar (EditWrite.Text));//把内容写入共享内存end; procedure TForm1.BtnReadClick(Sender: TObject);varS: string;beginS := PChar (MapFilePointer);//从共享内存读出内容EditRead.Text := S;end;用这种方法,不但可以在不同的程序之间共享数据,还可以在同一程序的不同实例间共享数据。为了及时通知其它进程共享数据的变化,可以自定义一条用户消息,通过发消息来实现,这里不再赘述。利用以上三种方法均可以有效地实现数据传递、共享,所有的例子程序均在Delphi 3.0,4.0下调试通过。如需源码,写信至[email protected]索
http://lysoft.7u7.net
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Edit1: TEdit;
procedure WndProc( var msg: TMessage ); override;
procedure Mymessage(var t:TWmCopyData);message WM_COPYDATA;
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
const
WM_SHAKEHAND = WM_USER + 3333;implementation{$R *.dfm}procedure TForm1.WndProc(var msg: TMessage);
begin
case msg.msg of WM_SHAKEHAND :
begin
//YourReceiveProc( msg.LParam, msg.WParam );
SendMessage(msg.LParam,WM_SHAKEHAND,0,Self.Handle);
showMessage('接受到了');
end; end;
inherited WndProc(msg);
end;
procedure TForm1.Mymessage(var t:TWmCopyData);
begin
Edit1.text:=StrPas(t.CopyDataStruct^.lpData);//接受数据并显示。
end;end.
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ShellAPI;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure WndProc( var msg: TMessage ); override;
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
const
WM_SHAKEHAND = WM_USER + 3333;implementation{$R *.dfm}
procedure TForm1.WndProc(var msg: TMessage);
begin
case msg.msg of WM_SHAKEHAND :
begin
//YourReceiveProc( msg.LParam, msg.WParam );
showMessage('接受到了,关闭');
SendMessage (msg.LParam ,WM_CLOSE ,0,0);
close;
end; end;
inherited WndProc(msg);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
HChild: Hwnd;
ds: TCopyDataStruct;
begin
ds.cbData := Length (Edit1.Text) + 1;
GetMem (ds.lpData, ds.cbData ); //为传递的数据区分配内存
StrCopy (ds.lpData, PChar (Edit1.Text)); HChild := FindWindow(nil,PChar('商贸通'));
if HChild <>0 then
begin
SendMessage (HChild, WM_COPYDATA, Handle ,Cardinal(@ds)); // 发送WM_COPYDATA消息 //PostMessage(HChild ,WM_SHAKEHAND,0,0);
//ShowMessage('发送消息了!');
end;
FreeMem (ds.lpData); //释放资源 //SendMessage(HChild,WM_SHAKEHAND,0,0);
end;procedure TForm1.Button2Click(Sender: TObject);
var
HChild: Hwnd;
begin HChild := FindWindow(nil,PChar('商贸通'));
if HChild <>0 then
begin
//SendMessage (HChild, WM_COPYDATA, Handle ,Cardinal(@ds)); // 发送WM_COPYDATA消息 PostMessage(HChild ,WM_SHAKEHAND,0,self.Handle );
//ShowMessage('发送消息了!');
end;
end;end.