netail.net
自作フリーソフトや,ゲームに関する雑記を公開してます.
日記はソフトウェア工学の論文ネタが中心です.
最近のお知らせ (古いものはこちら)
2006-01-24 [長年日記] ▲
_ [VolumeDeskbar] さらに問題の修正 ▲
デスクバンド情報をウィンドウ側に通知するために IOleCommandTarget のポインタを取得していた(SetSite で渡ってくる引数を参照型変数に代入していた)のに,それを SetSite(nil) のときにきちんとその参照型変数を nil に戻してないのが,実はオブジェクトの解放がきちんとおきない原因だったらしい.
Microsoft が提供している Deskband.cpp のサンプルでは,こんな通知処理なんかはしてないので,気づかなかった.
たぶん,参照されている限り解放しない(カウントが0になった時点で自動解放)という賢いコードなのだろうけど,今回みたいな循環参照環境(バンドが,自身を格納するウィンドウへの参照を保持してしまう)では,どうしようもなかった.
結局,正解の手順は: CloseDWでウィンドウを解放(このときにTMixerのインスタンスも解放)しておく→SetSite(nil)呼び出しのときに,古いSiteオブジェクトへの参照をすべて捨てる→デスクバンドオブジェクトのデストラクタが呼ばれる.
CloseDWでウィンドウを解放し忘れると,TMixer のインスタンスが生き残ってしまい,ウィンドウ破棄後に音量変更のメッセージが無効なウィンドウハンドルに届いてしまいエラーになるし,SetSiteで古いSiteオブジェクトへの参照を解放しないと,オブジェクトのデストラクタが呼ばれないことになる.で,参照の解放というのは,Delphiの場合は単に参照変数に nil を代入するだけで良かったらしい.