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

为何DIB位图数据全为0?Win32 GDI缩放滚动页面问题排查

问题:带滚动条的页面窗口缩放异常(内容超出边界时失效)

我正在开发一个带有水平和垂直滚动条的类页面窗口,用户可对页面内容进行缩放。该功能在内容未超出页面边界时正常工作,但超出边界后出现问题。我尝试使用内存设备上下文(memory device contexts)和Win32 GDI函数修复该问题,但收效甚微。

以下是页面缩放的代码:

//检查是否按下缩放按钮。
if(tmpn3 == 1){

    //获取窗口的设备上下文。
    tmphdc2 = GetDC(GLB_HWndMainDialog);

    //获取内存设备上下文。
    tmphdc3 = CreateCompatibleDC(tmphdc2);

    //设置StretchBlt模式。
    SetStretchBltMode(tmphdc2, 
                      BLACKONWHITE);

    //设置StretchBlt模式。
    SetStretchBltMode(tmphdc3, 
                      BLACKONWHITE);

    //放大页面并将像素复制到内存DC。
    StretchBlt(tmphdc3, 
               0, 
               0, 
               612, 
               900, 
               tmphdc2, 
               0, 
               0, 
               408, 
               600, 
               SRCCOPY);

    //放大页面并将像素复制到窗口页面。
    StretchBlt(tmphdc2, 
               8, 
               100, 
               400, 
               500, 
               tmphdc2, 
               8, 
               100, 
               200, 
               250, 
               SRCCOPY);

    //检查tmpbits是否不为空。
    if(tmpbits != NULL){

        //释放tmpbits。
        free(tmpbits);

    } //结束判断

    //获取页面客户区的DIB位图。该位图从页面左下角开始,到主对话框右上角结束。
    GetDIBPage(GLB_HWndMainDialog, 
               &tmpbits);
 
    //检查tmpbits2是否为空。
    if(tmpbits2 == NULL){

        //为tmpbits2分配内存。
        tmpbits2 = (void*)calloc((4 * 620 * 920), sizeof(char));

    } //结束判断

    //从tmphdc3获取DIB数据。

    //为tmpbmpinfo分配内存。
    tmpbmpinfo = (BITMAPINFO*)calloc(1, sizeof(BITMAPINFO));

    //设置tmpbmphdr变量。
    tmpbmphdr = &(tmpbmpinfo->bmiHeader);

    //设置位图信息头的成员
    tmpbmphdr->biSize = sizeof(BITMAPINFOHEADER);
    tmpbmphdr->biWidth = 612;
    tmpbmphdr->biHeight = 900;
    tmpbmphdr->biPlanes = 1;
    tmpbmphdr->biBitCount = 32;
    tmpbmphdr->biCompression = BI_RGB;
    tmpbmphdr->biSizeImage = 0;
    tmpbmphdr->biXPelsPerMeter = 0;
    tmpbmphdr->biYPelsPerMeter = 0;
    tmpbmphdr->biClrUsed = 0;
    tmpbmphdr->biClrImportant = 0;

    //创建兼容位图。
    tmphbitmap = CreateCompatibleBitmap(tmphdc3, 
                                        612, 
                                        900);

    //将位图中的数据复制到tmpbits2,不包含位图头。
    GetDIBits(tmphdc3, 
              tmphbitmap, 
              0, 
              900, 
              tmpbits2, 
              tmpbmpinfo, 
              DIB_RGB_COLORS);

    //释放设备上下文。
    ReleaseDC(GLB_HWndMainDialog, 
              tmphdc2);

    //释放变量
    DeleteObject(tmphbitmap);
    DeleteDC(tmphdc3);
    free(tmpbmpinfo);
}

根据Windows文档,StretchBlt应将像素从源DC复制到目标DC,因此我未使用SelectObject和BitBlt函数。恳请提供帮助。

内容的提问来源于stack exchange,提问作者Thema Guishard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:16:25