In the Color common dialog box, users can change the current color or create their own colors. The basic dialog box, shown in Figure 6-8, contains a control that displays as many as 48 colors. The user's display driver determines the actual number of colors; for example, a VGA driver displays 48 colors, whereas a monochrome driver displays only 16.
Figure 6-8.
When the user clicks the Define Custom Colors button, the width of the dialog box expands to display the custom colors control, as shown in Figure 6-9 on the following page. With this control, the user can create a new color by specifying red, green, and blue (RGB) values; by using the color spectrum to set hue, saturation, and luminosity (HSL); or by specifying HSL values in the edit controls. After the user has created a custom color, clicking the Add To Custom Colors button displays the new color in a Custom Colors section of the dialog box. The Color|Solid control displays both the dithered color (a mixture of solids) and the solid color that correspond to the user's selection.
Figure 6-9.
The Color common dialog box uses two color models: RGB and HSL. Screen displays and other devices that emit light use the RGB model. Valid values for red, green, and blue are in the range 0 through 255, with 0 the minimum intensity and 255 the maximum intensity. The application should specify COLORREF values using the RGB macro for RGB colors.
The HSL color model uses different ranges of values. As you can see in Figure 6-10, the saturation and luminosity values must be in the range 0 through 240, and the hue value must be in the range 0 through 239. The Color common dialog procedure that is provided in COMDLG32.DLL converts HSL values to the corresponding RGB values, so your application does not have to do this.
Figure 6-10.
Before displaying a Color common dialog box, an application must initialize a CHOOSECOLOR structure, which contains information such as the parent of the dialog box, the custom colors that should appear initially, and the use of hooks and templates to customize the dialog box. The following code demonstrates how the CMNDLG32 sample fills out the CHOOSECOLOR structure and makes the subsequent call to ChooseColor, the function that displays and handles the dialog box. Notice again that certain fields are filled differently if a hook or a template is included. The custom colors array is initially filled entirely with white, whose RGB value is (0, 0, 0); the color initially selected is black, with an RGB value of (255, 255, 255).
BOOL ChooseNewColor (HWND hWnd)
{
DWORD dwColor;
DWORD dwCustClrs [16];
BOOL fSetColor = FALSE;
int i;
for (i = 0; i < 15; i++)
dwCustClrs [i] = RGB (255, 255, 255);
dwColor = RGB (0, 0, 0);
chsclr.lStructSize = sizeof (CHOOSECOLOR);
chsclr.hwndOwner = hWnd;
chsclr.hInstance = (HANDLE)hInst;
chsclr.rgbResult = dwColor;
chsclr.lpCustColors = (LPDWORD)dwCustClrs;
chsclr.lCustData = 0L;
switch (wMode)
{
case IDM_HOOK:
chsclr.Flags = CC_ENABLEHOOK;
chsclr.lpfnHook = (LPCCHOOKPROC)ChooseColorHookProc;
chsclr.lpTemplateName = (LPTSTR)NULL;
break;
case IDM_CUSTOM:
chsclr.Flags = CC_PREVENTFULLOPEN | CC_ENABLEHOOK |
CC_ENABLETEMPLATE;
chsclr.lpfnHook = (LPCCHOOKPROC)ChooseColorHookProc;
chsclr.lpTemplateName = "CHOOSECOLOR";
break;
case IDM_STANDARD:
chsclr.Flags = CC_PREVENTFULLOPEN;
chsclr.lpfnHook = (LPCCHOOKPROC)(FARPROC)NULL;
chsclr.lpTemplateName = (LPTSTR)NULL;
break;
}
if (fSetColor = ChooseColor (&chsclr))
{
crColor = chsclr.rgbResult;
return TRUE;
}
else
{
ProcessCDError (CommDlgExtendedError (), hWnd);
return FALSE;
}
}