NDde を利用してシンプルなDDE通信のクライアントとサーバーを作成する

NDde を利用してシンプルなDDE通信のクライアントとサーバーを作成するコードを紹介します。

概要

プログラム間でデータの受け渡しをする場合、ファイルでの受け渡しやパラメーターでの受け渡しなどがありますが、DDEを利用するとプログラム間で通信をして値の受け渡しができます。この記事ではDDEを利用したデータの送受信プログラムを作成します。

プログラム例

Windows Formアプリケーションを作成します。

事前準備: NDde のインストール

DDE通信を利用するためには、DDE通信のWindows APIを呼ぶ方法がありますが、NDdeというライブラリを使用するとWindows APIを直接呼び出さずにDDEを利用できます。

Visual Studio を起動し、Windows Formアプリケーションのプロジェクトを作成します。プロジェクト作成後[ツール]メニューの[NuGet パッケージマネージャー]の[パッケージ マネージャー コンソール]の項目をクリックします。

[パッケージ マネージャー コンソール]ウィンドウが表示されます。

下記のコマンドを入力して実行します。
Install-Package NDde

パッケージのインストールが始まります。

パッケージのインストールが完了すると下図の表示になります。

UI (サーバー)

サーバー側のプログラムです。
下図のUIを作成します。複数行のテキストボックスとボタンを1つ配置します。

コード (サーバー)

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NDde.Server;

namespace SimpleNDDEServer
{
  public partial class FormMain : Form
  {
    public FormMain()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      MyDDEServer mds = new MyDDEServer("Test Service");
      mds.Register();
      textBox1.Text += "Register \r\n";
    }
  }
}
MyDDEServer.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NDde.Server;

namespace SimpleNDDEServer
{
  public class MyDDEServer : DdeServer
  {
    public MyDDEServer(string service) : base(service)
    {
    }

    public override void Register()
    {
      base.Register();
    }

    public override void Unregister()
    {
      base.Unregister();
    }

    protected override bool OnBeforeConnect(string topic)
    {
      return true;
    }

    protected override void OnAfterConnect(DdeConversation conversation)
    {
    }

    protected override void OnDisconnect(DdeConversation conversation)
    {
    }

    protected override bool OnStartAdvise(DdeConversation conversation, string item, int format)
    {
      return format == 1;
    }

    protected override void OnStopAdvise(DdeConversation conversation, string item)
    {
    }

    protected override ExecuteResult OnExecute(DdeConversation conversation, string command)
    {
      return ExecuteResult.Processed;
    }

    protected override PokeResult OnPoke(DdeConversation conversation, string item, byte[] data, int format)
    {
      return PokeResult.Processed;
    }

    protected override RequestResult OnRequest(DdeConversation conversation, string item, int format)
    {
      string ret = "echo:"+item;
      RequestResult rr = new RequestResult(System.Text.Encoding.ASCII.GetBytes(ret));
      return rr;
    }

    protected override byte[] OnAdvise(string topic, string item, int format)
    {
      byte[] output = new byte[0];
      return output;
    }
  }
}

解説

フォームのボタンをクリックすると、MyDDEServerクラスのインスタンスを作成します。コンストラクタの引数にサービス名を与えます。作成されたインスタンスオブジェクトのRegister()メソッドを呼び出しサーバーを登録します。
  private void button1_Click(object sender, EventArgs e)
  {
    MyDDEServer mds = new MyDDEServer("Test Service");
    mds.Register();
    textBox1.Text += "Register \r\n";
  }

MyDDEServer.cs は DdeServer クラスを継承したカスタムクラスです。基底クラスのメソッドをオーバーライドで実装します。今回の例では、 OnRequest メソッドをオーバーライドして独自のロジックを実装します。クライアントからのリクエストで受け取った文字列の頭に"echo:"の文字列を追加した文字列をサーバーからのレスポンスとしてクライアントに返します。
  protected override RequestResult OnRequest(DdeConversation conversation, string item, int format)
  {
    string ret = "echo:"+item;
    RequestResult rr = new RequestResult(System.Text.Encoding.ASCII.GetBytes(ret));
    return rr;
  }

UI (クライアント)

下図のUIを作成します。複数行のテキストボックスとボタンを1つ配置します。

コード (クライアント)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NDde.Client;

namespace SimpleNDDEClient
{
  public partial class FormMain : Form
  {
    public FormMain()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      DdeClient client = new DdeClient("Test Service", "Test Topic");
      client.Connect();

      textBox1.Text += "Connection OK\r\n";

      byte[] data = client.Request("Hello", 1, 1000);

      textBox1.Text += "Request OK\r\n";

      string str_data = System.Text.Encoding.ASCII.GetString(data);

      textBox1.Text += str_data;
    }
  }
}

解説

DdeClientクラスのインスタンスを作成します。第一引数にサービス名を与えます。第二引数にトピック名を与えます。第一引数のサービス名はサーバー側で設定したサービス名と同じ名称にします。
作製したDdeClient オブジェクトのConnect()メソッドを呼び出しサーバーに接続します。
  DdeClient client = new DdeClient("Test Service", "Test Topic");
  client.Connect();

接続後、DdeClientオブジェクトのRequest()メソッドを呼び出し、メッセージをサーバーに送信します。第一引数に送信するメッセージ、第二引数にフォーマットの種類、第三引数にタイムアウトの時間を与えます。
Request()メソッドの戻り値にサーバーからのレスポンスが返ります。レスポンスのメッセージをテキストボックスに表示します。
  byte[] data = client.Request("Hello", 1, 1000);
  string str_data = System.Text.Encoding.ASCII.GetString(data);
  textBox1.Text += str_data;

実行結果

サーバー側のプログラムを起動します。下図のウィンドウが表示されます。


[button1]をクリックします。テキストボックスに "Register" のメッセージが表示されます。


サーバー側のプログラムが起動している状態で、クライアントプログラムを起動します。下図のウィンドウが表示されます。


クライアント側のウィンドウの[button1]をクリックします。下図のメッセージがテキストボックスに表示されます。送信したメッセージの先頭に"echo:"を追加したテキストがレスポンスとしてクライアントに返されていることがわかります。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
作成日: 2018-12-18
Copyright © iPentec all rights reserverd.