Protocolsに準拠したDLLを作成し、それをレジストリに登録しました。DLLをロードさせて独自のデータを返すことができました。現在のアプリケーションで使用されるプロトコルを検出する方法を取り上げます。既存プロトコルの処理を変更したりできるようになります。そこにプロトコルを検出するオブジェクトを登録しなければなりません。インターネットセッションを表すIInternetSessionは、CoInternetGetSessionで取得できます。dwReserved);dwSessionModeは、予約されているため0を指定します。ppIInternetSessionは、IInternetSessionを受け取る変数のアドレスを指定します。dwReservedは、予約されているため0を指定します。IInternetSessionを取得したら、プロトコルを検出するオブジェクトをRegisterNameSpaceで登録できます。dwReserved);pCFは、IClassFactoryを実装したクラスオブジェクトを指定します。このオブジェクトのIClassFactory::CreateInstanceでは、IInternetProtocolを実装したオブジェクトを作成します。rclsidは、IInternetProtocolを実装したオブジェクトを識別するCLSIDを指定します。CLSID_NULLは指定するべきではないとされています。pwzProtocolは、検出したいプロトコルを表す文字列を指定します。たとば、httpの使用を検出したい場合はL"http:"を指定します。cPatternsは、使用されないため0を指定します。ppwzPatternsは、使用されないためNULLを指定します。dwReservedは、予約されているため0を指定します。次に、IInternetSession::RegisterNameSpaceを呼び出す例を示します。0);まず、CoInternetGetSessionでIInternetSessionを取得します。CClassFactoryという型のオブジェクトを事前に作成しています。これがどこか別の場所で使用されるようなことはないと思われます。http:を指定していることから、httpプロトコルの使用を検出したいことを意味します。検出が不要になった場合は、IInternetSession::UnregisterNameSpaceを呼び出すようにします。Monikersでhttpプロトコルが使用される場合にそれを検出し、HTTP通信を行います。言い換えれば、httpプロトコルをサポートする既定のオブジェクトと同じような動作を行います。ヘッダーファイル(protocol.h)を示します。0xa9}};続いて、ソースファイル(GUI関連)を示します。S_OK;}最後に、ソースファイル(IInternetProtocol関連)を示します。S_OK;}インターネットセッションを使用する場合においても、DLLを作成する場合と共通する処理は多くあります。最初に呼ばれるメソッドはIInternetProtocol::Startです。S_OK;}IInternetProtocolSinkはプロトコルの処理状況を伝えるために必要であるため、メンバとして保存しています。szUrlはプロトコルを含んだURLが格納されていますが、これも後で必要になるためメンバとして保存しています。Monikersを使用したアプリケーションがIBindStatusCallback::GetBindInfoで返したバインドフラグを取得するためです。CreateThreadで作成したスレッドでReportProtocolInfoを呼び出すようにしています。ReportProtocolInfoという自作メソッドの目的は、プロトコルの処理状況を伝えることです。キャッシュを使用するべきであることを意味します。今回は処理するプロトコルはhttpであり、このプロトコルのURLのキャッシュはGetUrlCacheEntryInfoで取得できます。2回目の呼び出しで実際にデータを取得します。この場合はGetProtocolDataという自作メソッドで実際にURLへアクセスします。これが成功すればキャッシュが存在するはずですから、GetUrlCacheEntryInfoを呼び出します。GetMimeTypeFromHeaderという自作メソッドは、キャッシュのヘッダー情報からMIMEタイプを取得します。Monikersを使用したアプリケーションのIBindStatusCallback::OnProgressが呼ばれます。キャッシュファイルの名前を指定する場合は、BINDSTATUS_CACHEFILENAMEAVAILABLEを指定します。MIMEタイプの通知は必須ではありませんが、ファイル名の通知は必須です。キャッシュを使用しない場合は、GetProtocolDataでデータを取得します。今回はhttpプロトコルを処理するため、WinINetを使用しています。その前にBINDSTATUS_FINDINGRESOURCEとBINDSTATUS_CONNECTINGを通知しています。現在URLを検索中であることや接続中であることが分かるようになります。これと同じ要領で、HttpSendRequestを呼び出す前でもリクエストの送信を示すBINDSTATUS_SENDINGREQUESTを通知しています。これもBINDSTATUS_VERIFIEDMIMETYPEAVAILABLEとして通知しています。このサイズだけバッファを確保してInternetReadFileを呼び出せば、バッファにデータが格納されます。2回目のInternetReadFileは、データがキャッシュに保存されるために呼び出しています。この場合はデータがキャッシュに保存されます。今回は使用していませんが、IInternetProtocolSinkにはSwitchというメソッドも用意されています。引数を通じてデータを渡すこともできます。このメソッドでS_OKを返した場合は、処理を一旦待機します。待機しているスレッドは起き上がりIInternetProtocol::Continueを実行します。仮にStart内でSwitchを呼び出しても、Continueが制御を返すまで制御を返しません。ワーカースレッドでSwitchを呼び出せば、Switchは直ちに制御を返します。