レガシー Windows API(概要)について

ここで紹介しているAPIは、Windows95、Windows NT3.5時代のAPI群であり、最新のAPIは含まれていないことに注しして欲しい。なお、当時の解説書は現在よりもより詳細に解説しているため、参考になるはずである。

  • レイアウトを変換する際、崩れているページがあります。
  • 概要およびSampleコードはありますが、APIの解説はありません。

ご要望があれば旧版のWin32 API(HELP形式)をお譲りします。問い合わせフォームより申し込みください。

Windows API メールスロットの概要

「メールスロット」とは、 単方向プロセス間通信を実現するための機構です。Microsoft(R) Windows(TM) 用のアプリケーションは、 メッセージをメールスロットに格納できます。メールスロットのオーナーは、 メールスロットに格納されているメッセージを取得できます。通常、 メールスロット メッセージは、 ネットワークを通じて、 特定のコンピュータや特定のドメイン内のすべてのコンピュータに送られます。「ドメイン」とは、 同じグループ名のワークステーションやサーバーのグループです。

次に示すトピックでは、 メールスロットについて説明しています。

メールスロットの名前

メールスロットとLAN Manager

サーバー関数とクライアント関数

メールスロットの作成

メールスロットへの書き込み

メールスロットからの読み取り

メールスロット関数

メールスロットはメモリ内に存在する疑似ファイルであり、 Windowsの標準ファイル関数で書き込むことができます。しかし、 ディスク上のファイルとは異なり、 メールスロットは、 一時的なものです。メールスロットのハンドルをすべてクローズすると、 メールスロットとそれに含まれるデータはすべて削除されます。メールスロット メッセージ内のデータの形式に制限はありません。

「メールスロット サーバー」とは、 メールスロットを作成して所有するプロセスです。メールスロットを作成したサーバーは、 メールスロット ハンドルを受け取ります。このハンドルは、 メールスロットからメッセージを読み取るときに使います。メールスロットからメッセージを読み取れるのは、 メールスロットを作成したプロセス (または継承などの機構によってメールスロットのハンドルを取得したプロセス) だけです。メールスロットは、 サーバー ハンドルをすべてクローズするか、 サーバー プロセスがすべて終了するまで存在します。メールスロットは、 すべて、 メールスロットを作成したプロセスにローカルです。プロセスはリモート メールスロットを作成できません。

「メールスロット クライアント」とは、 メールスロットにメッセージを書き込むプロセスです。プロセスは、 メールスロットの名前を知っていれば、 そのメールスロットにメッセージを置くことができます。新しいメッセージは、 メールスロットにすでに存在するメッセージの後に追加されます。

メールスロットは、 ドメイン内にメッセージをブロードキャストできます。ドメイン内の複数のプロセスが同じ名前のメールスロットをそれぞれ作成した場合は、 そのメールスロット宛てにドメインに送られたすべてのメッセージは、 メールスロットを所有する各プロセスに渡されます。メールスロットを書き込み操作用にオープンしたときは、 1つのプロセスがサーバー メールスロット ハンドルとクライアント ハンドルの両方を制御できるため、 ドメイン内での簡単なメッセージ受渡し機能を容易に実現できます。

場合によっては、 メールスロットではなく名前付きパイプを使ってプロセス間通信 (IPC) を行うこともあります。名前付きパイプを使えば2つのプロセス間でメッセージを簡単にやり取りできますが、 多くのプロセスにメッセージをブロードキャストする場合は、 メールスロットの方が便利です。

また、 メールスロットと名前付きパイプの選択に関しては、 もう1つ注意点があります。メールスロットはデータグラムを使っていますが、 名前付きパイプはデータグラムを使っていません。データグラムとは、 ネットワークで送られる情報の小さなパケットです。データグラムには、 ラジオやテレビの放送と同様に、 受け取りを確認する手段がなく、 相手がデータグラムを受け取ったかどうかは保証されません。データの受け取りの保証が必要ならば、 名前付きパイプを使ってください (ただし、 ブロードキャストはできません)。メールスロットには受け取りの保証はありませんが、 ブロードキャストができます。

メールスロットの名前

メールスロットを作成するときは、 次に示す形式のメールスロット名を使ってください。

\\.\mailslot\[path]name

