GDI Colors |
|
The color is one the most fundamental objects that enhances the aesthetic appearance of an object. The color is a non-spatial object that is added to an object to modify some of its visual aspects. The MFC library, combined with the Win32 API, provides various actions you can use to take advantage of the various aspects of colors.
Converted to decimal, each one of these numbers would produce: 27 + 26 + 25 + 24 + 23 + 22 + 21 + 20 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255
Therefore, each number can have a value that ranges from 0 to 255 in the decimal system.
Converted to decimal, this number has a value of 255 * 255 * 255 = 16581375. This means that we can have approximately 16 million colors available. The question that comes to mind is how we use these colors, to produce what effect. You computer monitor has a surface that resembles a series of tinny horizontal and vertical lines. The intersection of a one horizontal line and a vertical line is called a pixel. This pixel holds, carries, or displays one color. As the pixels close to each other have different colors, the effect is a wonderful distortion that creates an aesthetic picture. It is by changing the colors of pixels that you produce the effect of color variances seen on pictures and other graphics.
Microsoft Windows considers that a color is a 32-bit numeric value. Therefore, a color is actually a combination of 32 bits:
The bits of the most significant byte (the left byte) are reserved for the operating system's internal use and must be set to 0. Based on this, each color is characterized by its combination of a red, a green, and a blue values.
When all three numbers have their lowest value, which is 0, the color is called black. When the numbers are at their highest value, which is 255, the color is called white. Not all color combinations have a name. In fact, in MS Windows programming, the names are very
limited (but this has nothing to do with the operating system). For this reason, colors are rarely called by a name and usually, a name would depend on who is using it. Nevertheless, there are popular names that most people recognize. Examples are Black, White, Red, Green, Blue, Yellow. Except for black and white, each color can assume different variations. For example, when all three numbers have the same value but neither 0 nor 255, the color is called Gray
and there are more than 250 possible combinations. Sometimes the combination is called Silver (each value is 192) or Gray (values=128). LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { COLORREF NewColor; switch(Msg) { case WM_DESTROY: PostQuitMessage(WM_QUIT); break; default: return DefWindowProc(hWnd, Msg, wParam, lParam); } return 0; } When, or after, declaring such a variable, you can initialize it with a 32-bit decimal value. Here is an example: LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { COLORREF NewColor = 16711935; switch(Msg) { case WM_DESTROY: PostQuitMessage(WM_QUIT); break; default: return DefWindowProc(hWnd, Msg, wParam, lParam); } return 0; } Although the above number (16711935) is a legitimate color value, it does not mean much. To create a color value, the Win32 API provides the RGB macro. Its syntax is: COLORREF RGB(BYTE byRed, BYTE byGreen, BYTE byBlue); The RGB macro behaves like a function and allows you to pass three numeric values separated by a comma. Each value must be between 0 and 255. Therefore, the above initialization can be done as follows: LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { COLORREF NewColor = RGB(255, 0, 255); switch(Msg) { case WM_DESTROY: PostQuitMessage(WM_QUIT); break; default: return DefWindowProc(hWnd, Msg, wParam, lParam); } return 0; } Whether a color was initialized with a 32-bit integer or using the RGB macro, if you want to retrieve the red, green, and blue values of a color, you can use the GetRValue(), the GetGValue(), of the GetBValue() macros to extract the value of each. The syntaxes of these macros are: BYTE GetRValue(DWORD rgb); BYTE GetGValue(DWORD rgb); BYTE GetBValue(DWORD rgb); Each macro takes a 32-bit value as argument, rgb:
Device independence is the ability for an application to draw its intended figures, text, shapes, and display colors regardless of the device on which the drawing is performed. One way to take care of this is to manage colors at the operating system level so that Microsoft Windows can select the right color to render an object or portion of it. In some cases, a device, such as a monitor or a printer, may need to take care of the coloring details of the jobs it is asked to perform.
A color palette is a list of colors that a device can display. Based on this, one device may be able to handle only two colors; such is the case for a black and white printer. Another device could be able to use more colors than that. To control this situation, Microsoft Windows keeps track of the color palette of each device installed on the computer.
As mentioned above, a pixel is the real object that holds a color. Although it is so small, you can access a pixel and change its color. The pixels are stored in an array of [x][y] values. In fact, when you try accessing a pixel, you would be asked to provide a color for it. To change the color of a pixel, you can call the SetPixel() function. Its syntax is: COLORREF SetPixel(HDC hdc, int X, int Y, COLORREF crColor); The pixel you want to access is defined by its X and Y coordinates. The color you want to specify is the crColor argument.
By default, the device context is able to draw text using a font pre-selected, known as the System Font. To draw text, you can use the TextOut() method. Its syntax is: BOOL TextOut(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString); To use this funuction, you must specify where the text would start. This location is determined from the (0, 0) origin to the nXStart and to the nYStart values. The text to display is the lpString string. The cbString value is the length of the text. Here is an example: #include <windows.h> LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndCls; static char szAppName[] = "GDISuite"; MSG Msg; WndCls.cbSize = sizeof(WndCls); WndCls.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; WndCls.lpfnWndProc = WindProcedure; WndCls.cbClsExtra = 0; WndCls.cbWndExtra = 0; WndCls.hInstance = hInstance; WndCls.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndCls.hCursor = LoadCursor(NULL, IDC_ARROW); WndCls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); WndCls.lpszMenuName = NULL; WndCls.lpszClassName = szAppName; WndCls.hIconSm = LoadIcon(hInstance, IDI_APPLICATION); RegisterClassEx(&WndCls); CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, szAppName, "GDI Accessories and Tools", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); while( GetMessage(&Msg, NULL, 0, 0) ) { TranslateMessage(&Msg); DispatchMessage( &Msg); } return static_cast<int>(Msg.wParam); } LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { HDC hDC; PAINTSTRUCT Ps; switch(Msg) { case WM_DESTROY: PostQuitMessage(WM_QUIT); break; case WM_PAINT: hDC = BeginPaint(hWnd, &Ps); TextOut(hDC, 50, 42, "Johnny Carson", 13); EndPaint(hWnd, &Ps); break; default: return DefWindowProc(hWnd, Msg, wParam, lParam); } return 0; }
COLORREF SetTextColor(HDC hdc, COLORREF crColor); The crColor argument can be provided as a COLORREF variable or by calling the RGB macro. is an example: LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { HDC hDC; PAINTSTRUCT Ps; COLORREF clrRedish = RGB(255, 25, 2); switch(Msg) { case WM_DESTROY: PostQuitMessage(WM_QUIT); break; case WM_PAINT: hDC = BeginPaint(hWnd, &Ps); SetTextColor(hDC, clrRedish); TextOut(hDC, 50, 42, "Johnny Carson", 13); EndPaint(hWnd, &Ps); break; default: return DefWindowProc(hWnd, Msg, wParam, lParam); } return 0; } As you will see from now on concerning the device context, once you change one of its characteristics, it stays there until you change it again. It is similar to picking a spoon and start eating. As long as you are eating, you can use the spoon you are holding and only that spoon. It you want to cut the meat, you must replace the spoon in your hand with a knife. In the same way, if you change the color of text and draw more than one line of text, all of them would use the same color. If you want to use a different color, you must change the color used by calling the SetTextColor() method again. Here is an example: LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { HDC hDC; PAINTSTRUCT Ps; COLORREF clrRed = RGB(255, 25, 5); COLORREF clrBlue = RGB(12, 25, 255); switch(Msg) { case WM_DESTROY: PostQuitMessage(WM_QUIT); break; case WM_PAINT: hDC = BeginPaint(hWnd, &Ps); SetTextColor(hDC, clrRed); TextOut(hDC, 50, 42, "Johnny Carson", 13); SetTextColor(hDC, clrBlue); TextOut(hDC, 50, 80, "The once king of late-night", 27); EndPaint(hWnd, &Ps); break; default: return DefWindowProc(hWnd, Msg, wParam, lParam); } return 0; } If you want to highlight the text, which is equivalent to changing its background, you can call the SetBkColor() function. Its syntax is: COLORREF SetBkColor(HDC hdc, COLORREF crColor); You must provide the color you want to use as the crColor argument. If this function succeeds, it changes the background of the next text that would be drawn and it returns the previous background color, which you can restore at a later time. Here is an example: LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { HDC hDC; PAINTSTRUCT Ps; COLORREF clrRed = RGB(255, 25, 5); COLORREF clrAqua = RGB(0, 255, 255); COLORREF clrNavy = RGB(0, 0, 128); switch(Msg) { case WM_DESTROY: PostQuitMessage(WM_QUIT); break; case WM_PAINT: hDC = BeginPaint(hWnd, &Ps); SetBkColor(hDC, RGB(255, 255, 255)); SetTextColor(hDC, clrRed); TextOut(hDC, 50, 42, "Johnny Carson", 13); SetBkColor(hDC, clrNavy); SetTextColor(hDC, clrAqua); TextOut(hDC, 50, 80, "The once king of late-night", 27); EndPaint(hWnd, &Ps); break; default: return DefWindowProc(hWnd, Msg, wParam, lParam); } return 0; } If you want to know the background color applied on a drawn string, you can call the GetBkColor() function. Its syntax is: COLORREF GetBkColor(HDC hdc); This function returns the color used to highlight the text, if the text is highlighted. The highlighting of text is actually controlled by the SetBkMode() function whose syntax is: int SetBkMode(HDC hdc, int iBkMode); This function specifies whether the background color should be applied or not. This is set by the iBkMode argument. It can have one of two values. If it is:
If you want to find out what background mode is applied to the string(s) drawn, you can call the GetBkMode() method. It is declared as follows: int GetBkMode(HDC hdc); You can also draw text and include it in a (colored) rectangle. This can be done using the ExtTextOut() function. Its syntax is: BOOL ExtTextOut(HDC hdc, int X, int Y, UINT fuOptions, CONST RECT *lprc, LPCTSTR lpString, UINT cbCount, CONST INT *lpDx); The X and Y values specify the location of the first character of the text to be drawn. The fuOptions argument holds a constant that determines how the rectangle will be drawn. It can be:
The lprc is a RECT or CRect rectangle that will be drawn behind the text. The lpString value is the text to be drawn. The cbCount is the number of characters of lpString. The lpDx argument is an array of integers that specifies the amount of empty spaces that will be used between each combination of two characters. Unless you know what you are doing, pass this argument as 0, in which case the regular space used to separate characters would be used. Here is an example: LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { HDC hDC; PAINTSTRUCT Ps; COLORREF clrBlue = RGB(25, 55, 200); RECT Recto = { 20, 28, 188, 128 }; COLORREF clrAqua = RGB(128, 255, 255); switch(Msg) { case WM_DESTROY: PostQuitMessage(WM_QUIT); break; case WM_PAINT: hDC = BeginPaint(hWnd, &Ps); SetTextColor(hDC, clrBlue); SetBkColor(hDC, clrAqua); ExtTextOut(hDC, 50, 42, ETO_OPAQUE, &Recto, "Johnny Carson", 13, NULL); EndPaint(hWnd, &Ps); break; default: return DefWindowProc(hWnd, Msg, wParam, lParam); } return 0; }
|
|
|
||
Previous | Copyright © 2003 FunctionX, Inc. | Next |
|