SetDIBits терпит неудачу на WM_PAINT при попытке рисовать

0

Я пытаюсь рисовать график с использованием матрицы, где каждый элемент имеет значение DWORD, представляющее значение ARGB пикселя. Идея, лежащая в основе приложения, заключается в том, что один отдельный поток выполняет вычисление (мат. Формула), результатом которого будет матрица с значениями ARGB. Когда WM_PAINT будет поднят, я буду использовать функцию для рисования, используя заполненную матрицу:

void DrawImage( HDC hDC, WORD wWidth, WORD wHeight )
{
    HBITMAP hBitmap;
    HDC hMemDC;
    BITMAPINFO bi;

    int iSize = sizeof( BITMAPINFO );
    memcpy( &bi, dwBytes + 3, iSize);

    hBitmap = CreateCompatibleBitmap(hDC, wWidth, wHeight);

    hMemDC = CreateCompatibleDC( hDC );

    if ( 0 == SetDIBits( hDC, hBitmap, 0, 
        wHeight, dwBytes, &bi, DIB_RGB_COLORS ) )
    {
        // error MSDN http://msdn.microsoft.com/en-us/library/
        //windows/desktop/dd162973%28v=vs.85%29.aspx
    }

    hBitmap = (HBITMAP) SelectObject(hMemDC, hBitmap);

    BitBlt(hDC, 0, 0, wWidth, wHeight, hMemDC, 0, 0, SRCCOPY);

    DeleteObject(SelectObject(hMemDC, hBitmap));

    DeleteDC(hMemDC);
}

поэтому, когда WM_PAINT поднят:

case WM_PAINT:
{
    PAINTSTRUCT ps = { 0 };

    HDC hDC = BeginPaint( hWnd, &ps );

    DrawImage( hDC, iWidth, iHeight );

    EndPaint( hWnd, &ps );

    return 0L;
}

но ничего не происходит. Область черная. Когда SetDIBits возвращает 0, это означает, что "один или несколько входных параметров недействительны" в соответствии с MSDN. У меня нет идей.

  • 1
    Этот вызов memcpy () причудливый. Он не может быть получен из растровых данных, смещение +3 абсолютно случайно. Как отправлено, это должно быть bi которое содержит мусор.
Теги:
winforms

2 ответа

0

Вы указали, что я занимаюсь обработкой структуры BITMAPINFO, и вот она. После того, как я изменил одну плоскость, 32 бит на пиксель и ширину 800 и высоту 600 - это сработало!

void DrawImage( HDC hDC, WORD wWidth, WORD wHeight )
{
    HDC hMemDC;
    BITMAPINFO bmi;

    ZeroMemory(&bmi, sizeof(BITMAPINFO));

    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biHeight = 600;
    bmi.bmiHeader.biWidth = 800;
    bmi.bmiHeader.biPlanes = 1;

    hMemDC = CreateCompatibleDC( hDC );

    HBITMAP hBitmap = CreateDIBSection( hMemDC, &bmi, DIB_RGB_COLORS, 
        (void**) &dwBytes, NULL, 0);

    SetDIBits( hDC, hBitmap, 0, wHeight, dwBytes, &bmi, DIB_RGB_COLORS );

    HBITMAP hOldBitmap = (HBITMAP) SelectObject( hMemDC, hBitmap );

    BitBlt(hDC, 0, 0, wWidth, wHeight, hMemDC, 0, 0, SRCCOPY);

    SelectObject( hMemDC, hBitmap );

    DeleteObject( hBitmap );

    DeleteDC(hMemDC);
}

Я получил правильный результат: Изображение 174551

0

sizeof (BITMAPINFO) включает только 1 пиксель. BITMAPINFO - это структура переменной длины, поэтому вам нужно динамически вычислять ее размер и динамически выделять достаточную память.

  • 0
    В таблицу цветов входит 1 цвет, а не пиксель.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню