3.3.4 借助兼容DC加载DIB位图
创建一个与设备环境相兼容的DC,通过将位图暂时导入至兼容DC,然后利用CDC::BitBlt 或者CDC::StretchBlt函数将位图绘制到设备环境中。
示例代码如下:
void CFDlg::OnLoadbitmap() { // TODO: Add your control notification handler code here HBITMAP hbitmap; BITMAP bitmapinfo; CBitmap cbitmap; RECT rc; //获取指定ID号的窗口指针 CWnd* mywnd = GetDlgItem(IDC_BITMAPAREA); //定义一个与指定窗口相关的设备环境(DC) CClientDC dc(mywnd); //定义一个与dc向兼容的内存DC CDC memdc; //获取指定窗口的尺寸 mywnd->GetClientRect(&rc); //导入位图句柄 hbitmap = (HBITMAP) ::LoadImage(NULL , "D:\wanghui1.bmp" , IMAGE_BITMAP , 0 , 0 , LR_LOADFROMFILE ) ; //将位图句柄附贴至位图类对象中 cbitmap.Attach(hbitmap); //获取位图信息,包括位图宽、高等参数 cbitmap.GetBitmap(&bitmapinfo); //创建一个与指定窗口dc兼容的内存DC memdc.CreateCompatibleDC(&dc); //将位图加载到内存DC CBitmap *oldbitmap = memdc.SelectObject(&cbitmap); //将内存DC中的位图导入到指定窗口的实际DC中 // dc.StretchBlt(0, 0, (rc.right-rc.left), (rc.bottom-rc.top), &memdc, 0, 0, bitmapinfo.bmWidth, bitmapinfo.bmHeight, SRCCOPY); dc.BitBlt(0, 0, (rc.right-rc.left), (rc.bottom-rc.top), &memdc, 0, 0, SRCCOPY); //将位图从内存DC中移出 memdc.SelectObject(oldbitmap); //删除位图句柄,位图类对象在程序结束后调用其析构函数来释放内存 cbitmap.DeleteObject(); }
就上述示例代码,详细解释几个函数:
HANDLE LoadImage(
HINSTANCE hinst, // handle of the instance containing the image
LPCTSTR lpszName, // name or identifier of image
UINT uType, // type of image
int cxDesired, // desired width
int cyDesired, // desired height
UINT fuLoad // load flags
);
该函数可以导入一个图标、光标及位图。
hinst:指向应用程序的一个实例,可以通过AfxGetInstanceHandle( )函数来获取,
lpszName: 指向图像的文件名或者资源标识符,当fuLoad=LR_LOADFROMFILE时,lpszName指向文件名,hinst可取值NULL。
uType:图像类型,取值有:
value meaning
IMAGE_BITMAP 导入位图
IMAGE_CURSOR 导入光标
IMAGE_ICON 导入图标
cxDesired、cyDesired:光标或图标的宽度、高度,单位:像素。
fuLoad:当fuLoad = LR_LOADFROMFILE时,表示从lpszName指向的文件加载图像,如果LR_LOADFROMFILE未指定,lpszName指向的是资源名称。
3.3.5 利用SetDIBitsToDevice来加载位图
首先解释SetDIBitsToDevice:
int SetDIBitsToDevice(
HDC hdc, // handle to device context
int XDest, // x-coordinate of upper-left corner of dest. rect.
int YDest, // y-coordinate of upper-left corner of dest. rect.
DWORD dwWidth, // source rectangle width
DWORD dwHeight, // source rectangle height
int XSrc, // x-coordinate of lower-left corner of source rect.
int YSrc, // y-coordinate of lower-left corner of source rect.
UINT uStartScan, // first scan line in array
UINT cScanLines, // number of scan lines
CONST VOID *lpvBits, // address of array with DIB bits
CONST BITMAPINFO *lpbmi, // address of structure with bitmap info.
UINT fuColorUse // RGB or palette indexes
);
示例代码:
void CFDlg::OnLoadbitmap() {
unsigned char* ImageBuffer= NULL; unsigned char* ImageData = NULL; BITMAPFILEHEADER m_bitmapfileheader; BITMAPINFOHEADER* infoheader; RGBQUAD* palette; BITMAPINFO *bmi;; FILE *ImageFile; unsigned int BytesSize=0; if (NULL==(ImageFile=fopen("D:\wanghui1.bmp","rb"))) { printf("can not open the image file!"); return ; } else { //读取位图文件头 fread(&m_bitmapfileheader,sizeof(BITMAPFILEHEADER),1,ImageFile); //为位图信息头和调色板开辟内存 ImageBuffer = new unsigned char[m_bitmapfileheader.bfOffBits-sizeof(BITMAPFILEHEADER)]; //读取信息头与调色板数据块 fread(ImageBuffer,m_bitmapfileheader.bfOffBits-sizeof(BITMAPFILEHEADER),1,ImageFile); //将ImageBuffer强制转化成BITMAPINFO类型,然后将信息头指针和调色板指针指向对应地址位置 bmi = (BITMAPINFO*)ImageBuffer; infoheader = &(bmi->bmiHeader); palette = bmi->bmiColors; //计算文图数据字节大小 BytesSize = (infoheader->biWidth * infoheader->biHeight * (infoheader->biBitCount/8)); //开辟位图数据内存块 ImageData = new unsigned char[BytesSize]; //读取位图数据块 fread(ImageData,BytesSize,1,ImageFile); //获取指定窗口 CWnd* mywnd = GetDlgItem(IDC_BITMAPAREA); //创建指定窗口关联的DC CClientDC dc(mywnd); RECT rc; //获取指定窗口区域大小 mywnd->GetClientRect(&rc); //将位图绘制到指定窗口的DC上 SetDIBitsToDevice(dc.m_hDC, 0, 0, infoheader->biWidth, infoheader->biHeight, 0, 0, 0, infoheader->biHeight, ImageData, bmi, DIB_RGB_COLORS); } //释放动态开辟的内存 delete[] ImageBuffer; delete[] ImageData; }