メールスロット名には、 名前の先頭の2つの円記号 (\)、 ピリオド、 その後の円記号、 mailslotという単語、 その後の円記号が必要です。大文字と小文字は区別されません。メールスロット名の前には、 疑似ディレクトリの名前で構成されるパスを円記号で区切って付けることもできます。たとえば、 Bob、 Pete、 Sueからの税金に関するメッセージを受け取るため、 ユーザーが各送り側についてそれぞれメールスロットを作成できるようにすることもできます。

\\.\mailslot\taxes\bobs_comments
\\.\mailslot\taxes\petes_comments
\\.\mailslot\taxes\sues_comments

メールスロットにメッセージを置くには、 何種類かのうちのいずれかの形式の名前でメールスロットをオープンします。ローカル コンピュータのメールスロットに書き込むときは、 メールスロットを作成するときと同じ形式のメールスロット名が使えます。しかし、 そのような場合は多くありません。通常は、 次に示す形式を使って、 特定のリモート コンピュータのメールスロットに書き込みます。

\\computername\mailslot\[path]name

特定の名前のドメイン内のすべてのメールスロットにメッセージを置くには、 次に示す形式を使います。

\\domainname\mailslot\[path]name

システムのプライマリ ドメインの特定の名前のメールスロットすべてにメッセージを置くには、 次に示す形式を使います。

\\*\mailslot\[path]name

メールスロットとMicrosoft LAN Manager

Windowsは、 Microsoft LAN Managerバージョン2.0用に開発されたメールスロットに似たメールスロットを使います。LAN Manager 2.xのメールスロットを使用するアプリケーションは、 Windowsが作成したメールスロットにも簡単に対応できます。しかし、 WindowsのメールスロットとLAN Managerのメールスロットには、 次に示すような大きな違いがいくつかあります。

Windowsのメールスロットのクラスはすべて同じです。「第1クラス」や「第2クラス」のメールスロットはありません。

Windowsのメールスロット メッセージの優先順位はすべて同じで、 メッセージは常にメールスロット バッファの終端に追加されます。メッセージの優先順位を必要とするコンピュータのメールスロットに Windowsのメールスロット メッセージを書き込むときは、 システムは、 優先順位を最低 (0) に設定します。

ローカル コンピュータのWindowsメールスロットへの書き込み操作では、 エラーが発生するとエラー値が返されます。リモートWindowsメールスロットへの書き込み操作では、 失敗してもエラー値は返されません (メールスロット バッファのサイズには既定の制限はないため、 操作が失敗することはまれです)。

(バッファが小さすぎるときなど) メールスロット バッファにメッセージを追加できないときは、 Windowsメールスロットへの書き込み操作は即座に失敗します。失敗かどうかが即座にわかるため、 書き込みタイム アウトは無関係です。Windowsメールスロットでは、 LAN Managerメールスロットとは異なり、 書き込みタイム アウトはありません。

Windowsメールスロットを作成するときに、 子プロセスがそのメールスロット ハンドルを継承するように指定できます (LAN Managerのメールスロット ハンドルは継承できません)。

Windowsメールスロットにメッセージを書き込むには、 標準ファイル入出力関数を使います。LAN Managerのメールスロット関数とそれに対応するWindowsの関数を次の表に示します。

LAN Managerの関数 Windowsの関数

DosDeleteMailslot CloseHandle

DosMailslotInfo GetMailslotInfo

DosMakeMailslot CreateMailslot

DosReadMailslot ReadFile

DosWriteMailslot WriteFile

サーバー関数とクライアント関数

メールスロットを操作するクライアントとサーバーは、 この項で説明する関数だけを使ってください。ほかのWindows関数は、 ファイル ハンドルやファイル名を引数に取るものでも、 使わないでください。

サーバー関数

次の表に示す3つの関数は、 メールスロット サーバーだけが使います。

関数 説明

CreateMailslot メールスロットを作成し、 メールスロット ハンドルを返します。

GetMailslotInfo メッセージの最大サイズ、 メールスロットのサイズ、 メールスロットの次のメッセージのサイズ、 メールスロット内のメッセージ数、 読み取り操作でメッセージを待機するときの時間を取得します。

SetMailslotInfo メールスロットの読み取りタイム アウトを変更します。

また、 メールスロット サーバーは、 次に示す関数も使います。

関数 説明

DuplicateHandle メールスロット ハンドルを複製します。

ReadFile メールスロットからメッセージを取得します。

GetFileTime メールスロットの作成日時を取得します。

SetFileTime メールスロットの作成日時を設定します。

