1181196973 VC++6に関する質問です。

ChooseColor(&cc)で色設定のダイアログを表示しました。
基本色を選択することもできるし、一見正常に動作しているように
思えたのですが、色を選択し、『色の追加』を押しても
『作成した色』に情報が反映されません。

どのようにすれば
選択した色を『作成した色』に追加することができますか?
教えていただきたく宜しくお願いします。


[実際のコーディング内容]
static COLORREF cr = RGB(255, 255, 255);
CHOOSECOLOR cc;
ZeroMemory(&cc,sizeof(CHOOSECOLOR));
cc.lStructSize = sizeof(CHOOSECOLOR);
cc.hwndOwner =(HWND ) this->m_hWnd;
cc.lpCustColors = dwCustColors;
cc.rgbResult = cr;
cc.Flags = CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT;

// カラーダイアログを表示
if(ChooseColor(&cc)){

}


※なお、先ほど
ChooseColor(&cc)関数を呼び出す前に

cc.Flags = CC_ANYCOLOR

として呼び出したとき、作成した色の左上の一個だけ、色を追加
できるようになりました。
理由はわかりませんが他のフラグを追加すると、なぜかまた登録できなくなりました。

回答の条件
  • URL必須
  • 1人10回まで
  • 登録:
  • 終了:2007/06/12 19:17:40
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:jack_sonic No.1

回答回数124ベストアンサー獲得回数25

ポイント100pt

こんにちは。

ポイントとしては、

色選択ダイアログのカスタム色は、

CHOOSECOLOR構造体の、lpCustColorsプロパティに設定する、

DWORDの16個の配列に保存されます。

呼び出し関数内で値を保持するためには、

staticで宣言、もしくは、

値を保持できる変数を外から渡さなければ

なければなりません。

  • ①複数回呼び出されてもカスタム色を保持できる

および、

  • ②外からカスタム色配列を渡されたときに、最初からカスタム色の指定ができる

機能を持つ呼び出し関数を書くとこのような感じです。

サンプル(例: ②の機能でカスタム色を肌色系で指定したとき)

[f:id:jack_sonic:20070607200743j:image]

ヘッダファイル DialogFunc.h

// DialogFunc.h
#pragma once

// カラー選択ダイアログ表示関数
// (オーナーウィンドウ, 結果格納COLORREF, 初期カラー, 初期カラーを使うかどうか)
BOOL ColorDlg(HWND hWnd, COLORREF* p_crResult, 
			  COLORREF crFirst, BOOL bUseFirstColor, DWORD dwSpCustomColors[] );

ソースファイル DialogFunc.cpp

#include "StdAfx.h"  // VC++のときインクルード
///////////////////////////////////////////////////////////
//
//	ColorDlg() カラー選択ダイアログ関数
//	カスタムカラー配列はstaticで保存されます。
//		@param  hWnd		:   オーナーウィンドウ
//		@param  p_crResult	:	結果を受け取るCOLORREFのポインタ 
//		@param	crFirst		:  初期選択色
//		@param	bUserFirstColor: 初期選択色を使うかどうか
//		@param dwSpCustomColors[] 
//					: カスタムカラー配列を独自に指定する場合(NULL: デフォルト保存)
//		@return TRUE:選択 , FALSE :キャンセル
//
BOOL ColorDlg(HWND hWnd, COLORREF* p_crResult, 
			  COLORREF crFirst, BOOL bUseFirstColor, DWORD dwSpCustomColors[] )
{
	// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください

	// CHOOSECOLOR構造体定義
	CHOOSECOLOR cc;
	// カスタムカラーボックスのデータ配列定義
	// 16個のCOLORREF変数の配列 ( staticで宣言すること)
	static DWORD       dwDefaultCustomColors[16];   
	// COLORREF構造体定義
	static COLORREF crDefaultFirst = RGB(255,255,255);

	// CHOOSECOLOR構造体クリア
	ZeroMemory(&cc,sizeof(CHOOSECOLOR));
	// CHOOSECOLOR構造体サイズ設定
	cc.lStructSize = sizeof(CHOOSECOLOR);
	// オーナーウィンドウ設定
	cc.hwndOwner =(HWND ) hWnd;
	// カスタムカラーボックスのデータ配列設定
	cc.lpCustColors = ( dwSpCustomColors != NULL)? dwSpCustomColors: dwDefaultCustomColors;

	// 	初期選択色
	cc.rgbResult =  (bUseFirstColor == TRUE)? crFirst: crDefaultFirst;
	// フラグ設定
	// CC_FULLOPEN : カスタムカラー設定表示
	// CC_RGBINIT  : rgbResultの色を初期選択
	// CC_ANYCOLOR : 使用可能な全ての色を表示する
	cc.Flags = CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT;
	
	// カラーダイアログを表示
	if(ChooseColor(&cc)){
		*p_crResult = cc.rgbResult;
		return TRUE;
	}
	return FALSE;
}

