指定したウインドウのカラー色(RGB)取得

[戻る]
asuka 2007/10/24(水) 17:27:08
はじめまして。

VS2005のVC++6.0 SDK OS:2003サーバにて開発しております。



■質問
ウインドウハンドルが分かっているプログラムの背景色(RGB)を取得したいのですが、

どのように実装すればよろしいでしょうか?



■現在の取得方法
プログラム(EXE)はウインドウにアイコンが表示されたピクチャーボックスとエディット
ボックスが一つある画面です。

WM_LBUTTONUPにてアイコンを左クリックした時にキャプチャを開始しております。

WM_LBUTTONUPにキャプチャを開放しておりますが、開放する前に以下の方法でマウスポイ
ンタ直下のウインドウハンドルを取得しております。



// マウスポインタの現在の位置に相当するスクリーン座標を取得
GetCursorPos( &m_MPoint );
// 指定された座標を含むウィンドウのハンドルを取得します。
m_hTWnd = WindowFromPoint( m_MPoint );

// 自分の場合は処理しない
GetWindowThreadProcessId( _hWndT, &dwProcessId );
if( dwProcessId == GetCurrentProcessId() ) 
 break;



// カラー値取得
COLORREF crf;
HDC hDC;
hDC = GetDC( m_hTWnd );
crf = GetBkColor( hDC );

int a,r,g,b;
r = GetRValue( crf );
g = GetGValue( crf );
b = GetBValue( crf );

TCHAR szTmp[MAX_PATH];
wnsprintf( szTmp, MAX_PATH, "ClassName = %s, r = %d, g = %d, b = %d", m_szBuf, 
r, g, b ); 
MessageBox( hParent, szTmp, "RGB", MB_OK );



■結果
結果に表示されるメッセージボックスの値は[r = 255, g = 255, b = 255](白)です。

白でない色なのに全てのウインドウに対してこのような結果になってしまいます。

試しにデバッグとしてクラスを取得
if( m_hTWnd != NULL )
GetClassName( m_hTWnd, m_szBuf, MAX_PATH );
MessageBox(…);

とすると、きちんと対象のウインドウのクラス名は取得出来ております。


どのようにすれば正確な値が取得出来るのか御教授頂ければ幸いです。

wclrp ( 'o') 2007/10/24(水) 23:59:33
GetDC,GetBkColorでは
そのウィンドウに描画するための鉛筆の色を調べていることになる。
そしてGetDCした直後はいつも白地に黒である。

背景色なんてあいまいだとおもうんだけどな。
動画プレイヤとか背景色なんて使わないだろうし。

asuka 2007/10/25(木) 09:25:36
wclrpさんレスありがとうございます。

なるほど、そうだったのですか・・・

それでは一体何を調べれば良いのやら・・・



実は目的はIEのツールバーのRGBが知りたかったのです。

