netail.net
自作フリーソフトや,ゲームに関する雑記を公開してます.
日記はソフトウェア工学の論文ネタが中心です.
最近のお知らせ (古いものはこちら)
2007-09-24 [長年日記] ▲
_ [Delphi][VolumeDeskbar] Vista 対応を進行中 ▲
もう少しで,いちおうの Vista,XP 両対応版を出せそうです.以前から利用させていただいている TMixer と,Vista 用の別実装を,自動で切り替える形式にしてます.
ただし,実験環境もなく,あまり投資する気力がないので,複数のデバイスから制御対象を選択する機能を Vista ではサポートせず,デフォルトの音量だけを制御対象としています.
今回,実装上で微妙にはまった点は,IAudioEndpointVolumeCallback によるコールバック時のメモリアクセス違反です.
いわゆるフックを使うとき,Windows プロセス内で動いてるフックのコードからはフックを仕掛けたアプリのプロセスの変数は見えないので,共有メモリとかを使って,通知を受け取るウィンドウのハンドルなどを共有しておく必要があります.
今回のコールバックでも,同様に共有メモリを使うようにするまで,うまく動きませんでした.独立EXEとして実験してみたら,何もしなくてもエラーにはならなかったので,explorer.exe の内部で動く都合か,何か別のところで問題があったのかもしれません.
_ [Delphi] Delphi の True は一部 API にとっては FALSE ▲
一部 Windows API では bool 値を LongInt 値で受け取るが,Delphi は True/Falseを「0以外(定数は-1)/0」で扱っているのに,APIは「0より大/0以下」で受け取るために食い違いが発生し,定数 True を渡しているつもりでも反応しないことがあります.
IAudioEndpointVolume.SetMute もその1つで,VolumeDeskbarの場合,インタフェース宣言をLongInt型で宣言することで回避しています.
BDS2006の場合,定数 True のコード補完時の表示情報は Boolean(1) なのに,BoolToStr(True)とかBoolToStr(LongBool(1)) の結果は -1 が出てくるので,基本的には LongInt で通さないと危険みたいです(私が知らないだけで他に賢い回避策があるのかもしれません).