前節では、オブジェクトを作成する方法とオブジェクトから送られる通知の種類について説明しました。今回は、作成したオブジェクトをコンテナがどのように扱っていくかについて見ていきます。WM_PAINTでオブジェクトを描画する処理を行います。した一連のオブジェクトの先頭はm_pSiteで識別されています。これをp->m_pNextとすることで次に参照するオブジェクトを決定します。次のような実装になっています。(HBRUSH)GetStockObject(BLACK_BRUSH));}OleDrawを呼び出すことで、オブジェクトのイメージを第4引数の位置に描画することができます。そのような時にはオブジェクトにハッチパターンを描画することが推奨されています。このハッチパターンというのは、ハッチブラシを割り当てた状態でRectangleを呼び出せば描画することができます。SetBkModeで透過描画に設定しておかないと、OleDrawの結果が完全に上書きされてしまうことに注意してください。選択されている場合はDrawFocusRectで点線の枠を描画します。選択されていない場合はFrameRectで黒い線の枠を描画します。ここで言う選択とはオブジェクトをクリックした状態のことを意味します。オブジェクトのウインドウを必要に応じて開いて、それを編集することです。このため、コンテナはオブジェクトを起動するための処理を用意しておく必要があります。通常、この起動はダブルクリックを通じて行われるため、WM_LBUTTONDBLCLKを検出することになります。このメッセージを検出するためには、ウインドクラスのクラススタイルにCS_DBLCLKSを指定しておかなければならないことに注意してください。0;}GetSiteFormPosという自作メソッドは、第1引数の位置に存在するオブジェクトを第2引数に返します。オブジェクトが返った場合は、RunObjectという自作メソッドを呼び出します。&m_rc);}サイトがIAdviseSinkを実装している場合は、IOleObject::Adviseを呼び出して自身のアドレスをオブジェクトに渡します。これにより、オブジェクトからの通知をIAdviseSinkで受け取ることができます。第2引数の値は登録を解除する際に必要になるため、メンバ変数に保存しておきます。IViewObject::SetAdviseを呼び出しているのは、オブジェクトの外観が変更された場合を検出するためです。これによって、コンテナ上に描画されているオブジェクトのイメージを更新することができます。IOleObject::DoVerbを呼び出せば、実際にオブジェクトを起動することができます。OLEIVERB_PRIMARYの場合はオブジェクト自身に決定させます。サイトがIOleInPlaceSiteを実装している場合は、インプレースアクティベーションが発生することになります。第2引数は、起動の元になったメッセージ(今回はWM_LBUTTONDBLCLK)のMSG構造体を指定できますがNULLで問題ありません。第3引数はサイトを指定するようにし、第4引数は0で構いません。今回の場合はNULLを指定しても構いません。作成したオブジェクトは、マウスで任意の位置へ移動できると便利であるといえます。これはマウスの左ボタンを通じて行われるべきものであるため、WM_LBUTTONDOWNを検出します。0;}GetSiteFormPosがTRUEを返したということは、第1引数の位置にオブジェクトが存在していることを意味します。選択したオブジェクト(移動中のオブジェクト)をメンバ変数に保存します。クリックした位置を記憶するためにSetClickPosという自作メソッドも呼び出しておきます。bChangeSelectは、今回のクリックによって選択されたオブジェクトが変化した場合にTRUEとなります。オブジェクトが存在しない場所をクリックした場合にTRUEとなります。ChangeSelectObjectという自作メソッドでそれを行います。マウスの移動時にオブジェクトの位置を移動させる必要があります。0;GetCaptureがNULLでない値を返した場合は、現在キャプチャが行われていることを意味します。MoveRectという自作メソッドを呼び出してオブジェクトの位置を更新します。マウスの左ボタンを離した場合は、WM_LBUTTONUPが送られます。ReleaseCaptureを呼び出してマウスのキャプチャを解除します。移動中のオブジェクトがなくなったということで、m_pSiteMovingにNULLを格納します。オブジェクト上でマウスの右ボタンが押された場合は、ポップアップメニューを表示することになります。0;}まず、対象となるオブジェクトを選択状態にし、次にp->AddVerbMenuで初期化したポップアップメニューをTrackPopupMenuで表示します。AddVerbMenuの実装は次のようになっています。&hmenuTmp);}ポップアップメニューに追加すべき項目は、オブジェクトがサポートするVerb(実行できるコマンド)でなければなりません。Verbの取得もメニュー項目の作成もまとめて行うことができます。第4引数はオブジェクトに関する項目をメニューのどの位置に追加するかであり、先頭でよいのであれば0で問題ありません。第5引数は追加する最初の項目のIDであり、2つ目以降の項目はこのIDを加算していったものになります。そのIDは第6引数を超えることはありません。「編集」と「開く」という2つの項目を確認できるはずです。「編集」という項目のIDは0になり、「開く」という項目のIDは1になります。項目が選択された場合は、WM_COMMANDが送られます。項目のIDをRunObjectに指定します。これにより、内部でIOleObject::DoVerbが実行されることになります。OleUIInsertObjectの呼び出し以外にも存在します。IDataObjectを持っている場合はOleCreateFromDataを呼び出すことができます。例として、D&Dされたファイルを埋め込む方法を取り上げます。0;}アプリケーションがDragAcceptFilesを呼び出していれば、ファイルがドロップされた際にWM_DROPFILESが送られます。このファイルパスをInsertObjectに指定して埋め込みを行います。TRUE;}このInsertObjectの実装は基本的に前節と同じですが、ファイルパスが指定された場合はOleCreateFromFileを呼び出しています。これが成功した場合はIOleObjectを取得することができますから、後の処理はダイアログでオブジェクトを埋め込んだ場合と同様になります。