使い方

呼び出したいソースファイルの先頭で、

// インクルード
#include "DialogFunc.h"

と宣言してインクルードし、

ダイアログクラスCColorSampleDialogで、

ボタンおよびハンドラが2個あるとして、(OnButton1,OnButton2)

ボタン1でカスタム色を保持する色選択ダイアログを表示するなら、

void CColorSampleDlg::OnButton1() 
{
	COLORREF crSelected;
	COLORREF crFirst = RGB(133,133,122);
	// 最初の色を指定して呼び出し
	if( ColorDlg( this->m_hWnd, &crSelected, crFirst ,TRUE,NULL  ) )
	{
		// 色が選択されたとき		
	}

}

ボタン2でカスタム色を最初から指定して呼び出すなら

void CColorSampleDlg::OnButton2() 
{
	// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
	COLORREF crSelected;
	COLORREF crFirst = RGB(133,133,122);
	// カスタムカラー配列を最初から独自指定する場合
	static DWORD dwCustomColor[16];
	static int first = 1;
	// 最初の1回だけ実行
	if(first == 1)
	{
		for(int i=0; i < 16 ; i++)
		{
			// 肌色系の階のカスタムカラー配列にする
			dwCustomColor[i] = RGB(255, 150+ i*5, 100 + i* 5);	
		}

		first =2;
	}
	// カスタムカラー配列を独自指定して呼び出し
	if( ColorDlg( this->m_hWnd, &crSelected, crFirst ,TRUE, dwCustomColor ) )
	{
		
	}
}

というような感じで使います。


サンプル実行ファイル+プロジェクトファイルはこちらです。

VC++/カスタム色を使った色選択ダイアログの表示 - 情報処理研究所 ジャックズラボ(jack's Lab)

id:harunoharuno

いつも回答してありがとうございます。

早速教えていただいた方法を拝見し、

プログラムに組み込んでみました。

jack_sonic さんに教えていただいた

コーディングそのものだと、色の追加も正常に

に出来たのですが、

dwCustomColor[i] = RGB(255, 150+ i*5, 100 + i* 5);

dwCustomColor[i] = RGB(255, 255, 255);

の設定にし試したところ、以下の現象を確認しました。

・色の設定ダイアログを表示後、作成した色を選択すると、

 右側のカラーパレットから色を選んでも『色|純色』

 が変更されず、『色の追加』を押しても『作成した色』に反映されない。

これは何故なのでしょうか?

出来ればはじめの色は白にしたいと思っているのですが

無理なのでしょうか?

再度回答いただきたく宜しくお願いします。

[追記]

dwCustomColor[i] = RGB( 255, 255,230+i);

でやっても、『色の追加』を押しても『作成した色』に反映されない現象が発生しました。

これは何故なのでしょうか?jack_sonic

さんが初期設定の色として指定した

ものにルールがあるのならそれに付いても教えていただきたく宜しくお願いします。

2007/06/07 22:53:11

その他の回答1件)

id:jack_sonic No.1

回答回数124ベストアンサー獲得回数25ここでベストアンサー

ポイント100pt

こんにちは。

ポイントとしては、

色選択ダイアログのカスタム色は、

CHOOSECOLOR構造体の、lpCustColorsプロパティに設定する、

DWORDの16個の配列に保存されます。

呼び出し関数内で値を保持するためには、

staticで宣言、もしくは、

値を保持できる変数を外から渡さなければ

なければなりません。

  • ①複数回呼び出されてもカスタム色を保持できる

および、

  • ②外からカスタム色配列を渡されたときに、最初からカスタム色の指定ができる

機能を持つ呼び出し関数を書くとこのような感じです。

サンプル(例: ②の機能でカスタム色を肌色系で指定したとき)

[f:id:jack_sonic:20070607200743j:image]