クライアント関数

クライアント関数は、 次に示す関数を使ってメールスロットを操作できます。

関数 説明

CloseHandle クライアント プロセスのメールスロット ハンドルをクローズします。

CreateFile クライアント プロセス用のメールスロット ハンドルを作成します。

DuplicateHandle メールスロット ハンドルを複製します。

WriteFile メールスロットにデータを書き込みます。

メールスロットの使用

ここでは、 次の処理を実行する方法を説明します。

メールスロットの作成

メールスロットへの書き込み

メールスロットからの読み取り

メールスロットの作成

Windowsのメールスロットは、 CreateMailslot GetMailslotInfoSetMailslotInfoの3つの専用関数でサポートされます。これらの関数は、 メールスロット サーバーが使います。

次に示すコード例は、 CreateMailslot関数を使って、 sample_mailslotという名前のメールスロットのハンドルを取得します。

BOOL FAR PASCAL Makeslot(HWND hwnd, HDC hdc)
{
LPSTR lpszSlotName = "\\\\.\\mailslot\\sample_mailslot";

/* The mailslot handle "hSlot1" is declared globally. */

hSlot1 = CreateMailslot(lpszSlotName,
0,/* no maximum message size*/
MAILSLOT_WAIT_FOREVER,/* no time-out for read operations */
(LPSECURITY_ATTRIBUTES) NULL); /* no security attributes*/

if (hSlot1 == INVALID_HANDLE_VALUE) {
ErrorHandler(hwnd, "CreateMailslot"); /* local error handler */
return FALSE;
}

TextOut(hdc, 10, 10, "CreateMailslot successful.", 26);
return TRUE;
}

子プロセスが継承するメールスロットを作成するには、 CreateMailslotの最後のパラメータとして渡すSECURITY_ATTRIBUTES構造体を変更してください。この構造体のbInheritHandleメンバにTRUEを設定してください (デフォルト設定はFALSEです)。

メールスロットへの書き込み

メールスロットへの書き込みは通常のディスク ファイルへの書き込みに似ています。次に示すコードは、 CreateFile関数、 WriteFile関数、 CloseHandle関数を使って、 短いメッセージをメールスロットに置きます。メッセージは、 システムのプライマリ ドメインのすべてのコンピュータにブロードキャストされます。

LPSTR lpszMessage = "Message for sample_mailslot in primary domain.";
BOOL fResult;
HANDLE hFile;
DWORD cbWritten;

