システムフックでWM_DRAWCLIPBOARDを引っ掛ける

[戻る]
真鍋 2004/10/01(金) 12:47:44
Windows2000, VC++6.0sp6です。

DLLを作成しその中でSetWindowsHookExでWH_CALLWNDPROCRETのシステムフックをセット
し、フックプロシージャ内でWM_DRAWCLIPBOARDを引っ掛け、クリップボードの内容を取得
しようと思ったのですが、WM_DRAWCLIPBOARDが入ってきません。

このフックプロシージャ内にはWM_ACTIVATEやWM_SETTEXTは入ってきます。

SetClipboardViewerは使用していません。エディタなど、クリップボードを使用している
(と思われる)アプリで発生するWM_DRAWCLIPBOARDを捕らえたいのです。

何が原因か分からないのですが、どうしたらいいのかご存知の方ご教授していただけない
でしょうか。

ちなみに「http://www.google.co.jp/search?
q=cache:i1INBxdDmYsJ:diary.hatena.ne.jp/OguraKunio/20040212+WM_DRAWCLIPBOARD+%
E3%83%95%E3%83%83%E3%82%AF&hl=ja」ではWM_DRAWCLIPBOARDやWM_CHANGECBCHAINが
WH_CALLWNDPROCRETで取得できると書いてあります。

シャノン 2004/10/01(金) 13:01:54
こちらは?
http://forums.belution.com/ja/vc/000/267/67s.shtml

真鍋 2004/10/01(金) 21:49:30
>こちらは?
>http://forums.belution.com/ja/vc/000/267/67s.shtml
こっちでは分からなかったんです。すいません。

ROMフリーク 2004/10/01(金) 23:25:37
あいにく紹介されている本を読んだことがないので助言も
できないのですが「(うろ)覚え書き」が完全に正しいと
いう根拠はあるのでしょうか.
少なくとも出てくる本を読んでいる前提に見えますが彼方
は理解できるまで読み込みましたか.
この覚書だけが情報源なら、それを書いた本人にコンタク
トした方がよさそうです.

> こっちでは分からなかったんです。すいません。

話題を〆ずに放置されることがキライな常連さんもいます.
少なくともこの旨をきちんと向こうに書くべきだったと思
います.常連の方は複数の掲示板を見ています.別の掲示
板に書き込むくらいなら『やっぱりわかりませんでした』
と続きを書いた方が良かったかもしれません.

問題は現在の彼方の理解力や技術力ですから、どこに移っ
てもそうすぐには変わりません.冷たいですが彼方の問題
は最終的に彼方が解決するしかありません.

シャノン 2004/10/02(土) 14:58:53
向こうのスレを締めてから来てください…はROMフリークさんがおっしゃって
おられるので割愛。

何をなさりたいのでしょうか?
クリップボードの監視ならば SetClipboardViewer で十分でしょう。
フックということは既定の動作を変更するということですが、
WH_CALLWNDPROCRET はメッセージの処理を終えた後をフックするので、
他のアプリが WM_DRAWCLIPBOARD に対して起こすアクションを変更する
ことはできません。

メッセージパラメータにはポインタもなく、戻り値も無視されますので、
これをフックすることは、単に「WM_DRAWCLIPBOARD が届いた」ということを
検出する以上の意味を持たないと思われます。
繰り返しますが、そのような用途であれば、SetClipboardViewer で十分では
ないでしょうか。

また、前スレで dairygoods さんが書かれておられますが

> WM_DRAWCLIPBOARDは、SetClipboardViewerで登録されたビューアが
> 存在しなければ発生しないと思いますが、そのあたりは大丈夫でしょうか?

これもあります。
貴方は

> エディタなど、クリップボードを使用している
> (と思われる)アプリで発生するWM_DRAWCLIPBOARDを捕らえたいのです。

と書かれていますが、まず、本当にそのエディタはクリップボードを監視して
いるのか、また、他にクリップボードを監視していると確実に言えるアプリが
起動しているのかどうかを確認する必要があると思います。
でなければ、WM_DRAWCLIPBOARD は発生しないかもしれません。

シャノン 2004/10/02(土) 15:22:34
推測からもうひとつレス。

前スレ(belution の方です)を見ると、

> レジストリのShellServiceObjectDelayLoadキーにdllを登録し、その中で
> システムフックをかけているからです。

とあります。
ひょっとして、DLL だからウィンドウを持たず、自アプリでは SetClipboardViewer を
使えない、とお考えでしょうか。
であれば、DLL がウィンドウを作ってしまえばいいだけではないかと思われますが。
非表示でユーザーインターフェイスとしては機能しない、ただメッセージターゲットと
しての役割だけを持つウィンドウを作るわけです。

環境は Win2000 だそうですが、Win2000 以降でしか動かなくてもいいのなら、
まさにそのための「メッセージ専用ウィンドウ」という機能があります。
詳しくは CreateWindowEx の説明をご覧ください。

シャノン 2004/10/02(土) 15:23:26
ついでに
#駄レス失礼

ShellServiceObjectDelayLoad とは、なかなか面白いキーを教えていただきましたw
ありがとうございます。

真鍋 2004/10/03(日) 19:49:35
>ひょっとして、DLL だからウィンドウを持たず、自アプリでは SetClipboardViewer 
>を使えない、とお考えでしょうか。
そうです。

>環境は Win2000 だそうですが、Win2000 以降でしか動かなくてもいいのなら、
>まさにそのための「メッセージ専用ウィンドウ」という機能があります。
>詳しくは CreateWindowEx の説明をご覧ください。
Widows Meでも動かしたいです。

シャノン 2004/10/04(月) 09:22:44
>> ひょっとして、DLL だからウィンドウを持たず、自アプリでは SetClipboardViewer 
>> を使えない、とお考えでしょうか。

> そうです。

> であれば、DLL がウィンドウを作ってしまえばいいだけではないかと思われますが。
> 非表示でユーザーインターフェイスとしては機能しない、ただメッセージターゲット> しての役割だけを持つウィンドウを作るわけです。

メッセージ専用ウィンドウは Win2k 以降でしか使えませんが、
メッセージターゲットとしてのみ機能する非表示のウィンドウを作ることは
Me だろうが 95 だろうができるはずです。
フックなどという面倒なことをせず、SetClipboardViewer を使ってみては如何でしょう
か。
シンプルな方法で実現できるのなら、それに越したことはないと思います。

真鍋 2004/10/05(火) 21:05:28
[[解決]]
>メッセージ専用ウィンドウは Win2k 以降でしか使えませんが、
>メッセージターゲットとしてのみ機能する非表示のウィンドウを作ることは
>Me だろうが 95 だろうができるはずです。
そうですね。

>フックなどという面倒なことをせず、SetClipboardViewer を使ってみては如何でしょう
か。
>シンプルな方法で実現できるのなら、それに越したことはないと思います。
でもなんとかフックで実現したいのですが、無理でしょうか。

古いスレッドには追加発言できません。