ヘッダファイル DialogFunc.h

// DialogFunc.h
#pragma once

// カラー選択ダイアログ表示関数
// (オーナーウィンドウ, 結果格納COLORREF, 初期カラー, 初期カラーを使うかどうか)
BOOL ColorDlg(HWND hWnd, COLORREF* p_crResult, 
			  COLORREF crFirst, BOOL bUseFirstColor, DWORD dwSpCustomColors[] );

ソースファイル DialogFunc.cpp

#include "StdAfx.h"  // VC++のときインクルード
///////////////////////////////////////////////////////////
//
//	ColorDlg() カラー選択ダイアログ関数
//	カスタムカラー配列はstaticで保存されます。
//		@param  hWnd		:   オーナーウィンドウ
//		@param  p_crResult	:	結果を受け取るCOLORREFのポインタ 
//		@param	crFirst		:  初期選択色
//		@param	bUserFirstColor: 初期選択色を使うかどうか
//		@param dwSpCustomColors[] 
//					: カスタムカラー配列を独自に指定する場合(NULL: デフォルト保存)
//		@return TRUE:選択 , FALSE :キャンセル
//
BOOL ColorDlg(HWND hWnd, COLORREF* p_crResult, 
			  COLORREF crFirst, BOOL bUseFirstColor, DWORD dwSpCustomColors[] )
{
	// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください

	// CHOOSECOLOR構造体定義
	CHOOSECOLOR cc;
	// カスタムカラーボックスのデータ配列定義
	// 16個のCOLORREF変数の配列 ( staticで宣言すること)
	static DWORD       dwDefaultCustomColors[16];   
	// COLORREF構造体定義
	static COLORREF crDefaultFirst = RGB(255,255,255);

	// CHOOSECOLOR構造体クリア
	ZeroMemory(&cc,sizeof(CHOOSECOLOR));
	// CHOOSECOLOR構造体サイズ設定
	cc.lStructSize = sizeof(CHOOSECOLOR);
	// オーナーウィンドウ設定
	cc.hwndOwner =(HWND ) hWnd;
	// カスタムカラーボックスのデータ配列設定
	cc.lpCustColors = ( dwSpCustomColors != NULL)? dwSpCustomColors: dwDefaultCustomColors;

	// 	初期選択色
	cc.rgbResult =  (bUseFirstColor == TRUE)? crFirst: crDefaultFirst;
	// フラグ設定
	// CC_FULLOPEN : カスタムカラー設定表示
	// CC_RGBINIT  : rgbResultの色を初期選択
	// CC_ANYCOLOR : 使用可能な全ての色を表示する
	cc.Flags = CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT;
	
	// カラーダイアログを表示
	if(ChooseColor(&cc)){
		*p_crResult = cc.rgbResult;
		return TRUE;
	}
	return FALSE;
}

使い方

呼び出したいソースファイルの先頭で、

// インクルード
#include "DialogFunc.h"

と宣言してインクルードし、

ダイアログクラスCColorSampleDialogで、

ボタンおよびハンドラが2個あるとして、(OnButton1,OnButton2)

ボタン1でカスタム色を保持する色選択ダイアログを表示するなら、

void CColorSampleDlg::OnButton1() 
{
	COLORREF crSelected;
	COLORREF crFirst = RGB(133,133,122);
	// 最初の色を指定して呼び出し
	if( ColorDlg( this->m_hWnd, &crSelected, crFirst ,TRUE,NULL  ) )
	{
		// 色が選択されたとき		
	}

}

ボタン2でカスタム色を最初から指定して呼び出すなら

void CColorSampleDlg::OnButton2() 
{
	// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
	COLORREF crSelected;
	COLORREF crFirst = RGB(133,133,122);
	// カスタムカラー配列を最初から独自指定する場合
	static DWORD dwCustomColor[16];
	static int first = 1;
	// 最初の1回だけ実行
	if(first == 1)
	{
		for(int i=0; i < 16 ; i++)
		{
			// 肌色系の階のカスタムカラー配列にする
			dwCustomColor[i] = RGB(255, 150+ i*5, 100 + i* 5);	
		}

		first =2;
	}
	// カスタムカラー配列を独自指定して呼び出し
	if( ColorDlg( this->m_hWnd, &crSelected, crFirst ,TRUE, dwCustomColor ) )
	{
		
	}
}

