通知のフィルター処理と通信スタイル
このセクションでは、スプーラー プロセスと印刷プロセッサ、ドライバー、モニターなどの印刷コンポーネント間のインターフェイスについて説明します。
通知フィルタリング
PrintAsyncNotifyUserFilter 列挙型は、2 つの状況で使用されます。 これら 1 つ目では、スプーラー内で実行されている印刷コンポーネントが CreatePrintAsyncNotifyChannel 関数を呼び出して通知チャネルを作成します。 呼び出し元は、PrintAsyncNotifyUserFilter 列挙型の列挙子を 1 つ渡して、通知の受信を許可するリッスンしているクライアントを指定します。 2 番目の状況では、リッスンしているクライアントが RegisterForPrintAsyncNotifications 関数を呼び出して通知を登録します。 呼び出し元は、PrintAsyncNotifyUserFilter 列挙子のいずれかを渡して、受信する通知を示します。
typedef enum
{
kPerUser,
kAllUsers
} PrintAsyncNotifyUserFilter;
次の図では、kPerUser 列挙子が CreatePrintAsyncNotifyChannel 関数の呼び出しで使用されています。 その結果、登録を行ったユーザーと同じユーザー アカウントで実行されているリスナーのみが通知の受信を許可されます。
次の図では、kAllUsers 列挙子が CreatePrintAsyncNotifyChannel 関数の呼び出しで使用されています。 その結果、プリンターまたはサーバーに関心のあるすべてのリスナーが通知を受け取ることができます。 この関数の呼び出しで kAllUsers 設定を使用できるのは管理者のみであることに注意してください。
次の図は、RegisterForPrintAsyncNotifications 関数を呼び出して、呼び出しで kPerUser 列挙子を渡すことで、ユーザー 1 とユーザー 2 の両方が通知に登録している状況を示しています。 送信された 3 つの通知のうち、リスナー ユーザー 1 は、セッション 0 またはセッション 1 でユーザー 1 から通知を受信します。 リスナー ユーザー 2 は、セッション 2 でユーザー 2 から通知を受信します。
前の図に示すリッスンしているクライアントが RegisterForPrintAsyncNotifications を呼び出したが、今回は呼び出しで kAllUsers 列挙子を渡した場合、すべてのセッションのすべてのリスナーが 3 つの通知を受信したことになります。 この関数の呼び出しで kAllUsers 列挙子を使用できるのは管理者のみであることに注意してください。
管理者
管理者は、指定された印刷オブジェクトに対する PRINTER_ACCESS_ADMINISTER 権限を持つユーザーです。 管理者は誰にでも通知を送信でき、誰からでも通知を受け取ることができます。 通知フィルターは引き続き適用されることに注意してください。
次の図では、Joe は kPerUser を使用してチャネルに通知を送信します。 この列挙子に基づいてチャネルをフィルター処理された場合、通知はユーザー 1 (つまりセッション 1) に属するセッションにのみ送信する必要があります。 ただし、この通知はセッション 2 にも送信されます。そこに管理者はいて、この種類の通知をリスニングしているためです。 通知の種類が同じではないため、セッション 3 の管理者は通知を受信しないことに注意してください。
通信の種類の指定
通信の種類を指定することで、印刷コンポーネントは、リスナー クライアントからの応答が期待されるかどうか、および複数のクライアントから通知が返送されたときにスプーラーがケースを処理する方法を示します。
typedef enum
{
kBidirectional = 1,
kUnidirectional,
} PrintAsyncNotifyConversationStyle
通信には、一方向と双方向の 2 種類があります。 一方向の通信では、リッスンしているクライアントはスプーラー通知に応答しません。 この場合、リッスンしているクライアントは NULLIPrintAsyncNotifyChannel インターフェイス ポインターを受信するため、通知を送信できません。 双方向通信では、クライアントは通知を受信したときに応答を送信し、印刷コンポーネントとのダイアログを実行します。 これはUI 通知のケースです。
複数のセッションが UI 通知を受け取る状況はコメントに値します。 この場合、スプーラーはチャネルを開き、フィルターに一致するすべてのリスナーに通知し、最初の通知を送信します。 最初のリスナーが応答すると、スプーラーは他のチャネルを閉じ、ダイアログは最初のクライアントで続行されます。
登録済みのリッスンしているクライアントが応答する前に管理者 (たとえば) がログオンすると、管理者はリッスンしているクライアントと同じ UI 通知を受け取ります。
最初のユーザー (管理者など) が応答を送信すると、スプーラーは他のクライアントとの接続を "closed" としてマークします。他のリッスン しているクライアントが最終的に応答すると、"チャネルが閉じられた" メッセージを受信します。
通知の種類
通知の種類は、スプーラーが受け入れ、リスナー クライアントをフィルター処理するために使用する GUID です。 (ヘッダー ファイル Prnasnot.h の PrintAsyncNotificationType 型定義を参照してください)。スプーラー非同期通知メカニズムのクライアントは、独自の通知の種類を定義できます。 スプーラーは、送信される通知の種類の意味を認識しなくても、通知の種類に基づいてリスナー クライアントをフィルター処理します。
各通知には、通知データ型が関連付けられている必要があります。 この型は、通知データ スキーマを識別します。
通知データ型に加えて、チャネルに関連付けられている種類、通知チャネルの種類があります。 通知の送信者とリッスンしているクライアントは、さまざまな目的で通知チャネルの種類を使用します。
チャネルの送信者側では、印刷コンポーネントがチャネルを開いたときに、そのチャネルを介して送信する通知の種類を指定できます。 そのチャネルを通過するすべての通知は、通知チャネルの種類と同じ種類である必要があります。
スプーラーが適切なリッスンしているクライアントに送信する方法を "認識" できるように、送信者は常に型を通知に関連付ける必要があります。 リッスンしているクライアントは、独自のスキーマに従ってデータを検証する必要があります。 通知の種類によって、このスキーマが識別されます。
チャネルのリスナー側では、リッスンしているクライアントは、登録時に特定の通知データ型を指定することで、1 種類の通知の受信を要求できます。
スプーラーは、サービスまたはアプリケーションが死亡したことをリッスンしているクライアントに通知するために使用される特殊な通知の種類を定義します。
const GUID NOTIFICATION_RELEASE;
リッスンしているクライアントは、IPrintAsyncNotifyCallback::ChannelClosed メソッドが呼び出された場合にのみ、この種類のメッセージを受信できます。
通知登録ハンドル
クライアントが通知に登録すると、サーバー側スプーラーメインセキュリティ コンテキストなど、アプリケーションに関する情報を含む内部テーブルが含まれます。 通知登録ハンドルは、クライアントが受け取る不透明な構造です。
クライアントは、このハンドルを使用してのみ通知を受信するための登録を解除できます。