Здавалка
Главная | Обратная связь

Контекст отображения для класса окон



Можно создать единственный контекст отображения для всех окон некоторого класса. Для этого при регистрации класса указывают стиль 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 Все права принадлежат авторам размещенных материалов.