设为首页 加入收藏

TOP

vc显示bmp位图(三)
2012-03-11 08:21:10 来源: 作者: 【 】 浏览:3006
Tags:显示 bmp位图
 

显示所有种类bmp位图的程序DisplayBmp过程详解

1.新建一个基于多文档的项目DisplayBmp,CDisplayBmpView类的基类是CscrollView类。
2.将事先写好的DIBAPI.H和DIBAPI.CPP两个文件增加到项目中。这两个文件声明和定义了DIB处理函数。
3.String Table中的字符串资源IDR_DISPLATYPE修改为:(为了能打开.bmp格式的文件)
\nDib\nDib\nDib Files (*.bmp; *.dib)\n.bmp\nDisplayBmp.Document\nDisplayBmp Document
4.在DisplayBmpDoc.h文件中增加如下语句:(此类中增加成员变量表示DIB数据块内存句柄)
public:
HANDLE m_hDIB;
一定要在构造函数中对它初始化:m_hDIB=NULL;否则就让你死都不知道怎么死的
5.在DisplayBmpDoc.h中增加如下语句:
public:
        virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
在DisplayBmpDoc.cpp中添加如下语句
#include "dibapi.h" 
BOOL CDisplayBmpDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
if (!CDocument::OnOpenDocument(lpszPathName))
   return FALSE;

m_hDIB = LoadDIB(lpszPathName);
if (m_hDIB == NULL)
{
   // may not be DIB format
   return FALSE;
}
SetPathName(lpszPathName);
SetModifiedFlag(FALSE);     // start off with unmodified

return TRUE;
}

BOOL CDisplayBmpDoc::OnSaveDocument(LPCTSTR lpszPathName) 
{
return SaveDIB(m_hDIB, lpszPathName);
}
以上语句的作用是重载了成员函数OnOpenDocument和OnSaveDocument,分别调用了我们定义的LoadDIB和SaveDIB来读写DIB文件,所以还要包含头文件"dibapi.h"。
6.在DisplayBmpView.h中添加:
public:
CRect m_rcDIB;即为此类添加一个成员变量
将CDisplayBmpView类中的函数OnInitialUpdate()修改为:
void CDisplayBmpView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();

CDisplayBmpDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

CSize sizeTotal;
if (pDoc->m_hDIB != NULL)
{
   LPBITMAPINFOHEADER lpDIB = (LPBITMAPINFOHEADER)GlobalLock(pDoc->m_hDIB);
   m_rcDIB.left = 0;
   m_rcDIB.top = 0;
   sizeTotal.cx = m_rcDIB.right = ((LPBITMAPINFOHEADER)lpDIB)->biWidth;
   sizeTotal.cy = m_rcDIB.bottom = ((LPBITMAPINFOHEADER)lpDIB)->biHeight;
   GlobalUnlock(pDoc->m_hDIB);
}
else
{
   m_rcDIB.SetRectEmpty();
   sizeTotal.cx = sizeTotal.cy = 100;
}

SetScrollSizes(MM_TEXT, sizeTotal);
}
装入DIB文件时,OnInitialUpdate函数会首先调用
7.DisplayBmpView.cpp文件中添加语句
#include "dibapi.h"
View类的OnDraw函数修改为:
void CDisplayBmpView::OnDraw(CDC* pDC)
{
CDisplayBmpDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

if (pDoc->m_hDIB == NULL)
   return;

PaintDIB(pDC->GetSafeHdc(),
       m_rcDIB, 
    pDoc->m_hDIB, 
    m_rcDIB, 
    NULL, 
    SRCCOPY);
}

8.MainFrm.h中定义:“#define WM_REALIZEPAL     (WM_USER + 0x100)”。当系统调色板已被修改时,主框窗口将向视发送WM_REALIZEPAL消息。在CDisplayBmpView类
中增加响应该消息的函数OnRealizePal和相应的消息映射,代码如下
LRESULT CDisplayBmpView::OnRealizePal(WPARAM wParam, LPARAM lParam)
{
ASSERT(wParam != NULL);
CDisplayBmpDoc* pDoc = GetDocument();

if (pDoc->m_hDIB == NULL)
   return 0L; // must be a new document

LPBYTE lpbi = (LPBYTE)GlobalLock(pDoc->m_hDIB);
CPalette* pPal = CPalette::FromHandle(CreateDIBPalette(lpbi));
GlobalUnlock(pDoc->m_hDIB);
if (pPal != NULL)
{
   CWnd* pAppFrame = AfxGetApp()->m_pMainWnd;

   CClientDC appDC(pAppFrame);
   // All views but one should be a background palette.
   // wParam contains a handle to the active view, so the SelectPalette
   // bForceBackground flag is FALSE only if wParam == m_hWnd (this view)
   CPalette* oldPalette = appDC.SelectPalette(pPal, ((HWND)wParam) != m_hWnd);

   if (oldPalette != NULL)
   {
    UINT nColorsChanged = appDC.RealizePalette();
    if (nColorsChanged > 0)
     GetDocument()->UpdateAllViews(NULL);
    appDC.SelectPalette(oldPalette, TRUE);
   }
   else
   {
    TRACE0("\tSelectPalette failed!\n");
   }
}

return 0L;
}
在 DisplayBmpView.h添加如下代码
protected:
   afx_msg LRESULT OnRealizePal(WPARAM wParam, LPARAM lParam);

当系统调色板被修改时,主框收到系统的WM_PALETECHANGED和WM_QUERYNEWPALETTE消息,主框窗口通过下面的函数将向视发送WM_REALIZEPAL消息,OnRealizePal函数响应WM_REALIZEPAL消息。
9.添加响应WM_PALETECHANGED和WM_QUERYNEWPALETTE消息的函数,当系统察觉调色板发生变化时,会向程序的主框窗口发送这两个消息,然后由主框窗口通知各视窗。
在MainFrm.cpp中添加如下代码:
void CMainFrame::OnPaletteChanged(CWnd* pFocusWnd) 
{
CMDIFrameWnd::OnPaletteChanged(pFocusWnd);

// always realize the palette for the active view
CMDIChildWnd* pMDIChildWnd = MDIGetActive();
if (pMDIChildWnd == NULL)
   return; // no active MDI child frame
CView* pView = pMDIChildWnd->GetActiveView();
ASSERT(pView != NULL);

// notify all child windows that the palette has changed
SendMessageToDescendants(WM_REALIZEPAL, (WPARAM)pView->m_hWnd);
}

BOOL CMainFrame::OnQueryNewPalette() 
{
// always realize the palette for the active view
CMDIChildWnd* pMDIChildWnd = MDIGetActive();
if (pMDIChildWnd == NULL)
   return FALSE; // no active MDI child frame (no new palette)
CView* pView = pMDIChildWnd->GetActiveView();
ASSERT(pView != NULL);

// just notify the target view
pView->SendMessage(WM_REALIZEPAL, (WPARAM)pView->m_hWnd);
return TRUE;
}
在MainFrm.h中添加如下代码
protected:
afx_msg void OnPaletteChanged(CWnd* pFocusWnd);
afx_msg BOOL OnQueryNewPalette();


 

首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇SetTimer函数用法 下一篇CBitmap位图操作

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: