マウスクリックでRGBを取得するには?

解決


クライム  2003-09-16 22:56:54  No: 4847  IP: [192.*.*.*]

フォーム以外の領域(ウィンドウ全体)でマウスクリックで色を取得したいと考えているのですが、うまくいきません。
ご教授お願いいたします。
Delphi 6 Personal , WinXPPro

編集    削除
RBG  2003-09-19 02:26:41  No: 4848  IP: [192.*.*.*]

デスクトップ領域などの、
自Form外のクリックした位置の色を得たい
という事でしょうか?

application.OnDeactivate時に、
デスクトップのイメージを取得して、
〜.Color := 取得したImage.Canvas.Pixels[x.y];
で出来るかと思います。

※(x.y)はMouse.CursorPosで。
※デスクトップのイメージを得るのは検索すれば見つかると思います。
※FormのOnDeactivateではダメです。Help参照。

編集    削除
にしの  2003-09-19 02:46:33  No: 4849  IP: [192.*.*.*]

それだと、Alt+Tagでも発生しますよね。

編集    削除
にしの  2003-09-19 02:46:45  No: 4850  IP: [192.*.*.*]

スペルミス。
Alt+Tab

編集    削除
Halbow  2003-09-19 03:00:21  No: 4851  IP: [192.*.*.*]

Halbow です。

色の取得は、画像キャプチャの応用なので簡単です。
この質問の難しいところは、自分が作ったウィンドウ以外でのマウスクリックを
検出することですね。これはグローバルフックでできますが、DLL を作らなけれ
ばならないので、掲示板で回答を書くのをためらってしまいます。

編集    削除
RBG  2003-09-19 03:03:06  No: 4852  IP: [192.*.*.*]

クリックした時に色が取得出来ていればいいのではないでしょうか?

deactivate時は、
マウスボタンが押されているか確認するのは不可能ですか?
getkeystateで出来ませんか?

編集    削除
Halbw  2003-09-19 03:05:14  No: 4853  IP: [192.*.*.*]

Halbow です。

マウスクリックをグローバルフックで検出したとしても、ボタンなどを押すたび
に色を取得してしまうので、かえって使いにくいと思います。色を取得したい
ところにマウスを持っていって、たとえば F11 キーを押して色を取得する、
というのなら簡単そうです。

編集    削除
にしの  2003-09-19 17:28:29  No: 4854  IP: [192.*.*.*]

> deactivate時は、
> マウスボタンが押されているか確認するのは不可能ですか?
> getkeystateで出来ませんか?

「マウスのボタンが押されている」=「マウスのボタンが今押された」ではありませんから、押されているか確認できても、クリック時に取得は無理です。

例えば、
アプリ内のどこかでマウスダウン、Alt+Tabでタスクを切り替え(この時点でOnDeactivate発生)
こういう場合の判別が無理です。

それと、おそらくマウスでクリックしたい場所は、自分のアプリケーションウィンドウが表示されていない状態でのどこかでしょう。
そうであれば、デスクトップのスナップショットを取得し、クリックさせる方が実用的と言えます。
# マウスキャプチャでもできるかもしれませんが、未確認です

Halbowさんへ。
グローバルフックを使わずに、単純なマウスキャプチャでできませんか?試していないのでわからないのですが。

編集    削除
Halbow  URL  2003-09-19 18:35:40  No: 4855  IP: [192.*.*.*]

Halbow です。

> グローバルフックを使わずに、単純なマウスキャプチャでできませんか?

SDK の SetCapture() API のところには、

If the mouse cursor is over a window created by another thread, 
the system will direct mouse input to the specified window only
 if a mouse button is down.

となっていますので、例えば、Button1 を押してキャプチャを開始して、
Form1 を最小化し、取得したい場所のところへカーソルを持っていって、
というその間ずっと、ボタンを押し続けていないと、キャプチャが
はずれてしまいます。これでは無理ですね。

タイマで GtKeyState や GetAsyncKeyState で監視しておくのが
実用的かも知れませんね。

編集    削除
にしの  2003-09-19 19:09:20  No: 4856  IP: [192.*.*.*]

> ボタンを押し続けていないと、キャプチャが
> はずれてしまいます。これでは無理ですね。

そういえばそうですね。
勘違いしていたようです。
ありがとうございました。

編集    削除
クライム  2003-09-19 21:11:25  No: 4857  IP: [192.*.*.*]

みなさん、ご教授ありがとうございます。
説明不足ですいません。
自アプリにスポイト機能をつけたいと考えています。
スポイトボタンをクリックし、マウスカーソルをスポイトに変更。
それからデスクトップ上の色を取得したいです。
マウスボタンを離した瞬間に、その時点の色を取得できたらいいと考えています。
上級者レベルでしょうか?

編集    削除
Halbow  2003-09-19 22:29:58  No: 4858  IP: [192.*.*.*]

Halbow です。

新規で Form1 に Button1 と Panel1 を置いて

  public
    function GetColorAtPos(pt:TPoint):TColor;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function TForm1.GetColorAtPos(pt: TPoint): TColor;
var
  DispDC: HDC;
begin
  result := clBlack;
  DispDC := CreateDC('DISPLAY',nil,nil,nil);
  if DispDC <> 0 then begin
    result := GetPixel(DispDC,pt.x,pt.y);
    DeleteDC(DispDC);
  end;
end;

procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  Pt:TPoint;
begin
  Pt := Mouse.CursorPos;
  Panel1.Color := GetColorAtPos(Pt);
end;

Button1 をマウスで押したまま、スクリーンの任意の場所で離すと、そこの
色が Panel1 に反映されます。

編集    削除
くらいむ  2003-09-27 04:17:29  No: 4859  IP: [192.*.*.*]

レスかなり遅くなってしまって申し訳ございません。
みなさんのおかげで解決いたしました。
これからもDelphiプログラミングをがんばっていきたいと思ってますので、
よろしくお願い致します。

編集    削除