|
| БЕСПЛАТНАЯ ежедневная online лотерея! Выигрывай каждый день БЕСПЛАТНО! |
|
|
Using Brushes
You can use a brush to paint the interior of virtually any shape by using a GDI function. This includes the interiors of rectangles, ellipses, polygons, and paths. Depending on the requirements of your application, you can use a solid brush of a specified color, a stock brush, a hatch brush, or a pattern brush.
This section contains code samples that demonstrate the creation of a custom brush dialog box. The dialog box contains a grid that represents the bitmap Windows uses as a brush. A user can use this grid to create a pattern-brush bitmap and then view the custom pattern by clicking the Test Pattern button. The following illustration shows a pattern created by using the Custom Brush dialog box.
To display a dialog box, you must first create a dialog box template. The following dialog box template defines the Custom Brush dialog box.
CustBrush DIALOG 6, 18, 160, 118 STYLE WS_DLGFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION CAPTION "Custom Brush" FONT 8, "MS Sans Serif" BEGIN CONTROL "", IDD_GRID, "Static", SS_BLACKFRAME | WS_CHILD, 3, 2, 83, 79 CONTROL "", IDD_RECT, "Static", SS_BLACKFRAME | WS_CHILD, 96, 11, 57, 28 PUSHBUTTON "Test Pattern", IDD_PAINTRECT, 96, 47, 57, 14 PUSHBUTTON "OK", IDD_OK, 29, 98, 40, 14
PUSHBUTTON "Cancel", IDD_CANCEL, 92, 98, 40, 14 END
The Custom Brush dialog box contains five controls: a bitmap-grid window, a pattern-viewing window, and three push buttons, labeled Test Pattern, OK and Cancel. The Test Pattern push button enables the user to view the pattern. The dialog box template specifies the overall dimensions of the dialog box window, assigns a value to each control, specifies the location of each control, and so forth. (For more information about creating dialog box templates, see Dialog Boxes.)
The control values in the dialog box template are constants that have been defined as follows in the application's header file.
#define IDD_GRID 120 #define IDD_RECT 121 #define IDD_PAINTRECT 122 #define IDD_OK 123 #define IDD_CANCEL 124
After you create a dialog box template and include it in the application's resource-definition file, you must write a dialog procedure. This procedure processes messages that Windows sends to the dialog box. The following excerpt from an application's source code shows the dialog box procedure for the Custom Brush dialog box and the two application-defined functions it calls.
int APIENTRY BrushDlgProc(HWND hdlg, WORD message, LONG wParam, LONG lParam) { static HWND hwndGrid; /* grid-window control */ static HWND hwndBrush; /* pattern-brush control */ static RECT rctGrid; /* grid-window rectangle */ static RECT rctBrush; /* pattern-brush rectangle */ static UINT bBrushBits[8]; /* bitmap bits */ static RECT rect[64]; /* grid-cell array */
static HBITMAP hbm; /* bitmap handle */ HBRUSH hbrush; /* current brush */ HBRUSH hbrushOld; /* default brush */ HRGN hrgnCell; /* test-region handle */ HDC hdc; /* DC handle */ int x, y, deltaX, deltaY; /* drawing coordinates */ POINTS ptlHit; /* mouse coordinates */ int i; /* count variable */
switch (message) { case WM_INITDIALOG: /* * Retrieve a window handle for the grid-window and * pattern-brush controls */ hwndGrid = GetDlgItem(hdlg, IDD_GRID); hwndBrush = GetDlgItem(hdlg, IDD_RECT); /* Initialize the array of bits that defines the * custom brush pattern with the value 1 to produce a * solid white brush).
*/ for (i=0; i<8; i++) bBrushBits[i] = 0xFF; /* * Retrieve dimensions for the grid-window and pattern-brush * controls. */ GetClientRect(hwndGrid, &rctGrid); GetClientRect(hwndBrush, &rctBrush); /* Determine the width and height of a single cell. */ deltaX = (rctGrid.right - rctGrid.left)/8; deltaY = (rctGrid.bottom - rctGrid.top)/8;
/* Initialize the array of cell rectangles. */ for (y=rctGrid.top, i=0; y < rctGrid.bottom; y += deltaY){ for (x=rctGrid.left; x < (rctGrid.right - 8) && i < 64; x += deltaX, i++) { rect[i].left = x; rect[i].top = y; rect[i].right = x + deltaX; rect[i].bottom = y + deltaY; } } return FALSE;
case WM_PAINT: /* Draw the grid. */ hdc = GetDC(hwndGrid); for (i=rctGrid.left; i i+=(rctGrid.right - rctGrid.left)/8){ MoveToEx(hdc, i, rctGrid.top, NULL); LineTo(hdc, i, rctGrid.bottom); } for (i=rctGrid.top; i i+=(rctGrid.bottom - rctGrid.top)/8){ MoveToEx(hdc, rctGrid.left, i, NULL);
LineTo(hdc, rctGrid.right, i); } ReleaseDC(hwndGrid, hdc); return FALSE; case WM_LBUTTONDOWN: /* Store the mouse coordinates in a POINT structure. */ ptlHit = MAKEPOINTS((POINTS FAR *)lParam); /* * Create a rectangular region with dimensions and * coordinates that correspond to those of the grid * window.
*/ hrgnCell = CreateRectRgn(rctGrid.left, rctGrid.top, rctGrid.right, rctGrid.bottom); /* Retrieve a window DC for the grid window. */ hdc = GetDC(hwndGrid); /* Select the region into the DC. */ SelectObject(hdc, hrgnCell); /* Test for a button click in the grid-window rectangle. */ if (PtInRegion(hrgnCell, ptlHit.x, ptlHit.y)){
/* * A button click occurred in the grid-window rectangle; * isolate the cell in which it occurred. */ for(i=0; i<64; i++){ DeleteObject(hrgnCell); hrgnCell = CreateRectRgn(rect[i].left, rect[i].top, rect[i].right, rect[i].bottom); if (PtInRegion(hrgnCell, ptlHit.x, ptlHit.y)){
InvertRgn(hdc, hrgnCell); /* Set the appropriate brush bits. */ if (i % 8 == 0) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x80; else if (i % 8 == 1) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x40; else if (i % 8 == 2) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x20;
else if (i % 8 == 3) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x10; else if (i % 8 == 4) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x08; else if (i % 8 == 5) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x04; else if (i % 8 == 6) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x02;
else if (i % 8 == 7) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x01; /* Exit the "for" loop after the bit is set. */ break; } /* end if */ } /* end for */ } /* end if */ /* Release the DC for the control. */ ReleaseDC(hwndGrid, hdc); return TRUE; case WM_COMMAND:
switch (wParam){ case IDD_PAINTRECT: hdc = GetDC(hwndBrush); /* Create a monochrome bitmap. */ hbm = CreateBitmap(8, 8, 1, 1, (LPBYTE)bBrushBits); /* Select the custom brush into the DC. */ hbrush = CreatePatternBrush(hbm); hbrushOld = SelectObject(hdc, hbrush);
/* Use the custom brush to fill the rectangle. */ Rectangle(hdc, rctBrush.left, rctBrush.top, rctBrush.right, rctBrush.bottom); /* Clean up memory. */ SelectObject(hdc, hbrushOld); DeleteObject(hbrush); DeleteObject(hbm); ReleaseDC(hwndBrush, hdc); return TRUE;
case IDD_OK: case IDD_CANCEL: EndDialog(hdlg, TRUE); return TRUE; } /* end switch */ break; default: return FALSE; } } int GetStrLngth(LPTSTR cArray) { int i = 0; while (cArray[i++] != 0); return i-1; } DWORD RetrieveWidth(LPTSTR cArray, int iLength) { int i, iTmp; double dVal, dCount;
dVal = 0.0; dCount = (double)(iLength-1); for (i=0; i iTmp = cArray[i] - 0x30; dVal = dVal + (((double)iTmp) * pow(10.0, dCount--)); } return (DWORD)dVal; }
The dialog box procedure for the Custom Brush dialog box processes four messages, as described in the following table.
Message Action WM_INITDIALOG Retrieves a window handle and dimensions for the grid-window and pattern-brush controls, computes the dimensions of a single cell in the grid-window control, and initializes an array of grid-cell coordinates. WM_PAINT Draws the grid pattern in the grid-window control. WM_LBUTTONDOWN Determines whether the cursor is within the grid-window control when the user presses the left mouse button. If so, the dialog box procedure inverts the appropriate grid cell and records the state of that cell in an array of bits that is used to create the bitmap for the custom brush. WM_COMMAND Processes input for the three push button controls. If the user presses the Test Pattern button, the dialog box procedure paints the Test Pattern control with the new custom brush pattern. If the user presses the OK or Cancel button, the dialog box procedure performs actions accordingly.
For more information about messages and message processing, see Messages and Message Queues. After you write the dialog box procedure, export it in the module-definition file, include the function definition for the procedure in the application's header file, and then call the dialog box procedure at the appropriate point in the application. The following excerpt from the module-definition file shows how the dialog box procedure for the Custom Brush is exported.
; Export all functions that are called by a Windows routine. EXPORTS MainWndProc @1 ; name of window processing function BrushDlgProc @2 ; name of custom-brush processing function
The following excerpt from the application's header file shows the function definition for the dialog box procedure and the two functions it calls.
int APIENTRY BrushDlgProc(HWND hdlg, WORD message, LONG wParam, LONG lParam); int GetStrLngth(LPTSTR cArray); DWORD RetrieveWidth(LPTSTR cArray, int iLength);
Finally, the following code shows how the dialog box procedure is called from the application's source-code file. In this example, the dialog box procedure is called when the user chooses an option from the application's menu.
switch (message) { case WM_CREATE: break; case WM_COMMAND: // command from application menu switch(wParam) { case IDM_CUSTOMBRUSH: DialogBox((HANDLE)GetModuleHandle(NULL), (LPTSTR)"CustBrush", hWnd, (DLGPROC)BrushDlgProc); break;
| Пригласи друзей и счет твоего мобильника всегда будет положительным! |
| Пригласи друзей и счет твоего мобильника всегда будет положительным! |
Использование Щеток
Вы можете использовать щетку, чтобы закрашивать внутренность фактически любой формы используя функцию GDI. Это включает внутренности прямоугольников, эллипсов, многоугольников, и путей. В зависимости от требований вашего приложения, Вы можете использовать твердую щетку определенного цвета, фондовая щетка, щетка люка, или щетку образца.
Эта секция содержит кодовые образцы, которые демонстрируют создание диалогового ящика заказной щетки. Диалоговый ящик содержит сетку, которая представляет Окно побитового отображения использует как щетка. Потребитель может использовать эту сетку, чтобы создавать образец-щетку побитового отображения затем рассматривать заказной образец щелкая кнопку Образца Теста. Следующая иллюстрация показывает образец созданный использованием диалогового ящика Заказной Щетки.
Чтобы отображать диалоговый ящик, Вы должны сначала создать диалоговый шаблон ящика. Шаблон диалогового ящика следующего определяет диалоговый ящик Заказной Щетки.
ДИАЛОГ CustBrush 6, 18, 160, 118 STYLE WS_DLGFRAME | WS_POPUP | WS_VISIBLE | ЗАГОЛОВОК WS_CAPTION "Заказная Щетка" ШРИФТА 8, "Засечка МС Sans" НАЧИНАЕТСЯ УПРАВЛЕНИЕ "", IDD_GRID, "Статический", SS_BLACKFRAME | WS_CHILD, 3, 2, 83, 79 УПРАВЛЕНИЯ "", IDD_RECT, "Статический", SS_BLACKFRAME | WS_CHILD, 96, 11, 57, 28 КНОПОК "Образца Теста", IDD_PAINTRECT, 96, 47, 57, 14 КНОПОК "OK", IDD_OK, 29, 98, 40, 14
КНОПКА "Отмены", IDD_CANCEL, 92, 98, 40, 14 КОНЦОВ
Диалоговый ящик Заказной Щетки содержит пять элементов управления: побитовое отображение окна-сетка, образец-просмотр окна, и три кнопка, пометившее Тест Образца, OK и Отмена. Кнопка Образца Теста позволяет потребителя, чтобы рассматривать образец. Диалоговый шаблон ящика определяет общие измерения диалогового окна ящика, назначает величину на каждое управление, определяет позицию каждого управления, и так далее. (Более подробно о создании диалоговых шаблонов ящика, смотри Диалог Boxes.)
Управление оценивается в диалоговом шаблоне ящика - константы, которые определяются следующим образом в прикладном файле заголовка.
#define IDD_GRID 120 #define IDD_RECT 121 #define IDD_PAINTRECT 122 #define IDD_OK 123 #define IDD_CANCEL 124
После того, как Вы создадите диалоговый шаблон ящика и включите это в прикладном ресурсе-определении файла, Вы должны написать диалоговую процедуру. Эта процедура обрабатывает сообщения, которые Окно посылает в диалоговый ящик. Следующий отрывок из прикладного исходного кода показывает диалоговой процедуре ящика для диалогового ящика Заказной Щетки и двух определенных прикладных функции, которые он вызывает.
int APIENTRY BrushDlgProc(HWND hdlg, ТЕКСТОВОЕ сообщение, ДОЛГО (ДЛИНОЙ) wParam, ДОЛГО (ДЛИНОЙ) lParam) { статический HWND hwndGrid; /* сетка-окно управления */ статический HWND hwndBrush; /* образец-щетка управления */ статический RECT rctGrid; /* сетка-окно прямоугольника */ статический RECT rctBrush; /* образец-щетка прямоугольника */ статический UINT bBrushBits[8]; /* биты побитового отображения */ статический RECT rect[64]; /* сетка-ячейка массива */
статический hbm HBITMAP; /* ручка побитового отображения */ HBRUSH hbrush; /* текущая щетка */ HBRUSH hbrushOld; /* встроенная щетка */ HRGN hrgnCell; /* тест-регион ручки */ hdc HDC; /* РУЧКА DC */ int x, y, deltaX, deltaY; /* рисуя координаты */ ТОЧКИ ptlHit; /* координаты мыши */ int i; /* переменная счета */
ключ (сообщение) { случай WM_INITDIALOG: /* * Извлеките ручку окна для сетки-окна и * образец-щетка регулируется */ hwndGrid = GetDlgItem(hdlg, IDD_GRID); hwndBrush = GetDlgItem(hdlg, IDD_RECT); /* Инициализируйте массив битов, которые определяют the * заказной образец щетки с величиной 1, чтобы производить a * твердая белая щетка).
*/ для (i=0; i<8; я++) bBrushBits[i] = 0xFF; /* * Извлеките измерениям для сетки-окна и образца-щетка * элементы управления. */ GetClientRect(hwndGrid, &rctGrid); GetClientRect(hwndBrush, &rctBrush); /* Определите ширину и высоту единственного cell. */ deltaX = (rctGrid.right - rctGrid.left)/8; deltaY = (rctGrid.bottom - rctGrid.top)/8;
/* Инициализируйте массив ячейки rectangles. */ для (y=rctGrid.top, i=0; y < rctGrid.bottom; y += deltaY){ для (x=rctGrid.left; x < (rctGrid.right - 8) && я < 64; x += deltaX, я++) { rect[x i].left =; rect[y i].top =; rect[i].right = x + deltaX; rect[i].bottom = y + deltaY; } } обратная ЛОЖЬ;
случай WM_PAINT: /* Сделайте grid. */ hdc = GetDC(hwndGrid); для (i=rctGrid.left; i i+=(rctGrid.right - rctGrid.left)/8){ MoveToEx(hdc, я, rctGrid.top, НЕДЕЙСТВИТЕЛЬНЫЙ); LineTo(hdc, Я, rctGrid.bottom); } для (i=rctGrid.top; i i+=(rctGrid.bottom - rctGrid.top)/8){ MoveToEx(hdc, rctGrid.left, я, НЕДЕЙСТВИТЕЛЬНЫЙ);
LineTo(hdc, rctGrid.right, Я); } ReleaseDC(hwndGrid, hdc); обратная ЛОЖЬ; случай WM_LBUTTONDOWN: /* Сохраните координаты мыши в ТОЧКЕ structure. */ ptlHit = MAKEPOINTS((ТОЧКИ ЗНАЧИТЕЛЬНО *)lParam); /* * Создайте прямоугольный регион с измерениями и * координаты, что переписываться в сетки * окно.
*/ hrgnCell = CreateRectRgn(rctGrid.left, rctGrid.top, rctGrid.right, rctGrid.bottom); /* Извлеките окно DC для сетки window. */ hdc = GetDC(hwndGrid); /* Выберитесь регион в DC. */ SelectObject(hdc, hrgnCell); /* Протестируйте щелчок кнопки в сетке-окне rectangle. */ если (PtInRegion(hrgnCell, ptlHit.x, ptlHit.y)){
/* * Щелчок кнопки происходил в сетке-окне прямоугольника; * изолируйте ячейку в которой он произойден. */ для(i=0; i<64; я++){ DeleteObject(hrgnCell); hrgnCell = CreateRectRgn(rect[i].left, rect[i].top, rect[i].right, rect[i].bottom); если (PtInRegion(hrgnCell, ptlHit.x, ptlHit.y)){
InvertRgn(hdc, hrgnCell); /* Установите подходящую щетку bits. */ если (я % 8 == 0) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x80; еще если (я % 8 == 1) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x40; еще если (я % 8 == 2) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x20;
еще если (я % 8 == 3) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x10; еще если (я % 8 == 4) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x08; еще если (я % 8 == 5) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x04; еще если (я % 8 == 6) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x02;
еще если (я % 8 == 7) bBrushBits[i/8] = bBrushBits[i/8] ^ 0x01; /* Выходите из цикла "для" после того, как бит явится set. */ прерывание; } /* конец если */ } /* конец для */ } /* конец если */ /* Выпустите DC для control. */ ReleaseDC(hwndGrid, hdc); возвращайтесь ВЕРНО; случай WM_COMMAND:
ключ (wParam){ случай IDD_PAINTRECT: hdc = GetDC(hwndBrush); /* Создайте монохромный bitmap. */ hbm = CreateBitmap(8, 8, 1, 1, (LPBYTE)bBrushBits); /* Выберитесь заказную щетку в DC. */ hbrush = CreatePatternBrush(hbm); hbrushOld = SelectObject(hdc, hbrush);
/* Используйте заказную щетку, чтобы заполнять rectangle. */ Прямоугольник(hdc, rctBrush.left, rctBrush.top, rctBrush.right, rctBrush.bottom); /* Наведите порядок memory. */ SelectObject(hdc, hbrushOld); DeleteObject(hbrush); DeleteObject(hbm); ReleaseDC(hwndBrush, hdc); возвращайтесь ВЕРНО;
случай IDD_OK: случай IDD_CANCEL: EndDialog(hdlg, ИСТИНА); возвращайтесь ВЕРНО; } /* конечный ключ */ прерывание; невыполнение: обратная ЛОЖЬ; } } int GetStrLngth(LPTSTR cArray) { int i = 0; пока (cArray[я++] != 0); возврат i-1; } DWORD RetrieveWidth(LPTSTR cArray, int iLength) { int я, iTmp; удвойте dVal, dCount;
dVal = 0.0; dCount = (double)(iLength-1); для (i=0; i dVal = dVal + (((double)iTmp) * Военнопленные(10.0, dCount--)); } возврат (DWORD)dVal; }
Диалоговая процедура ящика для диалогового ящика Заказных процессов Щетки четырех сообщения, как описано на следующем столе.
Действие Сообщения WM_INITDIALOG Извлекает ручку окна и измерений для сетки-окна и элементы управления образца-щетка, вычисляет измерения единственной ячейки в сетке-окне управления и инициализирует массив сетки-ячейки координат. WM_PAINT Делает образцом сетки в сетке-окне управления. WM_LBUTTONDOWN Определяет независимо курсор - в пределах сетки-окна управления когда потребитель нажимает левую кнопку мыши. Если так, диалоговая процедура ящика инвертирует подходящую ячейку сетки и записывает состояние этой ячейки в массив битов, который использован, чтобы создавать побитовое отображение для заказной щетки. WM_COMMAND Обрабатывает вклад для трех элементов управления кнопки. Если потребитель нажимает кнопку Образца Теста, диалоговая процедура ящика изображает управление Образца Теста новым заказным образцом щетки. Если потребитель нажимает OK или кнопка Отмены, диалоговая процедура ящика выполняет действия соответственно.
Более подробно о сообщениях и сообщении, обрабатывающих, смотри Очереди Сообщений и Сообщения. После того, как Вы напишете диалоговую процедуру ящика, экспортируйте это в модульном определении файла, включите функциональное определение для процедуры в прикладном файле заголовка, затем вызывайте диалоговую процедуру ящика в подходящей точке в приложение. Следующий отрывок из модульного определения файла показывает как диалоговая процедура ящика для Заказной Щетки экспортирована.
; Экспортируйте все функции, которые вызваны программой Окна. ЭКСПОРТ MainWndProc @1; имя окна, обрабатывающего функцию BrushDlgProc @2; имя заказной-щетки, обрабатывающей функцию
Следующий отрывок из прикладного файла заголовка показывает функциональное определение для диалоговой процедуры ящика и две функции это вызывается.
int APIENTRY BrushDlgProc(HWND hdlg, ТЕКСТОВОЕ сообщение, ДОЛГО (ДЛИНОЙ) wParam, ДОЛГО (ДЛИНОЙ) lParam); int GetStrLngth(LPTSTR cArray); DWORD RetrieveWidth(LPTSTR cArray, int iLength);
Наконец, следующее кода показывает как диалоговая процедура ящика вызвана из прикладного исходного-кодового файла. В этом примере, диалоговый блок процедуры вызван когда пользователь выбирает опцию из прикладного меню.
ключ (сообщение) { случай WM_CREATE: прерывание; случай WM_COMMAND: // команда из прикладного ключа меню(wParam) { случай IDM_CUSTOMBRUSH: DialogBox((HANDLE)GetModuleHandle(НЕДЕЙСТВИТЕЛЬНЫЙ), (LPTSTR)"CustBrush", hWnd, (DLGPROC)BrushDlgProc); прерывание;
|
|
|
|
| |