Рисование в DC. Как избежать ошибок.
|
Страница 1 из 2 Данная статья не может претендовать на полноту раскрытия принципов рисования в среде Microsoft Windows, она создана в помощь тем, кто делает свои первые шаги в этой области, с целью обратить внимание на основные моменты и предотвратить возможные (наиболее часто встречающиеся) ошибки. Примеры кода будут представлены в двух вариантах: с использованием WinAPI и MFC.
1. Получение DC (Контекста устройства)Рисование в Windows осуществляется в контексте устройства (DC). Существуют 4 типа DC: Display, Printer, Memory (Compatible DC) и Information. Первые 3 используются для рисования, Information DC – для получения информации об устройстве. В данной статье будет рассматриваться Display DC (обращение с Memory DC будет рассмотрено в следующей статье, которая сейчас в подготовке), а обращение с Printer DC – большая отдельная тема, которую может быть кто-нибудь из участников осветит здесь на форуме. :)
Итак, нам требуется в некотором окне нарисовать нечто свое собственное, картинку, график, текст и т.д. Первым делом необходимо получить контекст для рисования. Для этого в WinAPI применяются следующие методы:
WinAPI Цитата | // Получить DC клиентской области окна по его хэндлу HDC GetDC(HWND hWnd);
// Получить DC всего окна (включая его заголовок, меню, скроллбары и т.д.) по его хэндлу HDC GetWindowDC (HWND hWnd);
// Освободить DC, ранее полученный по GetDC или GetWindowDC int ReleaseDC (HWND hWnd, HDC hDC); |
В MFC классом «оберткой» для DC служит класс CDC. Для получения объекта CDC какого либо окна, в классе CWnd существуют следующие методы:
MFC Цитата | // Получить DC клиентской области окна CDC *CWnd:: GetDC ();
// Получить DC всего окна (включая его заголовок, меню, скроллбары и т.д.) CDC *CWnd:: GetWindowDC ();
// Освободить DC, ранее полученный по GetDC или GetWindowDC int CWnd:: ReleaseDC (HWND hWnd, HDC hDC); |
Из приведенных методов получения DC наиболее часто используется GetDC, т.к. обычно рисование происходит в клиентской части.
ВАЖНО: Любой DC, полученный по GetDC или GetWindowDC должен быть потом освобожден через вызов ReleaseDC. В противном случае происходят утечки ресурсов GDI, что при долгом времени работы програмы неизбежно приведет к глюкам при рисовании. Также, надо отметить, что ReleaseDC должно вызываться только для DC, полученных по GetDC или GetWindowDC. Схема получения – освобождения DC
WinAPI // hWnd - хэндл окна, DC которого нам необходим
// Получаем DC HDC hDC = ::GetDC (hWnd);
// Здесь рисуем, используя полученный DC // …
// Освобождаем DC ::ReleaseDC (hWnd, hDC);
|
MFC // m_Button1 - член класса, объект типа CButton CDC *pDC = m_Button1.GetDC();
// Здесь рисуем, используя полученный DC // …
// Освобождаем DC m_Button1.ReleaseDC(pDC);
|
|