XP辺りから以降のOSでは通常CDの交換やUSBメモリを接続すると自動実行の
動作選択ダイアログが表示されますが、例えばウォークマン用のアプリケーションの
「x-アプリ」等が起動しているとCDの交換やUSBメモリを接続しても動作選択
ダイアログが表示されることがありません。これはどうゆう方法で実現しているのか
ご存知の方はいらっしゃいませんか?
使用している言語がVC++なのでこちらで質問させていただきました。
「Windows 自動実行 API」で検索すると…
http://social.msdn.microsoft.com/Forums/ja/csharpgeneralja/thread/cd234d76-dbb7-4dbf-b10e-adadfb4c7d7a
とか見つかります。
さらに「QueryCancelAutoPlay」で検索すると…
http://www.wildtree.jp/~araki/rakugaki/2006/01/usb-select-1.html
http://d.hatena.ne.jp/twhs/20080207/1202391389
http://www.logsoku.com/r/tech/1163375772/183-184
とかが見つかります。
やったことはありませんけどね。
瀬戸っぷ氏のコメントの最初のショートカットのとび先の文章の中に
////////////////////////////////////////////
アプリケーション全体でやるなら、
public class DisableAutoPlay : IMessageFilter
{
/// <summary>DisableAutoPlay を登録し、AutoPlay を無効にする</summary>
public static void Install()
{
Application.AddMessageFilter(new DisableAutoPlay());
}
// RegisterWindowMessage API を登録
[DllImport(USER32.DLL, SetLastError=true)]
private static extern int RegisterWindowMessage(string ident);
// RegisterWindowMessage を使用して QueryCancelAutoPlay を取得
private static int QueryCancelAutoPlay = RegisterWindowMessage
(QueryCancelAutoPlay);
bool IMessageFilter.PreFilterMessage(ref Message m)
{
// AutoPlay をキャンセルする
if (m.Msg == QueryCancelAutoPlay)
{
m.Result = new IntPtr(-1);
return true;
}
return false;
}
}
////////////////////////////////////////////
以上のようなソースがあるのですが、VC++6.0で実装するにはどうすれば良いの
でしょうか?
QueryCancelAutoPlayをメッセージ登録するのはいいのですが、アプリケーション全体
でメッセージをトラップする方法がわかりません。
うーーん、
QueryCancelAutoPlay自体VC++標準のものではないようなので、sivaさん
が望んでるような自動で登録するようなメッセージではなさそうですね。
瀬戸っぷさんの紹介されたサイトを手がかりに調べていくしかなさそうに見えます。
QueryCancelAutoPlayはウィンドウズが起動した時点でシステムがユーザー定義メッセー
ジを既に定義済みであり、アプリケーションでは
UINT msg = RegisterWindowMessage(QueryCancelAutoPlay);
で定義済みのメッセージIDをもらってくれば良いと認識しております。
で、問題なのはIMessageFilter関連の部分ですが、調べてみても C# 及び .NET 関連の
ページにしかたどり着けずVC++6.0で使う方法がわかりません。
ヘッダーファイル内にIMessageFilterインターフェイスの定義は見つけましたが、
インターフェイスの取得や使用方法がわかりません。
グローバルメッセージフックを作って処理してしまえばいいんでしょうか?
ちなみに前述の「x-アプリ」ですが、該当アプリが非アクティブでない状態でも自動実
行はブロックされていましたし、該当アプリ起動中にレジストリを除いてもレジストリ
は書き換わっていないようなのでこれもメッセージフック処理をしているのかなと考え
ております。
>で、問題なのはIMessageFilter関連の部分ですが、調べてみても C# 及び .NET 関連の
>ページにしかたどり着けずVC++6.0で使う方法がわかりません。
掲示のページではC#などが対象のコードで掲示されているので、
VC++6.0ではそのままでは無理でしょう。
自作アプリなどのWndProc()等でRegisterWindowMessage(QueryCancelAutoPlay)の値と
比較して処理する。
ということになるかと。
# MFCのメッセージハンドラに登録して、OnQueryCancelAutoPlay()みたいなのは無理かと
思われます。
>グローバルメッセージフックを作って処理してしまえばいいんでしょうか?
非アクティブでも…ということであれば、そうなる…んですかね。
少々間が空いてしまいました。
DLLを作成し、グローバルフックを作成したのですが、フックプロシージャのどのモード
で処理すればよいのか判りません。
m_hHook = ::SetWindowsHookEx( WH_CALLWNDPROC
, (HOOKPROC)CallWndProcHook
, m_hInst
, 0);
でCallWndProcHook()内で「QueryCancelAutoPlay」のメッセージIDをキャッチ出来ま
したが、これはキャッチできるだけで、メッセージそのものを処理することは出来ず、
またこの時アプリケーションがアクティブの時だけという状態でした。
そこでSetWindowsHookEx( WH_GETMESSAGE....でやってみたのですがメッセージIDその
ものがキャッチできませんでした。
どなたかご教授お願いいたします。