C++针对bmp格式解析实例

 更新时间:2014年10月15日 09:12:56   投稿:shichen2014  
这篇文章主要介绍了C++针对bmp格式解析实例,设计CWnd框架的使用及位图的操作,需要的朋友可以参考下

本文实例讲述了C++针对bmp格式解析的方法,分享给大家供大家参考。具体方法如下:

写这代码时,容易出现如下错误:
1. 忘了on_wm_paint()  一直在界面上画不出来
2. 正确写法

复制代码 代码如下:
BYTE* pBits = (BYTE*)lpBase + pbitmapFileHeader->bfOffBits;

写成了 

复制代码 代码如下:
BYTE* pBits =  pbitmapFileHeader->bfOffBits;

这里主要是用了前面一篇中的CWnd框架

.cpp源文件如下:

复制代码 代码如下:
#include "ReadBMP.h" 
#include "resource.h" 
#include <afxdlgs.h > 
 
CMyApp theApp; 
BOOL CMyApp::InitInstance() 

    m_pMainWnd = new CMainWindow; 
    m_pMainWnd->ShowWindow(m_nCmdShow); 
    return TRUE; //必须返回TRUE,否则不会进入消息循环,界面会直接退出 

 
//CMainWindow 
BEGIN_MESSAGE_MAP(CMainWindow, CWnd) 
ON_WM_CREATE() 
ON_WM_PAINT() 
ON_COMMAND(IDC_OPEN, OnOpen) 
END_MESSAGE_MAP() 
//构造函数 
CMainWindow::CMainWindow() 

    LPCTSTR lpszClassName = ::AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, ::LoadCursorA(NULL, IDC_ARROW), (HBRUSH)(COLOR_3DFACE+1), theApp.LoadIcon(IDI_MAIN)); 
    CreateEx(WS_EX_CLIENTEDGE, lpszClassName, "xxx", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL); 

//析构函数 
CMainWindow::~CMainWindow() 

 

//消息映射函数 
int CMainWindow::OnCreate(LPCREATESTRUCT lpCreateStruct) 

    //OutputDebugString("oncreate"); 
    CClientDC dc(this); 
    m_hMemDC = ::CreateCompatibleDC(dc); 
    m_nWidth = 0; 
    m_nHeight = 0; 
    //设置菜单 
    HMENU hMenu = ::LoadMenuA(theApp.m_hInstance, (LPCSTR)IDR_MENU); 
    ::SetMenu(m_hWnd, hMenu); 
    return 0; 

 
void CMainWindow::OnNcDestroy( ) 

    delete this; 

void CMainWindow::OnDestroy() 

     

void CMainWindow::OnPaint() 

    CPaintDC dc(this); 
    ::BitBlt(dc, 0, 0, m_nWidth, m_nHeight, m_hMemDC, 0, 0, SRCCOPY); 

void CMainWindow::OnOpen() 

    CFileDialog dlg(TRUE); 
    if (IDOK != dlg.DoModal()) 
    { 
        return; 
    } 
    HANDLE  hFile = ::CreateFile(dlg.GetPathName(), GENERIC_READ , FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
    if (INVALID_HANDLE_VALUE == hFile) 
    { 
        return; 
    } 
    HANDLE  hFileMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); 
    if (NULL == hFileMap) 
    { 
        return; 
    } 
    LPVOID lpBase = ::MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0); 
    if (NULL == lpBase) 
    { 
        return; 
    } 
    //从头结构中取三个信息:1.bfOffBits位图数据在文件中的起始位置,2.m_nWidth图像的宽,3.m_nHeight图像的高 
    BITMAPFILEHEADER* pbitmapFileHeader; 
    BITMAPINFO* pbitmapInfo; 
    pbitmapFileHeader = (BITMAPFILEHEADER*)lpBase; 
    if (pbitmapFileHeader->bfType != MAKEWORD('B','M')) 
    { 
        MessageBox("not bmp"); 
        ::UnmapViewOfFile(lpBase); 
        ::CloseHandle(hFileMap); 
        ::CloseHandle(hFile); 
    } 
    //DWORD bfOffBits = pbitmapFileHeader->bfOffBits; 
    BYTE* pBits = (BYTE*)lpBase + pbitmapFileHeader->bfOffBits; 
    pbitmapInfo = (BITMAPINFO*)((BYTE*)lpBase + sizeof(BITMAPFILEHEADER)); 
    m_nWidth = pbitmapInfo->bmiHeader.biWidth; 
    m_nHeight = pbitmapInfo->bmiHeader.biHeight; 
    //显示BMP文件到内存设备 
    //得客户区DC 
    CClientDC dc(this); 
    //创建与客户区DC兼容的位图 
    HBITMAP hBitmap = ::CreateCompatibleBitmap(dc, m_nWidth, m_nHeight); 
    if (hBitmap == 0) 
    { 
        return; 
    } 
    //位图选入内存DC 
    ::SelectObject(m_hMemDC, hBitmap); 
 
    //图像数据放到建立的DC中 
    ::SetDIBitsToDevice(m_hMemDC, 0, 0, m_nWidth, m_nHeight, 0, 0, 0, m_nHeight, pBits, pbitmapInfo, DIB_RGB_COLORS); 
 
    ::InvalidateRect(m_hWnd, NULL, TRUE); 
    ::DeleteObject(hBitmap); 
 
    ::UnmapViewOfFile(lpBase); 
    ::CloseHandle(hFileMap); 
    ::CloseHandle(hFile); 
 
}

