2014-12-16 2 views
0

Я читал много примеров в Интернете, но я все еще застрял. Я пытаюсь обработать сообщение WM_PAINT, отправленное в мое приложение.Обработка WM_PAINT

В моем приложении, я всегда рисую тот же DC, который называется g_hDC. Он работает отлично. Когда получено WM_PAINT, я просто попытаюсь нарисовать содержимое моего g_hDC в DC, возвращаемом BeginPaint. Думаю, g_hDC содержит последнее растровое изображение, которое я нарисовал. Поэтому я просто хочу его восстановить.

case WM_PAINT: 
PAINTSTRUCT ps; 

int ret; 
HDC compatDC; 
HDC currentDC; 
HDC paintDC; 
HBITMAP compatBitmap; 
HGDIOBJ oldBitmap; 

paintDC = BeginPaint(g_hWnd, &ps); 

currentDC = GetDC(g_hWnd); 
compatDC = CreateCompatibleDC(paintDC); 
compatBitmap=CreateCompatibleBitmap(paintDC, CONFIG_WINDOW_WIDTH, CONFIG_WINDOW_HEIGHT); 
oldBitmap=SelectObject(compatDC, compatBitmap); 

ret = BitBlt(compatDC, 
       ps.rcPaint.left, 
       ps.rcPaint.top, 
       ps.rcPaint.right - ps.rcPaint.left, 
       ps.rcPaint.bottom - ps.rcPaint.top, 
       currentDC, 
       ps.rcPaint.left, 
       ps.rcPaint.top, 
       SRCCOPY); 

ret = BitBlt(paintDC, 
       ps.rcPaint.left, 
       ps.rcPaint.top, 
       ps.rcPaint.right - ps.rcPaint.left, 
       ps.rcPaint.bottom - ps.rcPaint.top, 
       compatDC, 
       ps.rcPaint.left, 
       ps.rcPaint.top, 
       SRCCOPY); 

    DeleteObject(SelectObject(compatDC, oldBitmap)); 
    DeleteDC(compatDC); 
DeleteDC(currentDC); 

EndPaint(g_hWnd, &ps); 

break;

Но он просто рисует белый прямоугольник ... Я пробовал много возможностей и ничего не работает. Не могли бы вы мне помочь?

+0

C++ тег не верный. Измените его на Win32. – i486

+0

Вы ничего не нарисовали в compatBitmap - что вы ожидаете увидеть после BitBlt? Предположим, что должен быть «шум», то есть случайное изображение. – i486

+0

Я удалил тег C++. Я просто вижу белый прямоугольник на месте перекрывающегося окна. – vfloyd

ответ

0

Используйте это, чтобы удалить битмат: DeleteObject(SelectObject(compatDC,oldBitmap)); - без DeleteBitmap на предыдущей строке. SelectObject возвращает текущий (старый) выбор как возвращаемое значение - и вы удаляете его. В вашем случае вы пытаетесь удалить еще выбранное растровое изображение.

PS: Я не вижу CreateCompatibleDC - где вы создаете compatDC? Добавить compatDC = CreateCompatibleDC(hdc); до CreateCompatibleBitmap.

+0

Спасибо за ваш ответ. Я редактировал код в своем первом сообщении. Это все еще не работает. (обратите внимание, что теперь я BitBlt в compatDC вместо hdc). Проблема в том, что я не понимаю, что я делаю. Для меня это нелогично. Почему я должен создать совместимый Dc, так что BeginPaint уже дал мне DC? – vfloyd

+0

Идея с DC-s очень странная. Я использовал его в течение многих лет и до сих пор не могу полностью понять идею, но это метод работы. DC - это объект, где вы рисуете - что-то вроде виртуального дисплея. Это может быть реальный дисплей, может быть виртуальным дисплеем памяти, может быть поверхностью принтера. Я не уверен, что ваш g_hDC содержит допустимое растровое изображение и совместим с hdc/compatDC. Если вы 'BitBlt' от g_hDC до compatDC, вам понадобится дополнительная битBlt для передачи изображения из compatDC в hdc (реальный дисплей). Вместо этого попробуйте «BitBlt (hdc, 0,0, rect.right, rect.bottom, compatDC, 0,0, SRCCOPY);». – i486

1

Есть много вещей, которые вы делаете неправильно.

Во-первых, ваше сохранение g_hDC опирается на деталь реализации: вы заметили, что указатели одинаковы и, таким образом, сохраняют указатель. Это может работать в краткосрочной перспективе по целому ряду причин, связанных с оптимизацией на части GDI (например, есть DC cache), но прекратит работать в конечном итоге, когда это наименее удобно. Или у вас может возникнуть соблазн использовать указатель постоянного тока, если у вас нет постоянного тока, и будет записывать что-то еще (или не делать этого из-за близости потока объектов GDI).

Правильный способ доступа к DC-окну за пределами его WM_PAINT осуществляется по телефону GetDC(hwnd).

CreateCompatibleDC() создает постоянный постоянный ток, совместимый с hdc. Рисование до compatDC недостаточно для рисования hdc; вы должны вернуться к hdc после того, как вы нарисуете compatDC. Для вашего случая вам потребуется два вызова BitBlt(); вторая будет отходить от compatDC до hdc. See this sample code for details.

Вы не можете DeleteObject() растровое изображение, пока вы его выбрали в DC. Ваш звонок SelectObject(compatDC, oldBitmap) должен прибыть доDeleteObject(compatBitmap). (Это то, что i486 пытается получить в его ответе.)

(я уверен, что этот ответ является недостоверным или неполным в некоторых местах,., Пожалуйста, дайте мне знать, если он есть)

+0

Спасибо за ваш ответ. Я попробовал со вторым BitBlt, и получил тот же результат. Белый прямоугольник. Я также попытался с примером кода, который вы предоставили. Тот же результат. – vfloyd

+0

Я отредактировал свое первое сообщение с кодом, который я тестирую на данный момент. У меня еще белый прямоугольник. – vfloyd

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