2013-05-01 6 views
0

Я пишу приложение для рисования линии, прямоугольника, эллипса в клиентской области. Мне нужно сохранить изображение клиентской области, когда я рисую любую вещь. И я восстанавливаю его при появлении сообщения WM_PAINT.Как сохранить hdc и восстановить его?

Я использую HBITMAP для сохранения и восстановления

SAVE

RECT rc; 
GetClientRect(hMain, &rc); // hMain: handle main window 
hdc = GetDC(hMain); 
HDC hdcMem = CreateCompatibleDC(hdc); 
// hbm: handle bitmap to save and restore 
hbm = CreateCompatibleBitmap(hdc, rc.right - rc.left, rc.bottom - rc.top); 

SelectObject(hdcMem, hbm); 
BitBlt(hdcMem, 0, 0, rc.right - rc.left, rc.bottom - rc.top, 
    hdc, rc.right - rc.left, rc.bottom - rc.top, SRCCOPY); 
ReleaseDC(hMain, hdc); 

ВОССТАНОВЛЕНИЕ

PAINTSTRUCT ps; 
HDC hdc = BeginPaint(hMain, &ps); 
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1)); 
HDC hdcMem = CreateCompatibleDC(hdc); 
SelectObject(hdcMem, hbm); 
BitBlt(hdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, 
    hdcMem, rc.right - rc.left, rc.bottom - rc.top, SRCCOPY); 
ReleaseDC(hMain, hdc); 
EndPaint(hMain, &ps); 

Но это не работает. Пожалуйста, помогите мне.

+0

Не можете ли вы сделать это легко и сделать чертеж в WM_PAINT (а не)? – john

+0

Это неправильно как на стороне сохранения, так и на стороне восстановления. Сторона сохранения будет захватывать только видимые пиксели. Пиксели, которые не видны (например, закрыты другим окном), не будут захвачены. Сторона восстановления вызывает 'BeginPaint' вне сообщения' WM_PAINT', что не рекомендуется. В этом случае он получает DC, который полностью вырезается, потому что ничего недействительно. Вы должны просто выполнить всю работу внутри 'WM_PAINT' - если вы хотите заменить клиентскую область, нарисуйте замену. Когда вы хотите восстановить старую клиентскую область, выполните старый код чертежа. –

ответ

3

Если вы не решились на это с трудом, я бы отказался от этого подхода. Я вижу две разумные альтернативы:

  1. Просто выполните весь чертеж внутри WM_PAINT. Когда вы хотите, чтобы линии, прямоугольники, эллипсы и т. Д. Исчезли, установили какую-то переменную (или что-то еще), чтобы указать, что они ушли, и аннулировать окно, чтобы заставить перерисовать. Это обычный способ, и работы находят большую часть времени.

  2. Создайте второе окно, накладывающее клиентскую область вашего текущего окна. Создайте это как многоуровневое окно с набором CS_SAVEBITS в его классе окон. Нарисуйте свои линии, эллипсы и т. Д. Здесь и просто уничтожьте окно, когда вы хотите, чтобы они исчезли.

CS_SAVEBITS автоматически делает то, что вы пытаетесь сделать прямо сейчас: сохраняет растровое изображение области под окном, которое используется для восстановления, лежащей в основе окна (полностью автоматически), когда окно CS_SAVEBITS исчезает. И то, и другое, и то, как вы пытаетесь сделать что-то, имеют ту же проблему: сохраненная растровая карта не отслеживает любые изменения в базовом окне - они просто восстанавливают то, что было там, где было создано верхнее окно, которое может стать устаревшим. Он работает только правильно, если основное окно остается статичным в течение продолжительности.

Если это проблема, объедините два подхода: оставьте CS_SAVEBITS в окне оверлея. Когда он будет уничтожен, основное окно будет признано недействительным и восстановит себя обычной логикой повторного рисования.

Смежные вопросы