【VBA×WindowsAPI】[色の設定]ダイアログを表示する
VBAマクロ開発時にユーザーに色を選択させたいという場面に出くわすことがあります。Excel VBAの場合、組み込みダイアログ「Application.Dialogs(xlDialogEditColor).Show()」を利用することで色選択のダイアログを表示させることができます。ただし、この組み込みダイアログはアプリケーションによってはサポートされていないものもあるため、利用できないケースがあります。
色選択ダイアログをUserFormを使って0から作るとかなりの労力ですが、色選択のダイアログ自体はWindowsの標準機能として用意されており、WindowsAPIを使うことでそのダイアログをVBAで呼び出すことが可能です。WindowsAPIの場合はアプリケーションによる利用制限は無くなるので、どのアプリケーションのVBAからも呼び出すことが可能です。そのため組み込みダイアログが利用できないアプリケーションでの色選択の1つの手段として非常に役立つ機能となっています。
[色の設定]ダイアログを表示する
Windowsにはどのアプリケーションからでもアクセスすることのできる「コモンダイアログ」というUI(ユーザインターフェース)が用意されています。コモンダイアログにはファイル選択ダイアログや検索ダイアログ、印刷ダイアログ、フォントダイアログなどの汎用的なダイアログが用意されており、メモ帳やペイントなどのWindows標準アプリケーションのダイアログとしても利用されています。
その中でも[色の設定]ダイアログボックスは名前の通り、ユーザが色を選択するためのダイアログです。VBAの「Application.Dialogs(xlDialog~).Show」でも同じような処理は可能ですが、ダイアログの見た目や使い勝手がWindowsAPIとは少し異なります。
VBAでクリップボード内の文字列を取得するには下記のWindows APIを利用します。
また、関数の引数として「CHOOSECOLOR構造体」という構造体を定義する必要があります。
ChooseColor関数 :[色]ダイアログボックスを表示する
「そもそもWindows APIって何?」という方はコチラ(メインページ)も併せて参照下さい。
サンプルコード
VBAでコモンダイアログの[色の設定]ダイアログを表示するためのサンプルコードは下記の通りです。
下記コードを標準モジュールにコピペして実行すると、[色の設定]ダイアログが表示されます。ダイアログで選択した色のカラーコードが取得され、アクティブシートのA1セルを選択した色に着色します。[色の設定]ダイアログではデフォルトカラーの選択だけでなく色の作成を行うことも可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
Option Explicit Private Declare PtrSafe Function ChooseColor Lib "comdlg32.dll" Alias "ChooseColorA" (pChoosecolor As CHOOSE_COLOR) As Long 'CHOOSECOLOR用構造体 Private Type CHOOSE_COLOR lStructSize As Long hwndOwner As LongPtr hInstance As LongPtr rgbResult As Long lpCustColors As LongPtr flags As Long lCustData As LongPtr lpfnHook As LongPtr lpTemplateName As String End Type Const CC_FULLOPEN = &H2 '[色の作成]部分を拡張して表示する Const CC_PREVENTFULLOPEN = &H4 '[色の作成]ボタンを無効にする Const CC_RGBINIT = &H1 'rgbResultにセットした色を初期の選択色とする 'Const CC_SHOWHELP = &H8 'Const CC_ANYCOLOR = &H100 'Const CC_ENABLEHOOK = &H10 'Const CC_ENABLETEMPLATE = &H20 'Const CC_ENABLETEMPLATEHANDLE = &H40 'Const CC_SOLIDCOLOR = &H80 Sub main() Dim lColor As Long lColor = RGB(255, 255, 255) If ChooseColorDialog(lColor) = True Then 'A1セルにダイアログで選択された色をセットする ThisWorkbook.ActiveSheet.Cells(1, 1).Interior.Color = lColor Debug.Print Hex(lColor) End If End Sub '---------------------------------------------------------------------------------- '- [色の選択]ダイアログの表示 '- lColor : 初期選択カラー / ユーザ選択カラーの戻り値 '- (hWnd) : 親ウィンドウのハンドル(通常は呼び出し元のアプリケーションのハンドル) '---------------------------------------------------------------------------------- Private Function ChooseColorDialog(ByRef lColor As Long, Optional ByVal hWnd As LongPtr = 0) As Boolean Static lCustColors(0 To 15) As Long 'カスタムカラーを保持するため静的変数 Static flgInit As Boolean Dim tChooseColor As CHOOSE_COLOR Dim lFlg As Long Dim i As Long '初期化フラグの設定(複合の場合は[Or]) lFlg = CC_RGBINIT Or CC_FULLOPEN '初回起動時のみ[作成した色]をすべて白色にセット If flgInit = False Then For i = 0 To UBound(lCustColors) lCustColors(i) = RGB(255, 255, 255) Next flgInit = True End If 'ダイアログ初期設定 With tChooseColor .lStructSize = LenB(tChooseColor) '構造体のサイズ .hwndOwner = hWnd 'オーナー(親)ウィンドウのハンドル .rgbResult = lColor '初期選択カラー(&ユーザー選択カラーの受け取り) .lpCustColors = VarPtr(lCustColors(0)) '[作成した色]のカラーコードを格納した配列ポインタ .flags = lFlg 'ダイアログの初期化フラグ End With If ChooseColor(tChooseColor) = 0 Then ChooseColorDialog = False Else lColor = tChooseColor.rgbResult ChooseColorDialog = True End If End Function |
コード解説
CHOOSECOLOR構造体の設定
[色の設定]ダイアログを表示するためのChooseColor関数には引数としてCHOOSECOLOR構造体を入力しますが、この構造体の値によって[色の設定]ダイアログの初期設定を変更することができます。
構造体の要素は多くありますが下記の要素を入力しておけば問題ありません。
関数名 | 内容 |
lStructSize | 構造体のサイズ |
hwndOwner | 親ウィンドウのハンドル |
rgbResult | ダイアログの色情報 |
lpCustColors | [作成した色]の値の配列へのポインタ |
flags | ダイアログボックスの初期化に使用可能なフラグ |
lStructSizeは構造体のサイズを指定するための要素でLenB関数で取得した値を入力します。
hwndOwnerは[色の設定]ダイアログを属させる親ウィンドウのハンドルを入力します。値を入力しなかった場合、[色の設定]ウィンドウは独立したウィンドウとして表示されます。通常はFindWindow関数などを使って取得したアプリケーション(Excel等)のウィンドウを親として設定します。
rgbResultは[色の設定]ダイアログ内で選択されている色の値を保持する要素で、初期選択色(ダイアログ起動時に選択される色)が設定可能です。flagsで設定する値にCC_RGBINITが設定されている場合、この要素に入力された値の色が初期値となります。このとき入力した色の値が使用可能な色の中にない場合は、使用可能な最も近い純色が初期選択色となります。 rgbResultが0の場合、もしくはCC_RGBINITが設定されていない場合、ダイアログの初期選択色は黒色となります。
lpCustColorsは[色の設定]ダイアログ上でユーザーが任意で設定可能な[作成した色]の情報を格納するための配列のポインタを入力します。配列のポインタはVarPtr関数に配列の0番目の要素を入力することで取得することができます。このとき、この配列は値保持のためStaticステートメントを使って宣言しておく必要があります。また初期値として白色を設定していますが未入力の場合は黒色となります。予め各16要素にそれぞれ任意の色を設定しておくことも可能です。
flagsにはダイアログ作成時の設定に関するフラグ値を入力します。基本的には下記の3つさえ知っておけば問題ありません。(※その他のフラグはCHOOSECOLOR構造体ページ参照)
定数値 | 意味 |
CC_FULLOPEN = &H2 | [色の作成]部分を拡張して表示する |
CC_PREVENTFULLOPEN = &H4 | [色の作成]ボタンを無効にする |
CC_RGBINIT = &H1 | rgbResultにセットされている色を初期の選択色とする |
これら定数値をflagsに入力することで各種設定をおこなうことができます。
フラグを複数設定する場合はサンプルコードの通りOR演算子を使って指定します。
[色の設定]ダイアログの表示
[色の設定]ダイアログを表示するにはChooseColor関数にはを使い下記のように記載します。
lRet = ChooseColor(tChooseColor)
引数には前項で設定したCHOOSECOLOR構造体を入力します。戻り値はダイアログの[OK]ボタンが押されたら0以外の数値が返されます。
ダイアログ上で色の選択が行われると、引数で入力したCHOOSECOLOR構造体のrgbResultの値が選択された色の値に上書きされます。つまりダイアログの[OK]ボタンが押されたあとに、構造体のrgbResultの値を取得すればユーザーが選択した色を取得したことになります。
関連情報
VBA×WindowsAPIまとめページ
その他のWindowsAPI関数は下記ページにまとまっているので合わせて参照下さい。
参考
Microsoft公式:[色] ダイアログ ボックス – Win32 apps