现在的位置: 首页 > 综合 > 正文

解析兼容DC与兼容位图

2018年02月24日 ⁄ 综合 ⁄ 共 1722字 ⁄ 字号 评论关闭

   windows编程中老是遇到兼容DC与兼容位图,而我对他们的用法又不是很清晰,总觉得对只是一知半解非常不爽,今天索性将他们都好好研究一番。如有错误,还请指正批评,不甚感激!

首先讲怎么样在应用程序里显示一幅位图?
    ① 可以利用StretchDIBits函数来显示。这个方法需要先从文件里加载一个位图文件,然后获取位图相关信息来显示,只涉及到一个设备上下文HDC,也就是要显示的那个HDC。
    ② 可以利用BitBlt或StretchBlt 函数来显示。这个涉及到两个设备上下文HDC,一个源,一个目的。目的设备上下文就是要显示的HDC。那源设备上下文是什么呢?源设备上下文就是包含了要显示的位图的设备上下文。那如何把位图放到源设备上下文中去呢?直接把位图放进要显示的设备上下文(即目的设备上下文)岂不是更好!但是windows不容许直接将位图放入设备上下文,但是可以将位图放入兼容的设备上下文,然后将兼容设备上下文中的内容拷贝到目的设备上下文中去就可以到达目的。
    怎么来创建一个兼容DC呢?调用
    HDC CreateCompatibleDC(
        HDC hdc   // handle to DC
);
    函数就可以了。参数一般是要窗口的DC。根据MSDN,兼容DC被创造时,它的显示表面是1单色宽和1单色高。要想利用兼容DC,必须将一个位图选入兼容DC。如何把位图选入兼容DC呢?首先得到位图的句柄,将位图作为程序资源,调用LoadBitmap即可获得该位图句柄。然后利用SelectObject函数将位图选入指定兼容DC。需要说明的是,一幅位图只能被选入到一个兼容DC一次。例如下面代码就调用不成功:
    SelectObject(hdcA, hBitMap) ;
    ......
    SelectObject(hdcB, hBitMap) ;   //失败
    必须先将hdcA释放掉才能将hBitMap选入hdcB。

    那兼容位图又是什么呢?
    我们思考这样一个问题,当位图选入兼容DC之后,他们两者有什么联系呢?可以将兼容设备里的位图拷贝到一个显示的设备上下文,那么在兼容设备中操作之后(比方画线,画圆等),兼容设备里的位图有变化吗?当然有!在兼容设备里的操作会反应在里面的位图里。如果我们对兼容设备中的位图感兴趣,需要将位图保存或者显示到其他的地方(比如其他的窗口等),但是兼容设备里的位图是加载得到的,每次要得到这个位图就需要首先加载一个位图,您觉得有必要吗?不仅需要找一个位图资源作为样本,而且浪费空间时间!幸运的是,我们可以自己创建一个位图,利用CreateBitmap就可以。它的定义是:
HBITMAP CreateBitmap(
  int nWidth,         // bitmap width, in pixels
  int nHeight,        // bitmap height, in pixels
  UINT cPlanes,       // number of color planes
  UINT cBitsPerPel,   // number of bits to identify color
  CONST VOID *lpvBits // color data array
);
    其中有些参数有点难理解,可以自行百度或查询MSDN。创建一个位图之后,将它选入兼容设备,然后在兼容设备中绘图,也就是在该位图上绘图。
    我们还是会觉得CreateBitmap不太方便,参数不好理解。我们再回味一下,既然有兼容设备,那么有没有兼容位图呢?恭喜你,猜对了!就是有兼容位图,它与设备上下文相关,而且创建函数非常简单:
HBITMAP CreateCompatibleBitmap(
  HDC hdc,        // handle to DC
  int nWidth,     // width of bitmap, in pixels
  int nHeight     // height of bitmap, in pixels
);
只需要一个设备上下文句柄和位图的大小。需要注意一点的是,得到的位图颜色格式与hdc的颜色格式是一样的。如果hdc是一个单色的(没有选进位图的兼容DC就是),那么得到位图也就是单色的。
好了,差不多就这么多要点吧,在实际中的应用我们下回再谈!

抱歉!评论已关闭.