MFC贴图

说明:
1.创建MFC的对话框窗口。不使用PHOTO CONCTRUL.直接在窗口画出来。
2.画后面的图,前面的图清空。
3.对话框窗口的大小根据图片的大小改变。

步骤:
1.创建常用的MFC程序窗口,添加所需要的控件。
2.在控件的消息中添加CFileDialog ,用于打开文件。

贴图的重要步骤:
1.获取文件的句柄(图片、文档等)CreateFile()。
2.建立内存映射CreateFileMapping()。作用:可以使图片(文件)一次性加载到内存中。
3.将映射中的内容加载到计算机内存。MapViewOfFile()。

//可以参考bitmap格式的相关文档
4.分别 获取bitmap的头部信息,bmHead->bfType== MAKEWORD('B', 'M')。
注意:BITMAP的bfType,该值必需是0x4D42,也就是字符'BM'。
5.bitmap的数据内容。BYTE *pBitmapData = (BYTE*)bmHead + bmHead->bfOffBits;
6.bitmap的的大小
UINT uWidth = pBitmapHeadInfo->bmiHeader.biWidth;
UINT uHeight = pBitmapHeadInfo->bmiHeader.biHeight;


7.创建兼容DC。大小与客户区一样。
HDC hMemDc = CreateCompatibleDC(dc);
注意:画图不是在真实客户区的DC上画,而是在另一个DC(兼容DC),就好比在客户区上面放
一块画布,在这块布上作图。

8.画图
SetDIBitsToDevice();
BitBlt();

注意:
1.每次加载前、后进行刷新重绘。Invalidate(TRUE);

2.控件的本质就是窗口。在MFC中获取窗口句柄的方法(如下)。

CWnd *cwd = GetDlgItem(IDC_BUTTON1);
HWND hBotton = cwd->GetSafeHwnd();

 


源代码:

全局变量
CString m_strFilePath; //保存图片的路径


//加载按钮
void CFileMappingDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
Invalidate(TRUE);
CFileDialog filedlg(TRUE);
if (filedlg.DoModal()==IDOK)
{
m_strFilePath = filedlg.GetPathName();

CFileMappingDlg::PaintNewMap();
}

}

 

自定义函数
void CFileMappingDlg::SetDlgRect(UINT ucX, UINT ucY)
{
//设置对话框的位置 大小
CRect rect;
rect.left = 50;
rect.top = 50;
rect.right = ucX;
rect.bottom = ucY;

MoveWindow(&rect);

//获取按钮的句柄
CWnd *cwd = GetDlgItem(IDC_BUTTON1);
HWND hBotton = cwd->GetSafeHwnd();
//设置按钮控件的位置、大小
::MoveWindow(hBotton, rect.right/ 2-50, rect.bottom/2+50, 50, 50, TRUE);
}


自定义函数
void CFileMappingDlg::PaintNewMap()
{
//打开bitmap
{
HANDLE hFile = CreateFile(m_strFilePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
MessageBox(L"hfile Error");
return;
}

//建立内存映射
HANDLE hMapping = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, NULL);
if (hMapping != NULL)
{
//将映射中的内容加载到计算机内存
void* pMapAddr = (void*)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

//获取bitmap的头部信息
BITMAPFILEHEADER* bmHead = (BITMAPFILEHEADER*)pMapAddr;
if (bmHead->bfType == MAKEWORD('B', 'M'))
{
//bitmap的数据内容
BYTE *pBitmapData = (BYTE*)bmHead + bmHead->bfOffBits;
BITMAPINFO* pBitmapHeadInfo = (BITMAPINFO *)((BYTE*)pMapAddr + sizeof(BITMAPFILEHEADER));
//bitmap的的大小
UINT uWidth = pBitmapHeadInfo->bmiHeader.biWidth;
UINT uHeight = pBitmapHeadInfo->bmiHeader.biHeight;

CFileMappingDlg::SetDlgRect(uWidth, uHeight);

//获取客户区窗口的DC,并创建兼容DC
CClientDC dc(this);
HDC hMemDc = CreateCompatibleDC(dc);
HBITMAP hBitmap = CreateCompatibleBitmap(dc, uWidth, uHeight);

//将bitmap加载进兼容DC中
SelectObject(hMemDc, hBitmap);

//贴图
SetDIBitsToDevice(hMemDc, 0, 0, uWidth, uHeight, 0, 0, 0, uHeight, pBitmapData, pBitmapHeadInfo, DIB_RGB_COLORS);
BitBlt(dc, 0, 0, uWidth, uHeight, hMemDc, 0, 0, SRCCOPY);

DeleteObject(hBitmap);
DeleteObject(hMemDc);
}
CloseHandle(hFile);
CloseHandle(hMapping);
}

}
}

posted @ 2017-09-25 10:37  gd_沐辰  阅读(1026)  评论(0编辑  收藏  举报