.h头文件如下:

复制代码 代码如下:
#include <afxwin.h> 
 
class CMyApp:public CWinApp 

public: 
    virtual BOOL InitInstance(); 
}; 
 
//CMainWindow 
class CMainWindow:public CWnd 

public: 
    CMainWindow(); 
    ~CMainWindow(); 
 
protected: 
    HDC m_hMemDC; //与客户区兼容的内存DC句柄  
    UINT m_nWidth; //BMP的宽度 
    UINT m_nHeight; //BMP的高度 
     
    //消息映射 
    afx_msg void OnNcDestroy( ); 
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); 
    afx_msg void OnDestroy( ); 
    afx_msg void OnOpen(); 
    afx_msg void OnPaint(); 
    DECLARE_MESSAGE_MAP() 
};

希望本文所述对大家的C++程序设计有所帮助。

相关文章

  • C++中如何使用引用避免内存复制

    C++中如何使用引用避免内存复制

    C++引用是一种强大的工具,可以避免在函数调用过程中发生的常见内存复制问题,本文主要介绍了C++中如何使用引用避免内存复制,感兴趣的可以了解一下
    2023-10-10
  • 嵌入式C实战项目开发技巧:对一个有规律的数组表进行位移操作的方法

    嵌入式C实战项目开发技巧:对一个有规律的数组表进行位移操作的方法

    今天小编就为大家分享一篇关于嵌入式C实战项目开发技巧:对一个有规律的数组表进行位移操作的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • C++中replace()函数使用方法汇总

    C++中replace()函数使用方法汇总

    这篇文章主要介绍了C++中replace()函数使用方法汇总,在这篇文章中为大家详细介绍C++ replace()函数的各种应用方式,希望朋友们可以从这里介绍的内容充分掌握这一应用技巧
    2015-11-11
  • C++实现打地鼠游戏设计

    C++实现打地鼠游戏设计

    这篇文章主要为大家详细介绍了C++实现打地鼠游戏设计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • 如何写好C main函数的几个注意事项

    如何写好C main函数的几个注意事项

    这篇文章主要介绍了如何写好C main函数的几个注意事项,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-06-06
  • C++右值引用与move和forward函数的使用详解

    C++右值引用与move和forward函数的使用详解

    为了支持移动操作,新标准引入了一种新的引用类型——右值引用(rvalue reference)。所谓右值引用就是必须绑定到右值的引用,这篇文章主要介绍了C++右值引用与move和forward的使用
    2022-08-08
  • C++中const应放在类型前还是后

    C++中const应放在类型前还是后

    之前遇到小伙伴问C++中const加在类型名前和变量名前的区别,今天给大家简单分析下。
    2016-05-05
  • QT基于TCP网络聊天室

    QT基于TCP网络聊天室

    这篇文章主要为大家详细介绍了QT基于TCP网络聊天室,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • swift Character类型详解及实例

    swift Character类型详解及实例

    这篇文章主要介绍了 swift Character类型详解及实例的相关资料,需要的朋友可以参考下
    2017-06-06
  • 浅析C语言中typeof关键字用法

    浅析C语言中typeof关键字用法

    typeof关键字是C语言中的一个新扩展。在linux内核源代码中广泛使用。接下来通过本文给大家分享C语言中typeof关键字用法,需要的朋友参考下
    2017-02-02

最新评论