IEに自作のツールバーを入れたのですが(C#で作成)、背景色を以下のように設定しており
ます。

Color.FromKnownColor(KnownColor.MenuBar).A.ToString();

2000、2003ですと他のツールバーと同様になりうまくいくのですが、

XPですと若干色合いが異なってしまいます。

・2000 2003
ColorA =255 
ColorR =212 
ColorG =208 
ColorB =200

・XP Home Pro
ColorA =255 
ColorR =236 
ColorG =233 
ColorB =216



プログラムから背景色を設定出来るようにしておりますので、

最悪はXPの背景色(RGB)を調べてその値を設定させようと考えておりました。

C#ではマウスイベントの処理が分からなかったのでVC++で調査ツールを作成していたので
すが、

今度は調査対象(何のRGBを取得すればよいのか)が分からなくなってしまいました。TT

たいちう 2007/10/25(木) 10:32:49
マルチポストを指摘しておきます。
(このケースでは)決して非難の意味ではなく他の回答者の便宜のために。
『IEのツールバーをC#で作っているが、WindowsXPでは微妙な色の違いが出てしまう』
ということを、最初に書くべきでしたね。

http://bbs.wankuma.com/index.cgi?mode=al2&namber=9115

↑で、ひどりさんが書いてますが、とても難しそうですね。

私の手には負えませんが、"C# ツールバー"でググるとそれっぽい
ページが出てきました。参考になるでしょうか?

http://mobiquitous.com/programming/ietoolbar.html
http://www.codeproject.com/csharp/dotnetbandobjects.asp

asuka 2007/10/25(木) 11:13:10
んんん?

確かにC#での質問はツールバーに関しての『エクスプローラの色がMenuBarなのか』につ
いて質問してましたが、

今回は別ツール(VC++)で『マウス直下の色の取得』について伺ってるつもりです。

そんなに広い世界でもないのでマルチポストについては常識をもって行わないように心が
けているつもりです。

一連している作業なので背景を述べて、背景が被っただけではないでしょうか?^^;

ともあれ否定しておきます。




と、せっかく頂いた情報なのですが、

確かに頂いた情報が欲しいということであればマルチポストになるのでしょうけど、

同じく自分にも手に負えないと判断したので、今回はエクスプローラの透過ではなく、

マウス直下の下にある色を取得する方法が知りたいのです。^^
(全然違う内容じゃないでしょうか?^^;)



http://oshiete.nikkeibp.co.jp/kotaeru.php3?q_id=2185376

色々調べてみますと、上記のようなサイトを目にしたのですが、

そもそもVC++で

#using <System.Drawing.dll>
using namespace System;
using namespace System::IO;
using namespace System::Drawing;

こんなことが出来るのでしょうか!???



http://msdn2.microsoft.com/ja-jp/library/system.drawing.color.fromknowncolor
(VS.80).aspx

上記にも

C++
public:
static Color FromKnownColor (
    KnownColor color
)


とありますが、使い方が分からず困っております。TT

subaru 2007/10/25(木) 11:26:12
>Color.FromKnownColor(KnownColor.MenuBar).A.ToString();
ビジュアルスタイルが適用されているかどうかは考慮しないといけないですが
透過できないならこの方法くらいでしか値は取得できないような気がします。
#IEのツールバーは微妙にグラデーションがかかっていて右と左で色が違ったりするから
#単純に1色だけ取得しても意味がなさそう。

>最悪はXPの背景色(RGB)を調べてその値を設定させようと考えておりました。
GetClassLongでGCL_HBRBACKGROUNDを指定すれば
ウインドウに関連付けられた背景ブラシを取得できますが
必ずしもそれを使って描画しているとは限りません。
PrintWindowでイメージを取得すればもしかしたら正確なRGB値も取れるかも
しれませんがウインドウが対応していないこともありえます。

たいちう 2007/10/25(木) 11:46:18
> 一連している作業なので背景を述べて、背景が被っただけではないでしょうか?^^;
> 
> ともあれ否定しておきます。

非難するつもりはないと書きながら、マルチポストという言葉が非難に
当たっていたかもしれませんね。関連する質問の紹介、と訂正します。
失礼しました。


> #IEのツールバーは微妙にグラデーションがかかっていて右と左で色が違ったりする
から
> #単純に1色だけ取得しても意味がなさそう。

自分のツールバーがどこに表示されるかによっても、
色を変えないといけないということですね。

FUKU 2007/10/25(木) 12:52:19
試してみてないので何とも言えませんが、

 ::ScreenToClient(hWnd, &m_MPoint);
 crf = ::GetPixel(hDC, m_MPoint.x, m_MPoint.y);

ではどうでしょうか

asuka 2007/10/25(木) 13:58:41
レスありがとうございます。TT



頂いたアドバイスを元に実装してみました。

subaruさんから頂いたアイデアは思いつきもせず試してみようと思ったのですが、

必ずしもそのブラッシュが使用されている可能性がないということと、

ウインドが対応していない場合もあることから、

FUKUさんのアイデアを実装したところ、マウス直下のRGBを取得することが出来まし
た。

本当にありがとうございます。




ところがsubaruさん、たいちうさんのご指摘されますように、なんとXPのツールバーはグ
ラデーションされているようです。TT

調べた結果、2000、2003では一意であったのですが、XPでは横方向にずれるに従って値が
変わっていきました。



とりあえず本件の目的は果たせましたので深くお礼申し上げます。

予断ですが、このRGBなるものに、ARGBとありますが(A:255固定)、

GetRValue()
GetGValue()
GetBValue()

はあるものの、GetAValue()がなさそうなのですが、Aの値はVC++では取得出来ないのでし
ょうか!?

subaru 2007/10/25(木) 14:51:55
FUKUさんの方法はウインドウが隠れている場合は取得できないので
書きませんでしたが、マウス直下の色でしたね。。。

>予断ですが、このRGBなるものに、ARGBとありますが(A:255固定)、
>
>GetRValue()
>GetGValue()
>GetBValue()
>
>はあるものの、GetAValue()がなさそうなのですが、Aの値はVC++では取得出来ないのでし
>ょうか!?
RGB値は24ビットのためGetAValue()のようなものはありません。
32ビットのARGBのAはアルファ値を表します。
KnownColorのシステムカラーのAが255固定なのはアルファ情報を持たないからです。
VC++でもGdiplusで透過PNGファイルや透過GIFファイルを読んだ場合なんかは
ちゃんと設定されています。

あとVC++でもプロジェクトの設定によって.Net Frameworkの機能は使えます。

asuka 2007/10/25(木) 18:31:15
なるほどぉ・・・

Aの値取得云々についてはもう少し自分で調べてやってみます。

まずは.NetFrameworkをVC++で使えるよう設定出来るようにならなくては・・・^^;



色々とアドバイスありがとうございました。

asuka 2007/10/25(木) 18:31:52
[[解決]]
解決とさせて頂きます。

お返事くれた皆様、ありがとうございました。

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