サーバーの作成これまでExcelを対象にDDEクライアントを作成してきましたが、今回はDDEサーバーを作成することにします。アプリケーション名やトピック名、アイテム名なども決定しなければなりません。トピック名については必ずsystemという名前のトピックをサポートしなければなりません。統一した方法でサーバーの情報を取得できる利点が生まれます。次に、systemトピックがサポートできるアイテム名を指定します。サーバーがサポートするクリップボードフォーマットのリスト。サーバーの使い方を簡単に示したテキスト。最近使われたWM_DDE_ACKの詳細。サーバーの現在の状態を示す文字列。サーバーがサポートするsystemトピックのアイテム名のリスト。systemトピックの以外のトピックがサポートするアイテム名のリスト。トピック名として指定可能な文字列のリスト。WM_DDE_REQUESTに上記のアイテム名を指定してデータを取得できる可能性があります。SysItemsでサポートしているアイテム名を知るようにすればよいでしょう。データを返す際の形式については既存のアプリケーションを参考にしてください。Excelに対してSysItemsを要求すると、サポートするアイテム名がタブで区切られて返されます。アイテム名を定数として扱いたい場合は、ddeml.hに定義されたSZDDESYS_TOPICなどを使用します。このチェックボックスの状態の取得や設定をサポートします。ユーザーによってチェックされた際には、それをクライアントに通知します。bResult;}サーバーが何らかの動作を行うようになるのは、クライアントからのDDEメッセージを受信したときです。各メッセージの処理を順に見ていきます。0;}WM_DDE_INITIATEは、クライアントがサーバーとの対話を望んでいる場合に送られます。WM_DDE_ACKをクライアントに返すようにします。サーバーはトピック名としてmy-topicをサポートしているため、my-topicを指定しています。lParamが0である場合は応答するかどうか自由ですが、今回は応答するようにしています。サーバーと対話するクライアントは1つでなければなりません。MSDNにも掲載されている正しい方法であると思います。既存のDDEサーバーはGlobalDeleteAtomを呼び出す設計になっていないようです。グローバルアトムテーブルに格納されたアプリケーション名やトピック名が削除されない問題があります。これはExcelの終了時でも削除されないようです。WM_DDE_REQUESTの処理は次のようになっています。0;}WM_DDE_REQUESTは、クライアントがデータを要求する際に送られます。これらがサーバーのアイテムと一致するかをIsSupportItemで確認します。一致しない場合はWPARAMに0を指定してWM_DDE_ACKを返します。グローバルアトムはWM_DDE_DATAやWM_DDE_ACKでも必要になるため、削除せず使いまわすようにしています。IsSupportItemの内部は次のようになっています。0;}今回のサーバーにおけるアイテムとは、チェックボックスのことであり、check"という名前を持つものとします。フォーマットはCF_TEXTでなければなりません。続いて、PostDataの内部を確認します。今回の場合Valueメンバにはtrueまたはfalseという文字列を指定することになります。BM_GETCHECKをチェックボックスに送信しています。0;}WM_DDE_POKEは、クライアントがデータを設定する際に送られます。SetDataという自作関数でデータを設定するようになります。成功した場合は0x8000、失敗した場合は0をWPARAMに指定します。SetDataの内部は次のようになっています。falseである場合はチェックを外すようにします。trueでもfalseでもない場合は、データの設定が失敗したとみなします。0;}WM_DDE_ADVISEは、クライアントがデータの変更を検出したい場合に送られます。サポートしているアイテムを確認したら、データリンクの確立を示すbAdviseをTRUEにします。この状態でチェックボックスの状態が変化したら、データの変更をクライアントに通知するようにします。これは通知の際に必要になるため保存しておきます。fAckReqの値も保存しておくようにします。0;}チェックボックスの状態の変化した場合は、WM_COMMANDが通知されます。WM_DDE_DATAを送ることになります。ホットリンクの場合はデータそのものを送ることになります。0;}WM_DDE_UNADVISEは、クライアントがデータの通知が不要になった際に送られます。WM_DDE_ACKを処理できない可能性もあります。よって、今回はWM_DDE_ACKを返さないようにしています。0;WM_DDE_TERMINATEは、クライアントがサーバーとの対話を終了する際に送られます。hwndClientDDEをNULLで初期化しても問題ありません。今回作成したサーバーに対するクライアントを次に示します。右ボタンが押された場合はチェックボックスにチェックを付けます。ユーザーによってサーバーのチェックボックスが変更された場合は、それを検出します。TEXT("DDE対話の確立に失敗しました。TEXT("データの変更が通知されました。bResult;}コード量は多いですが、基本的にはこれまでのプログラムのコードを混ぜ合わしているだけです。この流れは前節と全く同じです。サーバーのアプリケーション名やトピック名、アイテム名などは、今回のサーバーと同じ値を指定するようにします。データをWM_DDE_DATAで受け取っていますが、この処理も以前に示した通りです。この処理も以前に示した通りです。