というような感じで使います。


サンプル実行ファイル+プロジェクトファイルはこちらです。

VC++/カスタム色を使った色選択ダイアログの表示 - 情報処理研究所 ジャックズラボ(jack's Lab)

id:harunoharuno

いつも回答してありがとうございます。

早速教えていただいた方法を拝見し、

プログラムに組み込んでみました。

jack_sonic さんに教えていただいた

コーディングそのものだと、色の追加も正常に

に出来たのですが、

dwCustomColor[i] = RGB(255, 150+ i*5, 100 + i* 5);

dwCustomColor[i] = RGB(255, 255, 255);

の設定にし試したところ、以下の現象を確認しました。

・色の設定ダイアログを表示後、作成した色を選択すると、

 右側のカラーパレットから色を選んでも『色|純色』

 が変更されず、『色の追加』を押しても『作成した色』に反映されない。

これは何故なのでしょうか?

出来ればはじめの色は白にしたいと思っているのですが

無理なのでしょうか?

再度回答いただきたく宜しくお願いします。

[追記]

dwCustomColor[i] = RGB( 255, 255,230+i);

でやっても、『色の追加』を押しても『作成した色』に反映されない現象が発生しました。

これは何故なのでしょうか?jack_sonic

さんが初期設定の色として指定した

ものにルールがあるのならそれに付いても教えていただきたく宜しくお願いします。

2007/06/07 22:53:11
id:jack_sonic No.2

回答回数124ベストアンサー獲得回数25

ポイント100pt

>harunoharuno様 への返信

どうも、1の回答をしたjack_sonicです。

白にした場合は、プログラムのことではなく、

色選択ダイアログの操作上の注意点があります。

ちょっとわかりにくいのですが、

色選択ダイアログは、右側の縦の「明るさスライダー」と、

ポインタによって色合いを選択する「色合いパレット」

の2つによって色彩情報値を決定するという仕様を持っています。

白色が選ばれている状態だと、明るさ値が最大に設定されます。

色彩の法則で、明るさが最大の色=白色だけであるという法則があるために、

明るさスライダーが最大値にポイントされている状態ですと、

色合いパレットのポインタを操作しても色が変わることが

できません。

色選択ダイアログの仕様で、

白色から色を変える場合は、明るさスライダーを先に下げてから

操作することで色を変えられます。

図解いたします。

白色時の注意点

[f:id:jack_sonic:20070607222729j:image]


違うことでしたらすみません。また状況を教えてください。

id:harunoharuno

わーーーーーーっ。。。

驚きです。明るさが原因だったなんて、、、

試してみましたが、デフォルトの色が白でも

問題なく色の追加ができました。

いろいろ試していたけど、

ここが原因だったなんて、、、、、脱力しました。

でも、わかって救われました。ありがとうございます

願わくば、デフォルトを白にして

明るさの初期設定を低めにすることが出来たら嬉しいですが、

それは出来ませんよね?

[追記]

あっすいません。

あせってしまい訳の解らないこと言ってしまいました。

デフォルトの明るさは中間位置になっていますね。

明るい色を選択した後に明るさが最大になるようなので

これが嫌ならダイアログを作り直すしかなさそう・・・。

でもそこまでするものでもないし、標準的なものが一番よいし

カラーダイアログの仕様として理解しておきます。

何度も助けていただき本当に重ねて御礼いたしますm(_ _)m

2007/06/07 23:16:57
  • id:jack_sonic
    >harunoharuno様 (への返信)
    そうですね。
    明るさ最大と白は1:1で対応しているのと、
    色選択ダイアログの仕様があるためそうなります。

    上方が白になっている、
    1つのポインタ操作で選べるタイプの
    カラーパネル種もあるのですが、Win標準ではないので
    自作するか、どこかからコンポーネントを
    借りることになると思います。

    フックでできるかどうかわかりませんが、
    明るさが最大のときに左の
    カラーパレットを操作しようとしたときに
    警告を出す、というのも考えられますね。

    また、それらを使用しない方法としては、
    カスタムカラー配列を独自に持ち、
    色選択ダイアログを出す前に、
    白が1つでも入っているかどうか検査して、
    真っ白が1つでもあったら、
    「白から色を変えるときは明るさを先に下げて下さい~」
    (「以後表示しない」オプションをつけて)
    的なダイアログボックスで警告する、
    という手もあります。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません