尝试绘制时,SetDIBits在WM_PAINT上失败

时间:2013-12-24 20:07:51

标签: c++ winforms

我正在尝试使用矩阵绘制绘图,其中每个元素都是DWORD值,表示像素ARGB值。应用程序背后的想法是一个单独的线程进行计算(mat。公式),其结果将是具有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,“一个或多个输入参数无效”。我没有想法..

2 个答案:

答案 0 :(得分:0)

sizeof(BITMAPINFO)仅包含1个像素。 BITMAPINFO是一种可变长度结构,因此您需要动态计算其大小并动态分配足够的内存。

答案 1 :(得分: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);
}

我得到了正确的结果: plot generated using DrawImage