MSPaint-приложение как написание.Как правильно сделать BitBlt? - PullRequest
1 голос
/ 26 сентября 2011

Я сейчас пишу простую mspaint-подобную программу на C ++ с использованием windows.h (GDI). Для моей программы мне нужен только инструмент пера. Итак, мне нужно где-то сохранить изображение главного окна (например, в памяти HDC и HBITMAP), чтобы нарисовать его в сообщении WM_PAINT.

  1. Когда мне сначала нужно сохранить HDC окна в моей памяти HDC и HBITMAP? В каком сообщении я должен хранить окно? Например, я думаю, что мы не можем сделать это в WM_CREATE, потому что у нас еще нет окна.

  2. В чем разница между PatBlt и BitBlt? Что я должен использовать для моего приложения?

  3. Как скопировать содержимое окна HDC в мою память HDC и Bitmap? Я пытаюсь сделать что-то вроде этого:

        LPRECT lpRect;
        GetClientRect(hwnd, lpRect);
        width = lpRect->right - lpRect->left;
        height = lpRect->bottom - lpRect->top;
    
        HDC hDC = GetDC(hwnd);
        memoryDC = CreateCompatibleDC(hDC);
        memoryBitmap = CreateCompatibleBitmap(hDC, width, height);
        SelectObject(memoryDC, memoryBitmap);
        PatBlt(memoryDC, 0, 0, width, height, PATCOPY);
        ReleaseDC(hwnd, hDC);
    

Но это не работает: программа вылетает.

  1. Как после этого восстановить окно в WM_PAINT?

  2. Как очистить мое окно белым цветом?

1 Ответ

4 голосов
/ 26 сентября 2011

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

2: PatBlt заполняет область растрового изображения, используя текущую кисть контекста устройства.Кисти определяют шаблоны, поэтому они называются PatBlt.BitBlt копирует данные из исходного растрового изображения в конечное растровое изображение.Вы должны использовать BitBlt, когда хотите переместить изображение из неэкранного растрового изображения в буфер кадров.

3: параметр lpRect в GetClientRect является выходным параметром.Это означает, что вы должны предоставить память.В этом случае GetClientRect пытается записать прямоугольник в нулевой указатель и вызывает сбой.

RECT clientRect;
GetClientRect(hwnd, &clientRect);
width = clientRect.right - clientRect.left;
height = clientRect.bottom - clientRect.top;
...