Контекст отображения для класса окон
Можно создать единственный контекст отображения для всех окон некоторого класса. Для этого при регистрации класса указывают стиль CS_CLASSDC. Тогда все окна этого класса будут пользоваться одним общим контекстом отображения. Приложения, однажды получив контекст отображения для класса окон, могут не освобождать его. Причем вызов функций EndPaint и ReleaseDC не освобождает такой контекст (хотя и. не вредит работе приложения). Для сохранения единого стиля работы с контекстами рекомендуется всегда вызывать эти функции. Контекст отображения для класса окон создают один раз. Если создано несколько окон этого класса, область ограничения и начало системы физических координат вывода автоматически настраиваются на то окно, которое использует контекст отображения. Но если на базе класса стиля CS_CLASSDC приложение создало только одно окно, оно может получить контекст отображения для класса окон один раз и не освобождать его. Таким образом, контекст отображения для класса окон повышает производительность вывода в окна тем, что не требует настройку многочисленных атрибутов контекста отображения после каждого вызова функции BeginPaint или EndPaint. Задача. Для окон класса стиля CS_CLASSDC создать единый контекст и установить его атрибуты по умолчанию. После нажатия левой клавиши мыши изменить атрибуты контекста, а после нажатия правой клавиши – восстановить исходные значения атрибутов. Листинг 3.4. Установка атрибутов контекста для класса по умолчанию, изменение атрибутов и восстановление их исходных значений. #include <windows.h> #include <tchar.h>
BOOL RegClass(WNDPROC, LPCTSTR, UINT); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void ContAttr(HWND hwnd);
HINSTANCE hInstance; TCHAR szClass[] = TEXT("ClassContext");
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow) { MSG msg; HWND hwnd1, hwnd2; hInstance = hInst; if (!RegClass(WndProc, szClass, COLOR_WINDOW)) return FALSE; hwnd1 = CreateWindow(szClass, TEXT("Первое окно"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, NULL); if (!hwnd1) return FALSE; hwnd2 = CreateWindow(szClass, TEXT("Второе окно"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, NULL); if (!hwnd2) return FALSE; //Устанавливаем исходные атрибуты контекста ContAttr(hwnd1); while(GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg); return msg.wParam; }
BOOL RegClass(WNDPROC Proc, LPCTSTR szName, UINT brBackground) { WNDCLASS wc; wc.cbClsExtra = wc.cbWndExtra = 0; wc.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC; wc.lpfnWndProc = Proc; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(brBackground +1); wc.lpszMenuName = NULL; wc.lpszClassName = szName; return (RegisterClass(&wc) != 0); }
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static short cx, cy; switch (msg) { case WM_SIZE: { cx = LOWORD(lParam); cy =HIWORD(lParam); return 0; } case WM_PAINT: { TCHAR szText[]=TEXT("Вывод с атрибутами контекста класса"); PAINTSTRUCT ps; HDC hdc=BeginPaint(hwnd, &ps); TextOut(hdc, cx/2, cy/2, szText, _tcslen(szText)); EndPaint(hwnd, &ps); return 0; } case WM_LBUTTONDOWN: { TCHAR szText[]=TEXT("Изменяем атрибуты контекста класса и выводим"); HDC hdc=GetDC(hwnd); //Цветом вывода символов выбираем малиновый SetTextColor(hdc, RGB(255, 0, 255)); //Цветом фона вывода символов выбираем кремовый SetBkColor(hdc, RGB(255, 251, 240)); TextOut(hdc, cx/2, cy/2-60, szText, _tcslen(szText)); ReleaseDC(hwnd, hdc); return 0; } case WM_RBUTTONDOWN: { //Восстанавливаем атрибуты контекста ContAttr(hwnd); TCHAR szText[]=TEXT("Восстанавливаем атрибуты контекста класса и выводим"); HDC hdc=GetDC(hwnd); TextOut(hdc, cx/2, cy/2+60, szText, _tcslen(szText)); ReleaseDC(hwnd, hdc); return 0; } case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(hwnd, msg, wParam, lParam); }
void ContAttr(HWND hwnd) { HDC hdc=GetDC(hwnd); //Цветом вывода символов устанавливаем синий SetTextColor(hdc, RGB(0, 0, 255)); //Цветом фона вывода символов устанавливаем желтый SetBkColor(hdc, RGB(255, 255, 0)); SetTextAlign(hdc, TA_CENTER); ReleaseDC(hwnd, hdc); }
Приложение регистрирует класс со стилем контекста для класса:
wc.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC;
Затем создает два различных окна этого класса с координатами по умолчанию и устанавливает исходные атрибуты контекста класса:
ContAttr(hwnd1);
При этом не имеет значения, дескриптор которого из окон данного класса служит аргументом этой функции. Для установки атрибутов контекста класса равноправны все окна данного класса. Оба окна в центре рабочей области содержат один и тот же текст "Вывод с атрибутами контекста класса", выведенный синим шрифтом на желтом фоне. Нажатие левой клавиши мыши над рабочей областью любого из двух окон приводит к изменению атрибутов контекста класса. В данном случае цвет шрифта изменяется на малиновый, а цвет фона – на кремовый. Выше текста "Вывод с атрибутами контекста класса" отображается новая строка, выведенная новыми атрибутами: "Изменяем атрибуты контекста класса и выводим". Обратите внимание, что ни в одном окне цвета шрифта и фона для строки "Вывод с атрибутами контекста класса" еще не изменились. Если изменить размеры любого из окон, то в этом окне появится строка "Вывод с атрибутами контекста класса" с изменившимися цветами шрифта и фона. То есть при обработке сообщения WM_PAINT используются новые атрибуты контекста. Нажатие правой клавиши мыши над рабочей областью любого из двух окон приводит к установке исходных атрибутов контекста класса. С этой целью опять вызываем функцию ContAttr. Ниже строки "Вывод с атрибутами контекста класса" появляется новая строка, выведенная с исходными атрибутами: "Восстанавливаем атрибуты контекста класса и выводим". Обратите внимание, что ни в одном окне цвета шрифта и фона для строки "Вывод с атрибутами контекста класса" еще не изменились. Если изменить размеры любого из окон, то в этом окне появится строка "Вывод с атрибутами контекста класса" с исходными цветами шрифта и фона. То есть при обработке сообщения WM_PAINT используются исходные атрибуты контекста. ©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.
|