如题。我无法得到BITMAP结构中的最后一个指针。总是空的。

解决方案 »

  1.   

    屏幕截取是令人比较感兴趣的事情.虽然现在有不少应用程序如hypersnap等可以用来截取你所喜欢的屏幕画面,但是如果能把这个功能加到自己的程序中,就更能利用它强大的作用. 
    ---- 下面用vc来逐步介绍在windows95下的实现过程.首先我们要确定屏幕截取的区域,用lprect结构来定义.可以截取一个窗口,或整个屏幕.以下代码把选定的屏幕区域拷贝到位图中.hbitmap copyscreentobitmap(lprect lprect)
    //lprect 代表选定区域
    {
    hdc hscrdc, hmemdc;
    // 屏幕和内存设备描述表
    hbitmap hbitmap, holdbitmap;
    // 位图句柄
    int nx, ny, nx2, ny2;
    // 选定区域坐标
    int nwidth, nheight;
    // 位图宽度和高度
    int xscrn, yscrn;
    // 屏幕分辨率// 确保选定区域不为空矩形
    if (isrectempty(lprect))
    return null;
    //为屏幕创建设备描述表
    hscrdc = createdc("display", null, null, null);
    //为屏幕设备描述表创建兼容的内存设备描述表
    hmemdc = createcompatibledc(hscrdc);
    // 获得选定区域坐标
    nx = lprect- >left;
    ny = lprect- >top;
    nx2 = lprect- >right;
    ny2 = lprect- >bottom;
    // 获得屏幕分辨率
    xscrn = getdevicecaps(hscrdc, horzres);
    yscrn = getdevicecaps(hscrdc, vertres);
    //确保选定区域是可见的
    if (nx 〈0)
    nx = 0;
    if (ny 〈 0)
    ny = 0;
    if (nx2 > xscrn)
    nx2 = xscrn;
    if (ny2 > yscrn)
    ny2 = yscrn;
    nwidth = nx2 - nx;
    nheight = ny2 - ny;
    // 创建一个与屏幕设备描述表兼容的位图
    hbitmap = createcompatiblebitmap
    (hscrdc, nwidth, nheight);
    // 把新位图选到内存设备描述表中
    holdbitmap = selectobject(hmemdc, hbitmap);
    // 把屏幕设备描述表拷贝到内存设备描述表中
    bitblt(hmemdc, 0, 0, nwidth, nheight,
    hscrdc, nx, ny, srccopy);
    //得到屏幕位图的句柄
    hbitmap = selectobject(hmemdc, holdbitmap);
    //清除
    deletedc(hscrdc);
    deletedc(hmemdc);
    // 返回位图句柄
    return hbitmap;
    }得到屏幕位图句柄以后,我们
    可以把屏幕内容粘贴到剪贴板上.
    if (openclipboard(hwnd))
    //hwnd为程序窗口句柄
    {
    //清空剪贴板
    emptyclipboard();
    //把屏幕内容粘贴到剪贴板上,
    hbitmap 为刚才的屏幕位图句柄
    setclipboarddata(cf_bitmap, hbitmap);
    //关闭剪贴板
    closeclipboard();
    }
    我们也可以把屏幕内容以位图格式存到磁盘文件上.int savebitmaptofile(hbitmap hbitmap ,
    lpstr lpfilename) //hbitmap 为刚才的屏幕位图句柄
    { //lpfilename 为位图文件名
    hdc hdc;
    //设备描述表
    int ibits;
    //当前显示分辨率下每个像素所占字节数
    word wbitcount;
    //位图中每个像素所占字节数
    //定义调色板大小, 位图中像素字节大小 ,
    位图文件大小 , 写入文件字节数
    dword dwpalettesize=0,
    dwbmbitssize,
    dwdibsize, dwwritten;
    bitmap bitmap;
    //位图属性结构
    bitmapfileheader bmfhdr;
    //位图文件头结构
    bitmapinfoheader bi;
    //位图信息头结构
    lpbitmapinfoheader lpbi;
    //指向位图信息头结构
    handle fh, hdib, hpal,holdpal=null;
    //定义文件,分配内存句柄,调色板句柄//计算位图文件每个像素所占字节数
    hdc = createdc("display",null,null,null);
    ibits = getdevicecaps(hdc, bitspixel) *
    getdevicecaps(hdc, planes);
    deletedc(hdc);
    if (ibits 〈 = 1)
    wbitcount = 1;
    else if (ibits 〈 = 4)
    wbitcount = 4;
    else if (ibits 〈 = 8)
    wbitcount = 8;
    else if (ibits 〈 = 24)
    wbitcount = 24;
    //计算调色板大小
    if (wbitcount 〈 = 8)
    dwpalettesize = (1 〈 〈 wbitcount) *
    sizeof(rgbquad);//设置位图信息头结构
    getobject(hbitmap, sizeof(bitmap), (lpstr)&bitmap);
    bi.bisize = sizeof(bitmapinfoheader);
    bi.biwidth = bitmap.bmwidth;
    bi.biheight = bitmap.bmheight;
    bi.biplanes = 1;
    bi.bibitcount = wbitcount;
    bi.bicompression = bi_rgb;
    bi.bisizeimage = 0;
    bi.bixpelspermeter = 0;
    bi.biypelspermeter = 0;
    bi.biclrused = 0;
    bi.biclrimportant = 0;dwbmbitssize = ((bitmap.bmwidth *
    wbitcount+31)/32)* 4
    *bitmap.bmheight ;
    //为位图内容分配内存
    hdib = globalalloc(ghnd,dwbmbitssize+
    dwpalettesize+sizeof(bitmapinfoheader));
    lpbi = (lpbitmapinfoheader)globallock(hdib);
    *lpbi = bi;
    // 处理调色板
    hpal = getstockobject(default_palette);
    if (hpal)
    {
    hdc = getdc(null);
    holdpal = selectpalette(hdc, hpal, false);
    realizepalette(hdc);
    }
    // 获取该调色板下新的像素值
    getdibits(hdc, hbitmap, 0, (uint) bitmap.bmheight,
    (lpstr)lpbi + sizeof(bitmapinfoheader)
    +dwpalettesize,
    (bitmapinfoheader *)
    lpbi, dib_rgb_colors);
    //恢复调色板
    if (holdpal)
    {
    selectpalette(hdc, holdpal, true);
    realizepalette(hdc);
    releasedc(null, hdc);
    }
    //创建位图文件
    fh = createfile(lpfilename, generic_write,
    0, null, create_always,
    file_attribute_normal | file_
    flag_sequential_scan, null);
    if (fh == invalid_handle_value)
    return false;
    // 设置位图文件头
    bmfhdr.bftype = 0x4d42; // "bm"
    dwdibsize = sizeof(bitmapfileheader)
    + sizeof(bitmapinfoheader)
    + dwpalettesize + dwbmbitssize;
    bmfhdr.bfsize = dwdibsize;
    bmfhdr.bfreserved1 = 0;
    bmfhdr.bfreserved2 = 0;
    bmfhdr.bfoffbits = (dword)sizeof
    (bitmapfileheader)
    + (dword)sizeof(bitmapinfoheader)
    + dwpalettesize;
    // 写入位图文件头
    writefile(fh, (lpstr)&bmfhdr, sizeof
    (bitmapfileheader), &dwwritten, null);
    // 写入位图文件其余内容
    writefile(fh, (lpstr)lpbi, dwdibsize,
    &dwwritten, null);
    //清除
    globalunlock(hdib);
    globalfree(hdib);
    closehandle(fh);
    }
      

  2.   

    屏幕截取是令人比较感兴趣的事情.虽然现在有不少应用程序如hypersnap等可以用来截取你所喜欢的屏幕画面,但是如果能把这个功能加到自己的程序中,就更能利用它强大的作用. 
    ---- 下面用vc来逐步介绍在windows95下的实现过程.首先我们要确定屏幕截取的区域,用lprect结构来定义.可以截取一个窗口,或整个屏幕.以下代码把选定的屏幕区域拷贝到位图中.hbitmap copyscreentobitmap(lprect lprect)
    //lprect 代表选定区域
    {
    hdc hscrdc, hmemdc;
    // 屏幕和内存设备描述表
    hbitmap hbitmap, holdbitmap;
    // 位图句柄
    int nx, ny, nx2, ny2;
    // 选定区域坐标
    int nwidth, nheight;
    // 位图宽度和高度
    int xscrn, yscrn;
    // 屏幕分辨率// 确保选定区域不为空矩形
    if (isrectempty(lprect))
    return null;
    //为屏幕创建设备描述表
    hscrdc = createdc("display", null, null, null);
    //为屏幕设备描述表创建兼容的内存设备描述表
    hmemdc = createcompatibledc(hscrdc);
    // 获得选定区域坐标
    nx = lprect- >left;
    ny = lprect- >top;
    nx2 = lprect- >right;
    ny2 = lprect- >bottom;
    // 获得屏幕分辨率
    xscrn = getdevicecaps(hscrdc, horzres);
    yscrn = getdevicecaps(hscrdc, vertres);
    //确保选定区域是可见的
    if (nx 〈0)
    nx = 0;
    if (ny 〈 0)
    ny = 0;
    if (nx2 > xscrn)
    nx2 = xscrn;
    if (ny2 > yscrn)
    ny2 = yscrn;
    nwidth = nx2 - nx;
    nheight = ny2 - ny;
    // 创建一个与屏幕设备描述表兼容的位图
    hbitmap = createcompatiblebitmap
    (hscrdc, nwidth, nheight);
    // 把新位图选到内存设备描述表中
    holdbitmap = selectobject(hmemdc, hbitmap);
    // 把屏幕设备描述表拷贝到内存设备描述表中
    bitblt(hmemdc, 0, 0, nwidth, nheight,
    hscrdc, nx, ny, srccopy);
    //得到屏幕位图的句柄
    hbitmap = selectobject(hmemdc, holdbitmap);
    //清除
    deletedc(hscrdc);
    deletedc(hmemdc);
    // 返回位图句柄
    return hbitmap;
    }得到屏幕位图句柄以后,我们
    可以把屏幕内容粘贴到剪贴板上.
    if (openclipboard(hwnd))
    //hwnd为程序窗口句柄
    {
    //清空剪贴板
    emptyclipboard();
    //把屏幕内容粘贴到剪贴板上,
    hbitmap 为刚才的屏幕位图句柄
    setclipboarddata(cf_bitmap, hbitmap);
    //关闭剪贴板
    closeclipboard();
    }
    我们也可以把屏幕内容以位图格式存到磁盘文件上.int savebitmaptofile(hbitmap hbitmap ,
    lpstr lpfilename) //hbitmap 为刚才的屏幕位图句柄
    { //lpfilename 为位图文件名
    hdc hdc;
    //设备描述表
    int ibits;
    //当前显示分辨率下每个像素所占字节数
    word wbitcount;
    //位图中每个像素所占字节数
    //定义调色板大小, 位图中像素字节大小 ,
    位图文件大小 , 写入文件字节数
    dword dwpalettesize=0,
    dwbmbitssize,
    dwdibsize, dwwritten;
    bitmap bitmap;
    //位图属性结构
    bitmapfileheader bmfhdr;
    //位图文件头结构
    bitmapinfoheader bi;
    //位图信息头结构
    lpbitmapinfoheader lpbi;
    //指向位图信息头结构
    handle fh, hdib, hpal,holdpal=null;
    //定义文件,分配内存句柄,调色板句柄//计算位图文件每个像素所占字节数
    hdc = createdc("display",null,null,null);
    ibits = getdevicecaps(hdc, bitspixel) *
    getdevicecaps(hdc, planes);
    deletedc(hdc);
    if (ibits 〈 = 1)
    wbitcount = 1;
    else if (ibits 〈 = 4)
    wbitcount = 4;
    else if (ibits 〈 = 8)
    wbitcount = 8;
    else if (ibits 〈 = 24)
    wbitcount = 24;
    //计算调色板大小
    if (wbitcount 〈 = 8)
    dwpalettesize = (1 〈 〈 wbitcount) *
    sizeof(rgbquad);//设置位图信息头结构
    getobject(hbitmap, sizeof(bitmap), (lpstr)&bitmap);
    bi.bisize = sizeof(bitmapinfoheader);
    bi.biwidth = bitmap.bmwidth;
    bi.biheight = bitmap.bmheight;
    bi.biplanes = 1;
    bi.bibitcount = wbitcount;
    bi.bicompression = bi_rgb;
    bi.bisizeimage = 0;
    bi.bixpelspermeter = 0;
    bi.biypelspermeter = 0;
    bi.biclrused = 0;
    bi.biclrimportant = 0;dwbmbitssize = ((bitmap.bmwidth *
    wbitcount+31)/32)* 4
    *bitmap.bmheight ;
    //为位图内容分配内存
    hdib = globalalloc(ghnd,dwbmbitssize+
    dwpalettesize+sizeof(bitmapinfoheader));
    lpbi = (lpbitmapinfoheader)globallock(hdib);
    *lpbi = bi;
    // 处理调色板
    hpal = getstockobject(default_palette);
    if (hpal)
    {
    hdc = getdc(null);
    holdpal = selectpalette(hdc, hpal, false);
    realizepalette(hdc);
    }
    // 获取该调色板下新的像素值
    getdibits(hdc, hbitmap, 0, (uint) bitmap.bmheight,
    (lpstr)lpbi + sizeof(bitmapinfoheader)
    +dwpalettesize,
    (bitmapinfoheader *)
    lpbi, dib_rgb_colors);
    //恢复调色板
    if (holdpal)
    {
    selectpalette(hdc, holdpal, true);
    realizepalette(hdc);
    releasedc(null, hdc);
    }
    //创建位图文件
    fh = createfile(lpfilename, generic_write,
    0, null, create_always,
    file_attribute_normal | file_
    flag_sequential_scan, null);
    if (fh == invalid_handle_value)
    return false;
    // 设置位图文件头
    bmfhdr.bftype = 0x4d42; // "bm"
    dwdibsize = sizeof(bitmapfileheader)
    + sizeof(bitmapinfoheader)
    + dwpalettesize + dwbmbitssize;
    bmfhdr.bfsize = dwdibsize;
    bmfhdr.bfreserved1 = 0;
    bmfhdr.bfreserved2 = 0;
    bmfhdr.bfoffbits = (dword)sizeof
    (bitmapfileheader)
    + (dword)sizeof(bitmapinfoheader)
    + dwpalettesize;
    // 写入位图文件头
    writefile(fh, (lpstr)&bmfhdr, sizeof
    (bitmapfileheader), &dwwritten, null);
    // 写入位图文件其余内容
    writefile(fh, (lpstr)lpbi, dwdibsize,
    &dwwritten, null);
    //清除
    globalunlock(hdib);
    globalfree(hdib);
    closehandle(fh);
    }