使用Win32绘制性能

时间:2016-10-13 18:36:39

标签: winapi win32gui

我使用Win32获得了很差的性能图。这需要太多时间,需要改进。请指教。

这就是我的工作。

HDC dc = GetDC(wnd);
HDC memoryDc = CreateCompatibleDC(dc);
HBITMAP memoryMapBitmap = CreateCompatibleBitmap(dc, 400, 400);
HGDIOBJ originalBitmap = SelectObject(memoryDc, memoryMapBitmap);

然后,我按如下方式绘制for循环。

HBRUSH brush = (HBRUSH)GetStockObject(DC_BRUSH);
SetDCBrushColor(memoryDc, colorRef);
FillRect(memoryDc, &rect, brush);

最后,我做了清理

SelectObject(memoryDc, originalBitmap);
DeleteDC(memoryDc);
ReleaseDC(wnd, dc);

绘图需要花费大量时间(几秒钟)。有没有办法用Win32快速绘制?

提前致谢!

1 个答案:

答案 0 :(得分:0)

看起来我已经解决了它。以下是一些评论的解决方案。

我在RC文件中定义了一个对话框。有一个控件可以在对话框中显示位图图像。

CONTROL         "", IDC_MEMORY_MAP, WC_STATIC, SS_BITMAP | SS_CENTERIMAGE | SS_SUNKEN, 9, 21, 271, 338, WS_EX_LEFT

在运行时我需要创建,绘制和显示位图:

HWND map = GetDlgItem(dlg, IDC_MEMORY_MAP);
HBITMAP bitmap = createMemoryMapBitmap(map);
bitmap = (HBITMAP)SendMessage(map, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)bitmap);
DeleteObject(bitmap); // (!) this is a very important line, otherwise old bitmap leaks

找出要创建的位图大小的代码:

HBITMAP createMemoryMapBitmap(HWND map) {
    RECT rect = {0, 0, 0, 0};
    GetClientRect(map, &rect);
    SIZE size = {rect.right - rect.left, rect.bottom - rect.top};

    HDC dc = GetDC(map);
    HBITMAP bitmap = doCreateMemoryMapBitmap(dc, &size);
    ReleaseDC(map, dc);

    return bitmap;
}

最后,我们实际上创建了位图并在其上绘图:

HBITMAP doCreateMemoryMapBitmap(HDC dc, LPSIZE bitmapSize) {
    // create 24bpp bitmap in memory in order to draw fast

    BITMAPINFO info;
    memset(&info, 0, sizeof(info));
    info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    info.bmiHeader.biWidth = bitmapSize->cx;
    info.bmiHeader.biHeight = bitmapSize->cy;
    info.bmiHeader.biPlanes = 1;
    info.bmiHeader.biBitCount = 24;
    info.bmiHeader.biCompression = BI_RGB;

    void *pixels = NULL;
    HBITMAP memoryBitmap = CreateDIBSection(dc, &info, DIB_RGB_COLORS, &pixels, NULL, 0);

    HDC memoryDc = CreateCompatibleDC(dc); // (!) memoryDc is attached to current thread
    HGDIOBJ originalDcBitmap = SelectObject(memoryDc, memoryBitmap);

    // drawing code here

    // perform windows gdi cleanup

    SelectObject(memoryDc, originalDcBitmap); // restore original bitmap in memoryDC (optional step)
    DeleteDC(memoryDc); // this releases memoryBitmap from memoryDC

    return memoryBitmap;
}

上面的想法是在内存中创建一个24bpp的位图并在其上绘制。这种方式绘图很快,正如@IInspectable指出的那样。

如果显示处于索引颜色模式,例如16或256色,似乎Windows原生控件足够智能,可以自动转换颜色深度,显示位图。