hFile = CreateFile("\\\\*\\mailslot\\sample_mailslot"_
GENERIC_WRITE,
FILE_SHARE_READ, /* required to write to a mailslot */
(LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);

if (hFile == INVALID_HANDLE_VALUE) {
ErrorHandler(hwnd, "Primary domain"); /* local error handler */
return FALSE;
}

fResult = WriteFile(hFile,
lpszMessage,
(DWORD) lstrlen(lpszMessage) + 1, /* include terminating null character */
&cbWritten,
(LPOVERLAPPED) NULL);

if (!fResult) {
ErrorHandler(hwnd, "WriteFile");
return FALSE;
}

TextOut(hdc, 10, 10, "WriteFile successful.", 21);

fResult = CloseHandle(hFile);

if (!fResult) {
ErrorHandler(hwnd, "CloseHandle");
return FALSE;
}

TextOut(hdc, 10, 30, "CloseHandle successful.", 23);
return TRUE;

ドメインにブロードキャストするメッセージの長さは、 400バイト以下でなければなりません。ブロードキャストしないメッセージの長さは64Kバイト未満でなければなりません。1つのメールスロットに送ることができるメッセージの個数には制限はありません。

メールスロットからの読み取り

メールスロットを作成したプロセスは、 メールスロット ハンドルを指定してReadFile関数を呼び出すことによって、 メールスロットからメッセージを読み取れます。次の例のコードは、 GetMailslotInfo関数を呼び出してメールスロットにメッセージがあるか調べます。メッセージが待機中ならば、 各メッセージを残りメッセージ数とともにメッセージ ボックスに表示します。

BOOL FAR PASCAL Readslot(HWND hwnd, HDC hdc)
{
DWORD cbMessage, cMessage, cbRead;
BOOL fResult;
LPSTR lpszBuffer;
CHAR achID[80];
DWORD cAllMessages;

cbMessage = cMessage = cbRead = 0;

/* Mailslot handle "hSlot1" is declared globally. */

fResult = GetMailslotInfo(hSlot1, /* mailslot handle*/
(LPDWORD) NULL,/* no maximum message size */
&cbMessage, /* size of next message*/
&cMessage,/* number of messages*/
(LPDWORD) NULL);/* no read time-out*/

if (!fResult) {
ErrorHandler(hwnd, "GetMailslotInfo");
return FALSE;
}

if (cbMessage == MAILSLOT_NO_MESSAGE) {
TextOut(hdc, 10, 10, "No waiting messages.", 20);
return TRUE;
}

cAllMessages = cMessage;

while (cMessage != 0) {/* retrieves each message*/

/* Create a message-number string. */

wsprintf((LPSTR) achID,
"\nMessage #%d of %d\n", cAllMessages - cMessage + 1,
cAllMessages);

/* Allocate memory for the message. */

lpszBuffer = (LPSTR) GlobalAlloc(GPTR,
lstrlen((LPSTR) achID) + cbMessage);

lpszBuffer[0] = '\0';

fResult = ReadFile(hSlot1,
lpszBuffer,
cbMessage,
&cbRead,
(LPOVERLAPPED) NULL);

if (!fResult) {
ErrorHandler(hwnd, "ReadFile");
GlobalFree((HGLOBAL) lpszBuffer);
return FALSE;
}

/* Concatenate the message and the message-number string. */

lstrcat(lpszBuffer, (LPSTR) achID);

/* Display the message. */

MessageBox(hwnd,
lpszBuffer,
"Contents of Mailslot",
MB_OK);

GlobalFree((HGLOBAL) lpszBuffer);

fResult = GetMailslotInfo(hSlot1, /* mailslot handle*/
(LPDWORD) NULL,/* no maximum message size */
&cbMessage,/* size of next message*/
&cMessage,/* number of messages*/
(LPDWORD) NULL);/* no read time-out*/

if (!fResult) {
ErrorHandler(hwnd, "GetMailslotInfo");
return FALSE;
}
}
return TRUE;
}

メールスロットは、 オープンされているすべてのサーバー ハンドルに対してCloseHandle関数が呼び出されるか、 メールスロット ハンドルを所有するサーバー プロセスがすべて終了するまで存在します。どちらの場合も、 未読のメッセージがメールスロットから削除され、 メールスロットを識別するクライアント ハンドルはすべてクローズされます。また、 メールスロット自体もメモリから削除されます。

メールスロット関数

メールスロットに関する関数を次に示します。

CreateMailslot

GetMailslotInfo

SetMailslotInfo

マルチメディア製造元IDおよびプロダクトID

はじめに

この付録では、 Microsoft(R) Windows(TM) で現在使われているマルチメディアの製造者IDと製品IDのリストを示します。Windows用のマルチメディア製品を開発する製造者が増えれば、 このリストも大きくなります。

Multimedia Extensionsの製造者IDと製品IDの現在のリストを入手したり、 新しいIDを登録するには、 次に示すグループから『Multimedia Developer Registration Kit』を入手してください。

Microsoft Corporation

Multimedia Systems Group

Product Marketing

One Microsoft Way

Redmond, WA 98052-6399

製造者ID

Multimedia Extensionsの現在の製造者IDを次に示します。

定数説明

MM_MICROSOFT1Microsoft Corporationが開発したドライバ

製品ID

Multimedia Extensionsの現在の製品IDを次に示します。

定数説明

MM_MIDI_MAPPER1Microsoft MIDIマッパー

MM_SNDBLAST_MIDIOUT3Sound Blaster MIDI出力ポート

MM_SNDBLAST_MIDIIN4Sound Blaster MIDI入力ポート

MM_SNDBLAST_SYNTH5Sound Blaster内部シンセサイザ

MM_SNDBLAST_WAVEOUT6Sound Blasterウェーブフォーム出力ポート

MM_SNDBLAST_WAVEIN7Sound Blasterウェーブフォーム入力ポート

MM_ADLIB9Ad Lib (またはAd Lib互換) シンセサイザ

MM_MPU401_MIDIOUT10Roland MPU-401 MIDI出力ポート

MM_MPU401_MIDIIN11Roland MPU-401 MIDI入力ポート

MM_PC_JOYSTICK12IBM Game Control Adapter

▲ページトップに戻る

【本を読んでもよくらからない】 … 個別指導でわかりやすくお教えします