小弟最近刚刚开始学习MFC,昨天照着一本书编程(把书里的源代码敲进VC里)。
程序是编写一个单文档程序,把BMP图像文件显示出来,鞘好以后编译连接都没问题,运行后试着打开一个BMP文件,但是文档里什么都没有,只是一片空白,不过左上注有BMP文件的名字,下面我把我的具体操作过程及源代码写出来,请大家帮我找找问题,谢谢
我给程序起名为MySee,基类是CView,选择要生产的文件的扩展名为mys(会不会是这里出问题呢?应该把扩展名设为bmp)。
下面是我的代码:有点长,请大家耐着性子看,呵呵
// MySeeDoc.cpp : implementation of the CMySeeDoc class
//#include "stdafx.h"
#include "MySee.h"#include "MySeeDoc.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CMySeeDoc
IMPLEMENT_DYNCREATE(CMySeeDoc, CDocument)
BEGIN_MESSAGE_MAP(CMySeeDoc, CDocument)
//{{AFX_MSG_MAP(CMySeeDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
//    DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMySeeDoc construction/destruction
CMySeeDoc::CMySeeDoc()
{
// TODO: add one-time construction code here}
CMySeeDoc::~CMySeeDoc()
{
if (flag==1)
{HeapFree(GetProcessHeap(),0,pbi);
HeapFree(GetProcessHeap(),0,lpBuf);
}
}
BOOL CMySeeDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMySeeDoc serialization
void CMySeeDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CMySeeDoc diagnostics
#ifdef _DEBUG
void CMySeeDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CMySeeDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMySeeDoc commands
void CMySeeDoc::OnFileOpen()
{//TODO:Add your command handler code here
LPCTSTR lpszFilter="BMP Files(*.bmp)|*.bmp|ÈκÎÎļþ|*.*||";
CFileDialog dlg1(TRUE,lpszFilter,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,lpszFilter,NULL);
CString filename;
CFile file;
//´ò¿ªÎļþ¶Ô»°¿ò
if (dlg1.DoModal()==IDOK)
{
filename=dlg1.GetPathName();
if (file.Open (filename,CFile ::modeRead|CFile::shareDenyNone,NULL)==0)
{//¶ÁÈ¡Îļþʧ°Ü
AfxMessageBox("ÎÞ·¨´ò¿ªÎļþ",MB_OK,0);
return;
}
//¶ÁÈ¡Í·Îļþ
file.Read (&bf,sizeof (bf));
//ÅжÏÊÇ·ñÊÇBMPÎļþ
if (bf.bfType!=0x4D42)//'BM'
{
AfxMessageBox("·ÇBMPÎļþ!!",MB_OK,0);
return;
}
//ÅжÏÎļþÊÇ·ñËð»µ
if (file.GetLength()!=bf.bfSize)
{
AfxMessageBox("ÎļþÒÑËð»µ",MB_OK,0);
return;
}
//¶ÁÎļþÐÅϢͷ
file.Read(&bi,sizeof(bi));
//¼ÆËãµ÷É«°åÊýÄ¿
numQuad=0;
if (bi.biBitCount<24)
{
numQuad=1<<bi.biBitCount;
}
//ΪͼÏñÎļþpbiÉêÇë¿Õ¼ä
pbi=(BITMAPINFO*)HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD));
memcpy(pbi,&bi,sizeof(bi));
quad=(RGBQUAD*)((BYTE*)pbi+sizeof(BITMAPINFOHEADER));
//¶ÁÈ¡µ÷É«°å
if (numQuad!=0)
{
file.Read(quad,sizeof(RGBQUAD)*numQuad);
}
//ΪͼÏñÊý¾ÝÉêÇë¿Õ¼ä
bi.biSizeImage=bf.bfSize-bf.bfOffBits;
lpBuf=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage);
//¶ÁȡͼÏñÊý¾Ý
file.Read(lpBuf,bi.biSizeImage);
//ͼÏñ¶ÁÈ¡Íê±Ï£¬¹Ø±ÕÎļþ£¬ÉèÖñêÖ¾
file.Close();
flag=1;
}
}
MySeeView.cpp : implementation of the CMySeeView class
//#include "stdafx.h"
#include "MySee.h"
#include "MySeeDoc.h"
#include "MySeeView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMySeeView
IMPLEMENT_DYNCREATE(CMySeeView, CView)
BEGIN_MESSAGE_MAP(CMySeeView, CView)
//{{AFX_MSG_MAP(CMySeeView)
// NOTE - the ClassWizard will add and remove mapping macros here.
//    DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMySeeView construction/destruction
CMySeeView::CMySeeView()
{
// TODO: add construction code here}
CMySeeView::~CMySeeView()
{
}
BOOL CMySeeView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
//  the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMySeeView drawing
void CMySeeView::OnDraw(CDC* pDC)
{
CMySeeDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}/////////////////////////////////////////////////////////////////////////////
// CMySeeView printingBOOL CMySeeView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CMySeeView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CMySeeView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CMySeeView diagnostics
#ifdef _DEBUG
void CMySeeView::AssertValid() const
{
CView::AssertValid();
}
void CMySeeView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMySeeDoc* CMySeeView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMySeeDoc)));
return (CMySeeDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMySeeView message handlers
void CMySeeView::OnPaint()
{
CPaintDC dc(this);//device context for painting //TODO:Add your message handler code here
//µÃµ½ÎĵµÖ¸Õë
CMySeeDoc* pDoc=GetDocument();
ASSERT_VALID(pDoc);
//ÊÇ·ñÒѾ­´ò¿ªÒ»¸öBMPÎļþ
if (pDoc->flag==1)
{
SetDIBitsToDevice(dc.m_hDC,//DIB½«Êä³öµÄÉ豸ÃèÊö±í
0,//É豸ÃèÊö±íÖÐλͼÊä³öÆðʼÂß¼­x×ø±ê
0,//É豸ÃèÊö±íÖÐλͼÊä³öÆðʼÂß¼­y×ø±ê
pDoc->bi.biWidth,//DIBµÄ¿í¶È
pDoc->bi.biHeight,//DIBµÄ¸ß¶È
0,//DIB¿ªÊ¼¶ÁÈ¡Êä³öµÄÏñËØÊý¾ÝµÄxλÖÃ
0,//DIB¿ªÊ¼¶ÁÈ¡Êä³öµÄÏñËØÊý¾ÝµÄyλÖÃ
0,//DIBÖÐÏñËصÄˮƽÐкţ¬Ëû¶ÔÓ¦lpBitsÄڴ滺³åÇøµÚÒ»ÐÐÊý¾Ý
pDoc->bi.biHeight,//DIBµÄÐÐÊý£¬¶ÔÓ¦°üº¬ÔÚÓÉlpBitsËùÖ¸Äڴ滺³åÇøÖеÄÊý¾Ý
pDoc->lpBuf,//°üº¬ÏñËØÊý¾ÝµÄÄÚ´Ù»º³åÇøµÄÖ¸Õë
pDoc->pbi,//Ö¸Ïò³õʼ»¯Á˵ÄBITMAPINFOÊý¾Ý½á¹¹µÄÖ¸Õ룬ÃèÊöÁËλͼµÄ´óСºÍÉ«²ÊÊý¾Ý
DIB_RGB_COLORS);//Ö¸¶¨ÊÇÏÔʾµÄÑÕÉ«
}
Invalidate(FALSE);
//Do not call CView::OnPaint() for painting messages
}
有点长,请大家耐着性子看,呵呵

解决方案 »

  1.   

    去看我发布的资源吧,名字叫bmp24读取显示,自己去下
      

  2.   

    lz试试这个
    CDC *pDC=GetDC();
    CRect rect(0,0,1000,1000);
    CBrush brush(RGB(255,255,255));
    pDC->FillRect(&rect,&brush);
    ::StretchDIBits(pDC->GetSafeHdc(),0,0,w,h,0,0,bi.biWidth,bi.biHeight,
    pImageData,pbi,DIB_RGB_COLORS,SRCCOPY);StretchDIBits函数的功能是拷贝一个DIB中的某矩形区域中的像素的颜色数据到指定的矩形区域中,如果目的矩形区域的大小与源区域不相同,该函数会自动地进行伸展或压缩以使之适合显示。它的原型如下:int StretchDIBits(
      HDC hdc,                      // 设备上下文句柄
      int XDest,                    // 目的区域左上角X轴坐标
      int YDest,                    // 目的区域左上角Y轴坐标
      int nDestWidth,               // 目的区域的宽度
      int nDestHeight,              // 目的区域的高度
      int XSrc,                     // 源区域左上角X轴坐标
      int YSrc,                     // 源区域左上角Y轴坐标
      int nSrcWidth,                // 源区域的宽度
      int nSrcHeight,               // 源区域的高度
      CONST VOID *lpBits,           // 指向位图的比特数据,即像素数据数组
      CONST BITMAPINFO *lpBitsInfo, // 位图头部信息的指针,包含了该DIB的信息
      UINT iUsage,                  // usage options
      DWORD dwRop                   // raster operation code
    );
      

  3.   

    BOOL GetScreenCaps(int *x,int *y) //得到屏幕的分辨率
    {
    HDC hScrDC;

    hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    *x = GetDeviceCaps(hScrDC, HORZRES);
    *y = GetDeviceCaps(hScrDC, VERTRES);
    DeleteObject(hScrDC); return TRUE;
    }
    /*将鼠标光标画到指定的地方去*/
    BOOL DrawMouse(HDC hdc,HCURSOR hcursor)
    {
    POINT CursorPos;
    ICONINFO IconInfo;// hcursor = ::GetCursor();
    // If the mouse cursor handle is invalid then forget it
    if (hcursor == NULL)
    return FALSE;

    // Get the cursor position
    if (!GetCursorPos(&CursorPos))
    return FALSE;

    // Translate position for hotspot
    if (GetIconInfo(hcursor, &IconInfo))
    {
    CursorPos.x -= ((int) IconInfo.xHotspot);
    CursorPos.y -= ((int) IconInfo.yHotspot);
    if (IconInfo.hbmMask != NULL)
    DeleteObject(IconInfo.hbmMask);
    if (IconInfo.hbmColor != NULL)
    DeleteObject(IconInfo.hbmColor);
    }

    // Draw the cursor
    DrawIconEx(
    hdc, // handle to device context 
    CursorPos.x, CursorPos.y, //
    hcursor, // handle to icon to draw 
    0,0, // width of the icon 
    0, // index of frame in animated cursor 
    NULL, // handle to background brush 
    DI_NORMAL | DI_COMPAT // icon-drawing flags 
    ); return TRUE;
    }
    //取屏幕数据,lpRect指定取屏幕的范围,len指定buf的大小
    //
    // 当buf不为NULL且长度足够拷贝数据时,返回图片数据大小
    // 当buf为NULL或者长度不够拷贝数据时,返回图片数据大小
    // 当执行失败时返回0
    unsigned GetScrnData(LPRECT lpRect, unsigned char * buf, unsigned len)
    {
    HDC       hScrDC, hMemDC;     // 屏幕和内存设备描 述表  
    HBITMAP    hBitmap, hOldBitmap;   // 位图句柄

    // 位图宽度和高度
    int iWidth, iHeight;
    iWidth = lpRect->right- lpRect->left;
    iHeight = lpRect->bottom - lpRect->top;

    //为屏幕创建设备描述表
    hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);

    // 获得屏幕分辨率
    int       xScrn, yScrn;         
    xScrn = GetDeviceCaps(hScrDC, HORZRES);
    yScrn = GetDeviceCaps(hScrDC, VERTRES);

    //为屏幕设备描述表创建兼容的内存设备描述表
    hMemDC = CreateCompatibleDC(hScrDC);
    hBitmap = CreateCompatibleBitmap(hScrDC, iWidth,iHeight);
    hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
    StretchBlt(hMemDC, 0, 0, iWidth, iHeight, hScrDC, 0, 0, xScrn,yScrn, SRCCOPY);

    /*这里把鼠标的图标画到图像中去*/
    if(buf && len)
    {
    // DrawMouse(hMemDC);
    HCURSOR cur = ::GetCursor();
    POINT curPos;
    GetCursorPos(&curPos);
    DrawIcon(hMemDC,curPos.x,curPos.y,cur);
    }
    // 创建位图头
    BITMAPINFO bmpInfo;
    ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
    bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth = iWidth;
    bmpInfo.bmiHeader.biHeight = iHeight;
    bmpInfo.bmiHeader.biPlanes = 1;
    bmpInfo.bmiHeader.biBitCount = 24;
    bmpInfo.bmiHeader.biCompression = BI_RGB;

    //图片信息
    if (0 == GetDIBits(hMemDC, hBitmap, 0, iHeight, NULL, &bmpInfo, DIB_RGB_COLORS))
    {
    MessageBox(NULL,"GetDIBits Fail !","ERROR",MB_OK);
    return 0;
    }

    //当接收缓冲为空或者,长度不够时返回需要的长度
    if (NULL == buf || len < bmpInfo.bmiHeader.biSizeImage)
    {
    // return bmpInfo.bmiHeader.biSizeImage;
    goto hah;
    }

    //把图片数据拷至缓冲中去
    GetDIBits(hMemDC, hBitmap, 0, iHeight, buf, &bmpInfo, DIB_RGB_COLORS);

    hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
    hah:
    int erro = DeleteObject(hBitmap);
    erro = DeleteDC(hScrDC);
    erro = DeleteDC(hMemDC);
    // DeleteObject(hBitmap);

    // 返回位图句柄
    return bmpInfo.bmiHeader.biSizeImage;
    }void DisplayPicture(HDC hdc,char *pdata,int datalen,int s_w,int s_h,int w,int h) //显示图像
    {
    BITMAPINFO bmpInfo;
    ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
    bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth = 0;
    bmpInfo.bmiHeader.biHeight = 0;
    bmpInfo.bmiHeader.biPlanes = 1;
    bmpInfo.bmiHeader.biBitCount = 24;
    bmpInfo.bmiHeader.biCompression = BI_RGB;
    bmpInfo.bmiHeader.biSizeImage = datalen;
    bmpInfo.bmiHeader.biWidth = w;
    bmpInfo.bmiHeader.biHeight = h; StretchDIBits(hdc,0,0,s_w,s_h,
    0,0,w,h,pdata,&bmpInfo,
    DIB_RGB_COLORS,SRCCOPY);
    }
    回lz   这个下该够你用了把 呵呵 以上代码 经过时间考验 保证能用
      

  4.   

    我记得在VC 6.0宝典中有创建DIB位图的类,发些代码给你:
    头文件:
    class CDib
    {public:
    CDib();
    ~CDib(); BOOL Load( const char * );  //加载位图
    BOOL Save( const char * );  //保存位图
    BOOL Draw( CDC *, int nX = 0, int nY = 0, int nWidth = -1, int nHeight = -1 );//绘制位图
    BOOL SetPalette( CDC * );//使用调色板private:
    CPalette m_Palette;
    unsigned char *m_pDib, *m_pDibBits;//m_pDib是从BITMAPINFOHEADER结构开始起的数据,m_pDibBits是实际的位图像素数据
    DWORD m_dwDibSize;//BITMAPINFOHEADER结构开始到文件未尾共有多长
    BITMAPINFOHEADER *m_pBIH;
    RGBQUAD *m_pPalette;   //位图中的颜色表数组
    int m_nPaletteEntries;  //调色板中的颜色数量};
      

  5.   

    实现体:
    CDib::CDib()
    { // Set the Dib pointer to
    // NULL so we know if it's
    // been loaded.
    m_pDib = NULL;}CDib::~CDib()
    { // If a Dib has been loaded,
    // delete the memory.
    if( m_pDib != NULL )
    delete [] m_pDib;}BOOL CDib::Load( const char *pszFilename )
    { CFile cf; // Attempt to open the Dib file for reading.
    if( !cf.Open( pszFilename, CFile::modeRead ) )
    return( FALSE ); DWORD dwDibSize;
            //得到从BITMAPFILEHEADER到文件尾的长度
    dwDibSize =
    cf.GetLength() - sizeof( BITMAPFILEHEADER ); // Attempt to allocate the Dib memory.
    unsigned char *pDib;
    pDib = new unsigned char [dwDibSize];
            //DIB位图为空,则失败
    if( pDib == NULL )
    return( FALSE ); BITMAPFILEHEADER BFH; // Read in the Dib header and data.
    try{ // 如果读取的位图文件不是DIB
    if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
    != sizeof( BITMAPFILEHEADER ) || // Is the type 'MB'?
    BFH.bfType != 'MB' || // Did we read in the remaining data?
    cf.Read( pDib, dwDibSize ) != dwDibSize ){ // Delete the memory if we had any
    // errors and return FALSE.
    delete [] pDib;
    return( FALSE );
    }
    } // If we catch an exception, delete the
    // exception, the temporary Dib memory,
    // and return FALSE.
    catch( CFileException *e ){
    e->Delete();
    delete [] pDib;
    return( FALSE );
    }

    //删除上一次的DIB指针
    if( m_pDib != NULL )
    delete m_pDib; // Store the local Dib data pointer and
    // Dib size variables in the class member
    // variables.
    m_pDib = pDib;
    m_dwDibSize = dwDibSize; //m_pDib指针指向了BITMAPINFOHEADER结构,因此可以直接转化成这个结构
    m_pBIH = (BITMAPINFOHEADER *) m_pDib;
            //将m_pDib指针向后偏移BITMAPINFOHEADER结构的尺寸,那么它指向了颜色表数组
    m_pPalette =
    (RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)]; // 获得颜色深度
    m_nPaletteEntries = 1 << m_pBIH->biBitCount;
            //如果颜色位大于8,也就是深度大于256,则调色板不存在.
    if( m_pBIH->biBitCount > 8 )
    m_nPaletteEntries = 0;
            //如果BITMAPINFOHEADER结构的成员biClrUsed不为空,说明位图使用了比调色板颜色数少的颜色,而这个颜色就是biClrUsed
    else if( m_pBIH->biClrUsed != 0 )
    m_nPaletteEntries = m_pBIH->biClrUsed; //当m_pDibBits指针向后偏移一个BITMAPINFOHEADER的长度,再向后移若干个颜色表长度的,那么它将指向实际的像素数据. 
    m_pDibBits =
    &m_pDib[sizeof(BITMAPINFOHEADER)+
    m_nPaletteEntries*sizeof(RGBQUAD)]; // 如果之前已使用了调色板,则删除它.
    if( m_Palette.GetSafeHandle() != NULL )
    m_Palette.DeleteObject(); //如果位图色深少或等于256,那么需要创建调色板,才能显示位图.
    if( m_nPaletteEntries != 0 ){ // Allocate the LOGPALETTE structure.
    LOGPALETTE *pLogPal = (LOGPALETTE *) new char
    [sizeof(LOGPALETTE)+
    m_nPaletteEntries*sizeof(PALETTEENTRY)]; if( pLogPal != NULL ){ // Set the LOGPALETTE to version 0x300
    // and store the number of palette
    // entries.
    pLogPal->palVersion = 0x300;
    pLogPal->palNumEntries = m_nPaletteEntries; // Store the RGB values into each
    // PALETTEENTRY element.
    for( int i=0; i<m_nPaletteEntries; i++ ){
    pLogPal->palPalEntry[i].peRed =
    m_pPalette[i].rgbRed;
    pLogPal->palPalEntry[i].peGreen =
    m_pPalette[i].rgbGreen;
    pLogPal->palPalEntry[i].peBlue =
    m_pPalette[i].rgbBlue;
    } // Create the CPalette object and
    // delete the LOGPALETTE memory.
    m_Palette.CreatePalette( pLogPal );
    delete [] pLogPal;
    }
    }

    return( TRUE );}BOOL CDib::Save( const char *pszFilename )
    { // If we have no data, we can't save.
    if( m_pDib == NULL )
    return( FALSE ); CFile cf; // Attempt to create the file.
    if( !cf.Open( pszFilename,
    CFile::modeCreate | CFile::modeWrite ) )
    return( FALSE );

    // Write the data.
    try{ // First, create a BITMAPFILEHEADER
    // with the correct data.
    BITMAPFILEHEADER BFH;
    memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
    BFH.bfType = 'MB';
    BFH.bfSize = sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
    BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
    sizeof( BITMAPINFOHEADER ) +
    m_nPaletteEntries * sizeof( RGBQUAD ); // Write the BITMAPFILEHEADER and the
    // Dib data.
    cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
    cf.Write( m_pDib, m_dwDibSize );
    } // If we get an exception, delete the exception and
    // return FALSE.
    catch( CFileException *e ){
    e->Delete();
    return( FALSE );
    } return( TRUE );}BOOL CDib::Draw( CDC *pDC, int nX, int nY, int nWidth, int nHeight )
    { // If we have not data we can't draw.
    if( m_pDib == NULL )
    return( FALSE ); // Check for the default values of -1
    // in the width and height arguments. If
    // we find -1 in either, we'll set them
    // to the value that's in the BITMAPINFOHEADER.
    if( nWidth == -1 )
    nWidth = m_pBIH->biWidth;
    if( nHeight == -1 )
    nHeight = m_pBIH->biHeight;

    // 将DIB位图缩放到目标区域内.
    StretchDIBits( pDC->m_hDC, nX, nY,
    nWidth, nHeight,
    0, 0,
    m_pBIH->biWidth, m_pBIH->biHeight,
    m_pDibBits,
    (BITMAPINFO *) m_pBIH,
    BI_RGB, SRCCOPY );

    return( TRUE );}BOOL CDib::SetPalette( CDC *pDC )
    { // If we have not data we
    // won't want to set the palette.
    if( m_pDib == NULL )
    return( FALSE ); // Check to see if we have a palette
    // handle. For Dibs greater than 8 bits,
    // this will be NULL.
    if( m_Palette.GetSafeHandle() == NULL )
    return( TRUE ); //在调色板存在的情况下应用调色板
    CPalette *pOldPalette;
            //将调色板选入到设备环境
    pOldPalette = pDC->SelectPalette( &m_Palette, FALSE );
            //将调色板应用到系统调色板
    pDC->RealizePalette();
    pDC->SelectPalette( pOldPalette, FALSE ); return( TRUE );}
      

  6.   

    外面调用代码如下:
    void CShowDIBView::OnFileOpen() 
    {
    static char szFilter[] = "BMP Files(*.BMP)|*.BMP||"; CFileDialog FileDlg( TRUE, NULL, NULL,
    OFN_HIDEREADONLY, szFilter ); if( FileDlg.DoModal() == IDOK &&
    m_Dib.Load( FileDlg.GetPathName() ) ){
    InvalidateRect( NULL, TRUE );
    UpdateWindow();
    }}
    void CShowDIBView::OnDraw(CDC* pDC)
    {
    CShowDIBDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc); RECT Rect;
    GetClientRect( &Rect );
            //如果位图使用调色板,下面的调用是必要的
    m_Dib.SetPalette( pDC );
    m_Dib.Draw( pDC, 0, 0,
    Rect.right, Rect.bottom );}
    这个方法不但可以显示16,24,32位的位图,还可以显示256色之内的位图