DIRECTX1 DirectPlay3 サービスプロバイダを列挙して選択させる

次にどのネットワークを使って接続するか、決定しなければなりません。どのネットワークを使用することができるのか、一覧を取得します。それをユーザが選び、選んだネットワークで接続を開始します。ネットワークにはTCP/IPや、IPX,シリアル接続、イーサネットLANなどがあります。それぞれの接続担当プログラムをサービスプロバイダと呼びます。使用可能なネットワークを取得して表示することを「サービスプロバイダを列挙する」といいます。これはネットワークの用語なんでしょうか、マイクロソフトの用語なんでしょうか。分かりにくい単語です。

サービスプロバイダを列挙するわけですが、どこに列挙すれば良いでしょうか。ボタンをならべて一つ一つにサービスプロバイダの名前を表示しても良いし、コンボボックスに表示してもかまいません。Formに直接描いても良いのですが、あとでそれを選択しなければなりません。番号で指定するのか、名前を選択するのか、ボタンを押すのか。なんでも構わないのですが、ここではわかりやすいようにリストボックスを使うことにします。サービスプロバイダの列挙には、コールバック関数を使うので、表示にどのような方法を使うかによって書きかがが違ってきます。他のやり方をする場合は気をつけてください。

メンバ関数です。
 

HRESULT CDxPlay::DxEnumProvider(CListBox* listbox)
{
 
// lpDirectPlay4A->EnumConnections(NULL, DirectPlayEnumCBack, hDlg, 0);
HRESULT ret = lpDP4A->EnumConnections(NULL, DirectPlayEnumCBack, listbox, 0);
if(ret == DP_OK){
 AfxMessageBox("プロバイダの列挙に成功しました");
 return DP_OK;
}
AfxMessageBox("プロバイダの列挙に失敗しました");
}
 

メンバ関数に渡す、DirectPlayEnumCBack関数です。これはグローバルで作ります。
 

BOOL
CALLBACK
DirectPlayEnumCBack(LPCGUID lpguidSP,
 LPVOID lpConnection,
 DWORD dwConnectionSize,
 LPCDPNAME lpName,
 DWORD dwFlags,
 LPVOID lpContext)
{
int num;
 
CListBox* listbox = (CListBox*) lpContext;
 
// 名前をリストボックスで表示する
listbox->AddString(lpName->lpszShortNameA);
 
// connections = (Connections*)lpContext;
num = connections.numConnections;
 
// コネクション情報を保存する
connections.lpConnections=(LPVOID*)realloc(connections.lpConnections,
sizeof(LPVOID)*(num+1));

connections.lpConnections[num]=(LPVOID)malloc(dwConnectionSize);
memcpy(connections.lpConnections[num],lpConnection,dwConnectionSize);
// サービスプロバイダ名を保存する
connections.lpDPNAME=(LPDPNAME*)realloc(connections.lpDPNAME,
sizeof(LPDPNAME)*(num+1));
 
connections.lpDPNAME[num]=(LPDPNAME)malloc(sizeof(DPNAME));
memcpy(connections.lpDPNAME[num],lpName,sizeof(DPNAME));
 
num++;
connections.numConnections=num;
 
return TRUE;
}
 

ちなみに宣言の

BOOL
CALLBACK
DirectPlayEnumCBack(LPCGUID lpguidSP,
 LPVOID lpConnection,
 DWORD dwConnectionSize,
 LPCDPNAME lpName,
 DWORD dwFlags,
 LPVOID lpContext)

は、

BOOL CALLBACK DirectPlayEnumCBack(LPCGUID lpguidSP,LPVOID lpConnection, DWORD dwConnectionSize, LPCDPNAME lpName, DWORD dwFlags, LPVOID lpContext)

とかわりませんん、念のため。

あと必要な変数は、グローバル変数の   

Connections connections;   これは  hEvent の下に定義してください。

それと

typedef struct{
 LPVOID *lpConnections;
 LPDPNAME *lpDPNAME;
 int numConnections;
}Connections;


という構造体を宣言してください。これはCDxPlay.hの先頭の方に書きます。

以上で必要なコーディングは全部です。ボタンのハンドルから

  dxp.DxEnumProvider(&m_List1);

と呼び出しを追加して、ビルド、実行して見てください。

m_List1は、リストボックスのメンバ変数です。無ければ追加しましょう。以下のように表示されればOKです。