• 締切済み

Formの外にある画面の色を取得

Delphi XE3で始めたものです。 今まではアプリの自Formに画像をロードしてマウスをクリックするとその色を取得するものを作って動かしていましたが、最近自Formの外にある画面の色を取得するソフトがあることを知りました。 これをDelphiで作ってみたいと思いますがDelphiでこのようなことができる方法があったら教えてください。

みんなの回答

  • kumatti1
  • ベストアンサー率60% (73/121)
回答No.4

#鮮やかにスルーされてるのでコメントする気も失せますが。 SetCapture時はGetCursorPosとWindowFromPointを使います。 それが面倒ならWH_MOUSE_LLフックやDLLを作成してのグローバルフックではどうでしょうか。

cgsksnng
質問者

補足

kumatti1様 知識がないためご教示いただいたフックとかグローバルフックなどの意味が分からずまったく手のつけようがなく失礼しました。WEBで探してみると色々とあるようですのでキーワードを頼りに理解に勤めようと思います。 ありがとうございました。

回答No.3

以下のページを参考に、APIでマウスをキャプチャしよう。 http://wisdom.sakura.ne.jp/system/winapi/win32/win45.html 具体的には 1.自作アプリ内に「色の取得」と言うボタンを配置して、有効化しておく。 2.自作アプリ内に「色の取得の中止」と言うボタンを配置して、無効化しておく。 3.「色の取得」のボタンが押されたイベントに飛んできたら、「色の取得」のボタンを無効化して押せないようにして(2度押しの防止)、「色の取得の中止」のボタンを有効化して押せるようにして、マウスボタンを押した時、マウスボタンを離した時のイベントを設定して、API関数のSetCapture()関数を呼ぶ。 4.「マウスボタンを押した時」のイベントに飛んできたら、マウスボタンを押した時のイベントを無効にして(イベント2重実行の抑止)、マウスカーソルを消去してから(これ重要)、画面をキャプチャして、マウスカーソルの表示を元に戻して、マウス位置をスクリーン座標に変換して、スクリーン座標に対応した位置のピクセルを取得して、カラーを24ビットカラーに変換する。 5.「マウスボタンを離した時」のイベントに飛んできたら、マウスボタンを押した時と離した時の両方のイベントを無効にして、API関数のReleaseCapture()関数を呼んで、「色の取得」のボタンを有効化して押せるようにして、「色の取得の中止」のボタンを無効化して押せないようにする。 6.「色の取得の中止」のボタンが押されたイベントに飛んできたら、マウスボタンを押した時と離した時の両方のイベントを無効にして、API関数のReleaseCapture()関数を呼んで、「色の取得」のボタンを有効化して押せるようにして、「色の取得の中止」のボタンを無効化して押せないようにする。 特に「色の取得の中止」のボタンは必須。SetCapture()関数を呼んでマウスをキャプチャしている状態で、マウスカーソルがフォームの外に居る時に、他のアプリに制御が移ったりすると、「マウスボタンを離した時」のイベントに飛んでこないまま、マウスボタンが離された状態になり、色の取得中の状態から抜け出せなくなります。 なので「マウスボタンはもう離されているのに、ボタンを離した時のイベントが起きなかった時」に備えて「色の取得の中止」のボタンが必要です。 あと、画面をキャプチャする時は「今のマウスカーソルの状態を覚えておいて、マウスカーソルを消して、画面を取り込んでから、マウスカーソルを元に戻す」と言う処理が必要。これを行わないと「ピクセルを取り込んだ位置には、常にマウスカーソルが居る」ので、画面の色じゃなく、マウスカーソルの先端の色を拾ってしまいます。 蛇足だけど、本当は「マルチスクリーン環境」の事も考えないといけない。マルチスクリーン環境で、マウスカーソルがメインモニタに居るかサブモニタに居るかで、画面とピクセルを取り込む処理を変えないといけない筈(当方はマルチモニタ環境じゃないので試せない)

cgsksnng
質問者

補足

Chie6553様 詳細なアクションをご紹介いただきありがとうございました。 今まで作った画像ファイルをロードしてから色を取得するのに代えてスクリーンをCaptureすることはできました。なおテストしたところマウスポインターはキャプチャーされないようでしたのでマウスポインター対策は不要のようでした。 この状態ではあくまでクライアント領域の範囲内での処理になりますが、これを何とかクライアントの外の情報を取得を取れないものかと思っています。例えば非表示のImage1とかTBitmapをスクリーンのサイズにして常時キャプチャーしておいて色のデータを表示するFormは小さくしておきます。これでマウスのスクリーン座標(クライアント領域外)、マウスダウン、マウスアップの情報を取得して非表示のキャプチャー画像から色を取得して小さなFormに色の情報を表示するというものを考えましたが不可能でしょうか? このようなわけでFormの外にあるSetCaptureやWMNCLButtonCLKなどを試してみましたがForm内のものしか反応しませんでした。マウスホイールなどはマウスがFormの外にあっても反応するので簡単にできるかと思っていましたがかなり大変なことに感じました。また何か情報がありましたらよろしくお願いします。

  • kumatti1
  • ベストアンサー率60% (73/121)
回答No.2

> Formの外でのMouseMoveやMouseDownなどのイベント Formをサブクラス化してSetCaptureでマウスメッセージを処理する事になるのではと。 他はDirectInputかWM_INPUT。

回答No.1

以下のページを参考に、APIでスクリーンをキャプチャしよう。 http://mrxray.on.coocan.jp/Halbow/Notes/N009.html キャプチャしたら、マウスの「スクリーン座標」を元に、キャプチャした画像からピクセルを拾い出し、24ビットカラーに変換すれば良い。 因みに「キャプチャした画像が24ビットカラーとは限らない」ので注意すべし。画面のプロパティで、画面のカラーが16ビットカラーになっている可能性もある。

cgsksnng
質問者

補足

chie65535様 情報をありがとうございます。試したところキャプチャーはできました。 これでFormの外でのMouseMoveやMouseDownなどのイベントが発生できるようになれば目的のことができると思い探してみました。いままで見たところではDelphiアプリ上のイベントでしか反応しないものばかりでした。Formの外でのMouseDownやMouseMoveなどのイベントを発生させる方法などの情報をご存知でしたら教えてください。 

関連するQ&A