You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言窗口截图代码调用GetDIBits返回ERROR_INVALID_PARAMETER错误

GetDIBits 调用返回 ERROR_INVALID_PARAMETER 的核心排查方向

常见的跨语言移植差异根因

  • C语言栈局部结构体未清零,导致字段为随机垃圾值
    PowerBuilder 中实例化结构体时会自动将所有成员初始化为0,而C语言的栈上局部变量不会自动初始化内存。原代码中的BITMAPINFO lstr_Info是栈变量,仅给bmiHeader.biSize赋值,其余字段(biWidth、biHeight、biPlanes、biBitCount、biCompression等)全是随机残留值,GetDIBits做参数校验时检测到非法字段值,会直接抛出ERROR_INVALID_PARAMETER错误。
  • 未校验前置API的执行结果
    调用BitBlt后如果不检查返回值就直接执行GetDIBits,一旦BitBlt执行失败,关联到内存DC的位图内容未定义,同样会触发参数校验失败。
  • 非法的入参值
    函数入参的width、height如果为0,会导致创建兼容位图、BitBlt调用、GetDIBits全链路触发参数错误,需要在函数入口增加入参合法性判断。

修正后的核心代码片段

extern "C" __declspec(dllexport) BOOL __stdcall WindowScreenShot(const wchar_t* fileName, unsigned long x, unsigned long y, unsigned long width, unsigned long height)
{
    // 入参合法性校验
    if (width == 0 || height == 0)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    HWND ll_hWnd;
    HDC ll_hdc, ll_hdcMem;
    HBITMAP ll_hBitmap, ll_hOldBmp;
    HANDLE hDib = NULL, hFile = NULL;
    char* lpBitmap = NULL;
    BOOL lb_result, lb_ok = FALSE;
    // 结构体直接零初始化,替代手动赋值
    BITMAPINFO lstr_Info = {0};
    BITMAPFILEHEADER lstr_Header = {0};
    int li_pixels;
    DWORD dwBmpSize, dwBytesWritten;

    ll_hWnd = GetDesktopWindow();
    ll_hdc = GetDC(ll_hWnd);
    ll_hdcMem = CreateCompatibleDC(ll_hdc);
    ll_hBitmap = CreateCompatibleBitmap(ll_hdc, width, height);

    if (ll_hBitmap != 0)
    {
        ll_hOldBmp = (HBITMAP)SelectObject(ll_hdcMem, ll_hBitmap);
        lb_result = BitBlt(ll_hdcMem, 0, 0, width, height, ll_hdc, x, y, SRCCOPY);
        if (lb_result)
        {
            lstr_Info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
            // 此处调用不再触发参数错误
            if (GetDIBits(ll_hdcMem, ll_hBitmap, 0, height, NULL, &lstr_Info, DIB_RGB_COLORS) > 0)
            {
                // 后续位图写入逻辑
            }
        }
        // 资源还原
        SelectObject(ll_hdcMem, ll_hOldBmp);
    }
    // GDI资源清理逻辑
    DeleteObject(ll_hBitmap);
    DeleteDC(ll_hdcMem);
    ReleaseDC(ll_hWnd, ll_hdc);
    return lb_ok;
}

补充说明

  • 调用GetDIBits获取位图信息时,不需要额外给biBitCount赋值,API会自动根据关联位图的实际参数填充合法值;只要提前将结构体清零,仅设置biSize字段,即可满足入参要求。
  • GDI资源使用完成后必须还原之前选中的对象、删除兼容DC、释放设备上下文,避免产生GDI资源泄漏。

内容的提问来源于stack exchange,提问作者Dan Cooperstock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 13:24:04