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


    以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,截图:

    QQ截图20120520221444

  • 相关阅读:
    [Leetcode]-- Median of Two Sorted Arrays
    Implement strStr()
    [Leetcode]-- Remove Element
    3Sum
    推荐一个跨平台内存分配器
    ACE的缺陷
    详谈高性能UDP服务器的开发
    vi查找替换命令详解
    gcc多版本切换
    Centos 5.5升级Python到2.7版本
  • 原文地址:https://www.cnblogs.com/fjut/p/2510910.html
Copyright © 2020-2023  润新知