您的位置:首页 > 编程语言 > Delphi

delphi 与 C++ 进程之间的命名管道通信

2012-05-20 22:15 701 查看
以C++生成的程序作为服务端,delphi生成的程序为客户端,实现客户端发送数据,服务端接受数据并处理。

客户端:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,ShellAPI,ComCtrls, xmldom, XMLIntf, msxmldom, XMLDoc;

type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
OpenDialog1: TOpenDialog;
Button1: TButton;
Button3: TButton;
GroupBox2: TGroupBox;
XMLDocument1: TXMLDocument;
Button9: TButton;
Label4: TLabel;
Edit1: TEdit;
Label5: TLabel;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
Label7: TLabel;
Label8: TLabel;
Edit10: TEdit;
GroupBox4: TGroupBox;
Label9: TLabel;
ComboBox1: TComboBox;
Label10: TLabel;
ComboBox2: TComboBox;
TabSheet3: TTabSheet;
GroupBox5: TGroupBox;
ListBox1: TListBox;
GroupBox3: TGroupBox;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
Label6: TLabel;
Button2: TButton;
Edit11: TEdit;
Button4: TButton;
Button5: TButton;
Button6: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button9Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure ComboBox1Exit(Sender: TObject);
procedure ComboBox2Exit(Sender: TObject);
procedure ListBox1EndDrag(Sender, Target: TObject; X, Y: Integer);
procedure ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
par, index: Integer; //判断是否存在config.xml

implementation

{$R *.dfm}

//选择图片(基本动作)
procedure TForm1.Button1Click(Sender: TObject);
begin
form1.OpenDialog1.DefaultExt:='png'; //设置缺省扩展名
form1.OpenDialog1.Title:='请选择一个png文件';  //设置对话框标题
form1.OpenDialog1.Filter:='Text files(*.png)|*.png'; //设置文件过滤条件
form1.OpenDialog1.Execute;   //打开对话框
edit10.Clear;
edit10.text:=OpenDialog1.FileName;
end;

//载入配置文件config.xml,并打开ConfigAction.win32.exe
procedure TForm1.FormCreate(Sender: TObject);
var
nodelist: ixmlnodelist;
node: ixmlnode;
i: integer;
begin
XMLDocument1.LoadFromFile(ExtractFilePath(Application.ExeName)+'config\config.xml');
combobox1.Clear;
nodelist:= XMLDocument1.DocumentElement.ChildNodes;

for i := 0 to nodelist.count - 1 do
begin
node := nodeList[i];
combobox1.Items.add(node.nodename);
end;

ShellExecute(handle, 'open','E:\ios\study\action\2012-4-1\ConfigAction\ConfigAction\Debug.win32\ConfigAction.win32.exe', '',nil, SW_SHOWNORMAL);
end;

//将基本动作配置参数存入config.xml
procedure TForm1.Button9Click(Sender: TObject);
var
nodelist: ixmlnodelist;
node: ixmlnode;
begin
node:= xmldocument1.documentelement.childnodes['move'];
XMLDocument1.Options := [doNodeAutoIndent];  //换行
node:= node.AddChild('item');
node.Attributes['id']:= FormatDateTime( 'YYYYMMDDHHmmss ', Now);
node.Attributes['beginPoint']:= edit1.Text+':'+edit2.Text;
node.Attributes['controlPoint1']:= edit3.Text+':'+edit4.Text;
node.Attributes['controlPoint2']:= edit5.Text+':'+edit6.Text;
node.Attributes['endPoint']:= edit7.Text+':'+edit8.Text;
node.Attributes['time']:= edit9.text;
node.Attributes['png']:= edit10.text;
XMLDocument1.Options := [doNodeAutoIndent];  //换行
XMLDocument1.SaveToFile(ExtractFilePath(Application.Exename) + 'config\config.xml');
FormCreate(nil); //重新载入
end;

//将复杂动作配置参数存入config.xml
procedure TForm1.Button4Click(Sender: TObject);
var
nodelist: ixmlnodelist;
node: ixmlnode;
i: integer;
typeStr:string;
begin
if(radiobutton1.checked) then
begin
typeStr:= '1';
end
else if (radiobutton2.checked) then
begin
typeStr:='2';
end
else
showmessage('请选择动作类型!');

