CD-ROMドライブの開閉イベント取得するには?

解決


まーく  2004-12-21 12:04:06  No: 12425

CD-ROM開閉イベントで色々と調べていたのですが、WM_DEVICECHANGEで取得
しようとしてもMsg.WParamを捕まえる事が出来ませんでした。
最初の1、2回うまく行えたのですが、実行出来ない時もあります。
ネットにて色々と調べましたが、関連記事が古い物でしたので Win2k 等
に対応していない可能性があると思い書き込ませて頂きました。
初投稿ですがどうか宜しくお願い致します。

当方の環境は「Delphi6 Pro UpdatePack2 (他RTL等)」と「Win2k SP4」です。

pravate
  procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE; 

procedure TForm1.WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
const 
  DBT_DEVICEARRIVAL = $8000;
  DBT_DEVICEREMOVECOMPLETE = $8004;
var
  Str: string;
begin
  inherited;
  case Msg.WParam of 
    DBT_DEVICEARRIVAL       : Str := 'CD Inseart';
    DBT_DEVICEREMOVECOMPLETE: Str := 'CD None';
  end; 
  ShowMessage(Str);
end;


まーく  2004-12-21 12:07:42  No: 12426

訂正します
誤「procedure TForm1.WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;」
正「procedure TForm1.WMDeviceChange(var Msg: TMessage);」
です。


平太  2004-12-21 18:44:28  No: 12427

WIN2KでもXPでもうまくいきますよ。
ただし、タイミングによってうまくいかないときがあるので、
私はintervalを2000に設定したタイマーを使ってその中で
判断させる(判断を遅らせる)ことで、うまくいくように
なりました。

ちなみに訂正された部分ですが、私は「誤」の方で、うまく
処理できてます。


jissou  2004-12-21 19:21:26  No: 12428

> 私は「誤」の方で、うまく処理できてます。

それは変。実装部に message 指令は書けないはず。


平太  2004-12-21 19:29:40  No: 12429

失礼。
Private宣言部と間違えました。


まーく  2004-12-22 02:00:33  No: 12430

平太様お返事有難う御座います。
タイマーを使ってうまく行えているようですが、
やはりタイミングの問題ですかね。
スレッドにて監視しても良いのですが、開閉イベント取得だけの為に
使うのもちょっと考えてしまいます。(^^;

各掲示板等も拝見させて頂きましたが、Win98時代の頃の物が多かった為
Win2k等にて別のAPIがあるのか??(^^;;;
と思ってました。

MS等で調べてたら以下のような記事がありました。
http://support.microsoft.com/default.aspx?scid=kb%3Bja%3B842473

「最終更新日2004年5月13日」と割と最近のようですが、記事には
「5 秒以上応答していないアプリケーションをハングアップとみなす」
「トップレベルのウィンドウを持つアプリケーションでWM_DEVICECHANGEを受け取れない」
と言う情報を見つけました。

PCの状態によってはうまく受け取れない?事になってしまうのでしょうか?
ご存知の方宜しくお願いします。

追伸:訂正の件でお騒がせ致しました。


りおりお  2004-12-22 03:21:54  No: 12431

正確には

ハングアップしたアプリのトップレベルのウィンドウでWM_DEVICECHANGEを受け取れない

とうことで、これはシステム側の事情を説明したものです。ハングアップしていると
いずれにしろ実際に受け取れないのですから、アプリ側で考慮する必要はありません。


まーく  2004-12-22 04:24:53  No: 12432

りおりお様お返事有難う御座います。
MS資料の
「ほかのトップレベルのウィンドウを持つアプリケーションでWM_DEVICECHANGE メッセージを受け取ることができません」
の「ほかの」とは、別のアプリ「自分自身以外(多の常駐アプリ等)がハングアップ」している場合も
受け取れない・・・と言う表現でしょうか?(^^;当方はそう思ってました

此方で確認した結果「OS起動直後(クリーンな状態)」ではメッセージを捕らえる事は出来ますが、
「4〜5時間(ネット等)」使っていると受け取れなくなるようで、その間に別アプリが応答なし
になるとメッセージが捕らえる事が出来ない物かと思ってました。(^^;

実際こういう場合にはどうしたら宜しいのでしょうか?(?_?結構ハマッてます


りおりお  2004-12-22 08:20:17  No: 12433

> 別のアプリ「自分自身以外(多の常駐アプリ等)がハングアップ」している場合も
> 受け取れない・・・と言う表現でしょうか?(^^;当方はそう思ってました

はい、そうです。BSF_NOHANG をフラグにセットして BroadcastSystemMessage を
実行すると、一つでもハングアップしたトップレベルウィンドウを持つアプリが
あると、それ以降のメッセージの送信を停止します。ということですね。

> 実際こういう場合にはどうしたら宜しいのでしょうか?

これはすみませんが知りません。

頻繁にハングアップするアプリがあるなら、そもそも起動しないようにすべきだ、
と思います。


まーく  2004-12-22 11:03:40  No: 12434

りおりお様、再び恐縮です。
やはり他のアプリがハングしてもそうなるのですね。

おっしゃるとうり、頻繁にハングするアプリがあるなら利用しない事に
こした事はありませんが、当方のマシンだけの環境なら良いのですが、
多のマシン(他の複数ユーザ)に使ってもらう事を前提にすると厳しいですね。(^^;

ちなみに、時々「応答なし」になるアプリは主要アプリである
「IE6」「インターネットセキュリティ」等のソフト
特にIEがホームページにより応答なしになります。
(試しにインターネットセキュリティをインストールしていないWin2k)でも同じです。
IEのバグかな?パッチ適用済ですが・・・

Broadcast にヒントがありそうなので「DEV_BROADCAST_HDR」について
調べてみます。


りおりお  2004-12-22 16:48:17  No: 12435

> Broadcast にヒントがありそうなので「DEV_BROADCAST_HDR」について
> 調べてみます。

わたしも調べてみました。CDROM の場合は、

The DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE events are 
automatically broadcast to all top-level windows for port devices. 
Therefore, it is not necessary to call RegisterDeviceNotification for ports

ということで、RegisterDeviceNotification を実行する必要がないようです。
したがって、やはりハングアップしたアプリがあると、メッセージをもらえない
ことがあり得ますね。タイマを使って定期的にチェックしに行く、とかが現実的
なのかもしれません。


まーく  2004-12-23 10:59:34  No: 12436

りおりお様、そちらでも調べて頂き大変有難う御座います。
当方でも色々と調べた結果やはりハングしたアプリがあると駄目のようです

最初に平太様からご指摘あったとうり定期的監視するのが適切かも知れません

CD-ROMとは関係有りませんが、WM_DEVICECHANGE(デバイスの変更)と言う事で
USBの事をふと考えてみると、Win側でもUSBデバイスの監視にはポーリング
処理を行っている事を考えると、定期的に見張るしかないのかもしれません。

Win側の仕様・・・と言う事で定期的に監視する事にします。

りおりお様、平太様色々と大変有難う御座いました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加