共享文件的方式读取BMP文件

这个博客详细介绍了如何在MFC环境中创建一个内存映射BMP对象,并从磁盘文件加载BMP图像,然后在对话框中显示。通过使用CreateCompatibleDC、CreateCompatibleBitmap、SetDIBitsToDevice等函数,实现了BMP文件的高效读取和显示。代码中还包含了错误处理和性能计时。
摘要由CSDN通过智能技术生成
CBitMapDlg::CBitMapDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CBitMapDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    m_nHeight = 0;
    m_nWidth = 0;
}

CBitMapDlg::~CBitMapDlg()
{
    DeleteDC(m_hMemDC);
}

void CBitMapDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CBitMapDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDOK, &CBitMapDlg::OnBnClickedOk)
END_MESSAGE_MAP()


// CBitMapDlg 消息处理程序

BOOL CBitMapDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

         


	return TRUE;
}

void CBitMapDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CBitMapDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
        CClientDC dc(this);
        DWORD StartTime = timeGetTime();
        BitBlt(dc, 0, 0, m_nWidth, m_nHeight, m_hMemDC, 0, 0, SRCCOPY);
        TRACE(_T("Paint %u\n"), timeGetTime() - StartTime);
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CBitMapDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

/************************************************
    作者:
    版本:
    函数名:CreateBMP
    函数作用:创建一个内存映射BMP的文件, 然后读取打印出来
    输入参数:无
    输出参数:
    返回值: 无
    *************************************************/
BOOL CBitMapDlg::CreateBMP()
{
    CClientDC dc(this);
    m_hMemDC = ::CreateCompatibleDC(dc);
    CFileDialog file(TRUE);
    if (!file.DoModal())
    {
        return FALSE;
    }
    CString fileName = file.GetPathName();
    HANDLE hFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == hFile)
    {   
        MessageBox(_T("读取文件出错!!!"));
        return FALSE;
    }
    HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, NULL, NULL, NULL);
    LPVOID lpBase = ::MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);

    BITMAPFILEHEADER* pFileHeader = NULL;
    BITMAPINFO*       pInfoHeader = NULL;
    pFileHeader = (BITMAPFILEHEADER*)lpBase;
    if (pFileHeader->bfType != MAKEWORD('B','M'))
    {
        MessageBox("本程序只读取BMP文件!");
        ::UnmapViewOfFile(lpBase);
        CloseHandle(hMap);
        CloseHandle(hFile);
    }

    BYTE* pBits = (BYTE*)lpBase + pFileHeader->bfOffBits;

    pInfoHeader = (BITMAPINFO*)((BYTE*)lpBase + sizeof(BITMAPFILEHEADER));
    m_nWidth = pInfoHeader->bmiHeader.biWidth;
    m_nHeight = pInfoHeader->bmiHeader.biHeight;

    DWORD StartTime = timeGetTime();
    HBITMAP hBitmap = ::CreateCompatibleBitmap(dc, m_nWidth, m_nHeight);
    ::SelectObject(m_hMemDC, hBitmap);
    int nRet = ::SetDIBitsToDevice(m_hMemDC, 0, 0, m_nWidth, m_nHeight,
        0,0, 0, m_nHeight,pBits, pInfoHeader, DIB_RGB_COLORS);
    TRACE(_T("%u\n"), timeGetTime() - StartTime);
    ::InvalidateRect(this->GetSafeHwnd(), NULL, TRUE);

    DeleteObject(hBitmap);
    UnmapViewOfFile(lpBase);
    CloseHandle(hMap);
    CloseHandle(hFile);
    return TRUE;
}

void CBitMapDlg::OnBnClickedOk()
{
    CreateBMP();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值