node:= xmldocument1.documentelement.childnodes['complex'];
XMLDocument1.Options := [doNodeAutoIndent];  //换行
node:= node.AddChild('item');
node.Attributes['id']:= FormatDateTime( 'YYYYMMDDHHmmss ', Now);
node.Attributes['type']:= typeStr;

for i:=0 to listbox1.Items.Count-1 do
begin
node.Attributes['action' + inttostr(i+1)]:= listbox1.Items[i];
end;

node.Attributes['png']:= edit11.text;
XMLDocument1.Options := [doNodeAutoIndent];  //换行
XMLDocument1.SaveToFile(ExtractFilePath(Application.Exename) + 'config\config.xml');
end;

//选择图片(复杂动作)
procedure TForm1.Button2Click(Sender: TObject);
begin
form1.OpenDialog1.DefaultExt:='png'; //设置缺省扩展名
form1.OpenDialog1.Title:='请选择一个png文件';  //设置对话框标题
form1.OpenDialog1.Filter:='Text files(*.png)|*.png'; //设置文件过滤条件
form1.OpenDialog1.Execute;   //打开对话框
edit11.Clear;
edit11.text:=OpenDialog1.FileName;
end;

//选择动作类型并将其下的动作项add到combobox2下
procedure TForm1.ComboBox1Exit(Sender: TObject);
var
nodelist: ixmlnodelist;
node: ixmlnode;
i,j,num: integer;
begin
combobox2.Clear;
nodelist:= xmldocument1.DocumentElement.ChildNodes;

for i:=0 to nodelist.Count-1 do
begin
if nodelist[i].NodeName = combobox1.Text then
break;
end;

if booltostr(nodelist[i].HasChildNodes)<>'0' then
begin
nodelist:=nodelist[i].ChildNodes;
for j := 0 to nodelist.Count-1 do
begin
combobox2.Items.add(nodelist[j].Attributes['id']);
end;
end;
end;

//添加基本动作项到listbox1
procedure TForm1.ComboBox2Exit(Sender: TObject);
begin
listbox1.items.Add(combobox2.text);
end;

//实现listbox里的项的拖拉排序
procedure TForm1.ListBox1EndDrag(Sender, Target: TObject; X, Y: Integer);
var
Tmp: string;
begin
Tmp:=ListBox1.Items[ListBox1.ItemIndex];
ListBox1.Items[ListBox1.ItemIndex]:=ListBox1.Items[Index];
ListBox1.Items[Index]:=Tmp;
ListBox1.OnEndDrag:=nil;
end;

//实现listbox里的项的拖拉排序
procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Index:=TListBox(Source).ItemIndex;
ListBox1.OnEndDrag:=ListBox1EndDrag;
if State<>dsDragMove then
Accept:=false;
end;

//预览,发送数据给服务端。
procedure TForm1.Button3Click(Sender: TObject);
var
pipehandle:hwnd;
byteswrite:dword;
pipenamestr, dataStr:string;

begin
//打开exe
ShellExecute(handle, 'open','E:\ios\study\action\2012-4-1\ConfigAction\ConfigAction\Debug.win32\ConfigAction.win32.exe', '',nil, SW_SHOWNORMAL);
//管道名
pipenamestr:='\\.\pipe\demo';
//发送的数据,以','为分隔符
dataStr:= edit1.Text+','+edit2.Text+','+edit3.Text+','+edit4.Text+','+edit5.Text+','+edit6.Text+','+edit7.Text+','+edit8.Text+','+edit9.Text+','+edit10.Text;
//等待管道的出现
if waitnamedpipe(pchar(pipenamestr),nmpwait_wait_forever)=false then
begin
showmessage(format('waitnamedpipe faile with error %d',[getlasterror()]));
exit;
end;

//打开一个通信端口
pipehandle:= createfile(pchar(pipenamestr),generic_read or generic_write,
file_share_write,nil,open_existing,file_attribute_normal,0);
if pipehandle=invalid_handle_value then
begin
showmessage(format('createfile faile with error %d',[getlasterror()]));
exit;
end;

