如何从屏幕上取一部分到BITMAP类中? 如题。我无法得到BITMAP结构中的最后一个指针。总是空的。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 屏幕截取是令人比较感兴趣的事情.虽然现在有不少应用程序如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);} 屏幕截取是令人比较感兴趣的事情.虽然现在有不少应用程序如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);} 自己写的抓包程序能抓到http请求报文却住不到http回应的报文,怎么回事? 怎么实现如图所示结构? 急:关于Webservice客户端开发的问题 问题! thinking in C++ 第一卷 书后习题答案 为什么我的ATL控件在win2000下看不到界面,在winxp下可以 向大家请教几个问题,关于WORD开发的 如何在所有的分割窗体里显示OPenGL图形? ISDN共享 好消息! CSDN高手到哪去了?有没人会印章识别技术啊? 关于画图
---- 下面用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);
}
---- 下面用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);
}