//发送数据
if writefile(pipehandle,pchar(dataStr)^,length(dataStr),byteswrite,nil)=
false then
begin
showmessage(format('writefile faile with error %d',[getlasterror()]));
exit;
end;
//关闭串行口
closehandle(pipehandle);
end;

end.


服务端主要代码:

/**************接收客户端发来的数据****************/
#include "GetParameter.h"
#include <iostream>

using namespace std;

GetParameter::GetParameter(void)
{

}

GetParameter::~GetParameter(void)
{
}

int GetParameter::commWithClient(void)
{
//创建命名管道
h=CreateNamedPipe(_T("\\\\.\\pipe\\demo"), PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0, 1, 1024, 1024, 0, NULL);
if(INVALID_HANDLE_VALUE==h)
{
//cout<<"创建命名管道失败!"<<endl;
return 1;
}

if(ConnectNamedPipe(h, NULL)==NULL)
{
//cout<<"连接失败!"<<endl;
return 2;
}

return 0;
}

int GetParameter::readDataFromPipe()
{
DWORD len=0;
if(ReadFile(h, buf, sizeof(buf), &len, NULL)==TRUE)
{
//管道连接成功,读取数据
buf[len] = '\0';
//cout << buf<< endl;
CloseHandle(h);
return 0;
}
CloseHandle(h);
return 1;
}

char* GetParameter::getBuf(void)
{
return buf;
}

/******获取数据并分离处理,并使用数据进行 贝塞尔曲线 演示********/

#include "DemoLayer.h"
#include "GetParameter.h"

using namespace cocos2d;

DemoLayer::DemoLayer(void)
{
}

DemoLayer::~DemoLayer(void)
{
}

bool DemoLayer::init(void)
{
GetParameter* k= new GetParameter();
k->commWithClient();
k->readDataFromPipe();

//获取客户端发来的数据
char* m = k->getBuf();

//分离出各个字符串(以","为分隔符)
char *token = NULL, *p[10];
int i = 0;
p[i] = strtok(m, ",");
while ((token = strtok(NULL, ",")) != NULL)
{
p[++i] = token;
}

//使用p[]数据。
bool bRet = false;
do
{
CC_BREAK_IF(! CCLayer::init());

CCSize s = CCDirector::sharedDirector()->getWinSize();
CCMenuItemImage* quit = CCMenuItemImage::itemFromNormalImage("CloseNormal.png", "CloseSelected.png", this, menu_selector(DemoLayer::onQuit));
CC_BREAK_IF(! quit);
quit->setPosition(ccp(s.width-20, 20));

CCMenu* pMenu = CCMenu::menuWithItems(quit, NULL);
CC_BREAK_IF(! pMenu);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu, 0, 1);

bgSprite = CCSprite::spriteWithFile("bg.png");
CC_BREAK_IF(! bgSprite);
//bgSprite->setAnchorPoint(CCPointZero);
this->addChild(bgSprite, -1, 2);

pSprite = CCSprite::spriteWithFile(p[9]);
CC_BREAK_IF(! pSprite);
pSprite->setPosition(CCPointMake(atoi(p[0]), atoi(p[1])));
this->addChild(pSprite, 1, 3);

//ActionBezier 测试
ccBezierConfig bezier;
bezier.controlPoint_1 = CCPointMake(atoi(p[2]), atoi(p[3]));
bezier.controlPoint_2 = CCPointMake(atoi(p[4]), atoi(p[5]));
bezier.endPosition = CCPointMake(atoi(p[6]), atoi(p[7]));

CCActionInterval*  bezierTo = CCBezierTo::actionWithDuration(atoi(p[8]), bezier);
pSprite->runAction(bezierTo);

this->setIsTouchEnabled(true);

bRet = true;

} while (0);

delete k;

return bRet;
}
/*
void DemoLayer::ccTouchesEnded(cocos2d::CCSet* pTouches, cocos2d::CCEvent* pEvent)
{
CCTouch* touch = (CCTouch*)pTouches->anyObject();
//获得触点坐标
CCPoint location = touch->locationInView(touch->view());
CCPoint convertedLocation = CCDirector::sharedDirector()->convertToGL(location);
}
*/
void DemoLayer::onQuit(CCObject* pSender)
{
CCDirector::sharedDirector()->end();
}


OK,截图:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: