小弟最近刚刚开始学习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
}
有点长,请大家耐着性子看,呵呵
程序是编写一个单文档程序,把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
}
有点长,请大家耐着性子看,呵呵
解决方案 »
- 求解决一个win32显示窗口的问题
- 300分求VC++的QQ自动注册源码
- char * data Format到 CString里显示了乱码
- 怎么弹出一个SDI?
- 在菜单中如何打开一个对话框
- 学过sdk的人都进来看看 最初期的问题关于RegisterClassEx (UP gz绝无分数)
- 请问怎么样在线程里响应事件,来者给分
- 请指教:)
- 高手出招吧,可以加分 (时间比较急,老板在催命)
- 挑战delphi程序员
- VS2008的MFC非托管程序怎样访问C#编写的WebService?如何添加Web引用?
- LINK : fatal error LNK1104: cannot open file "E:\Microsoft.obj"该怎么解决?
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
);
{
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 这个下该够你用了把 呵呵 以上代码 经过时间考验 保证能用
头文件:
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; //调色板中的颜色数量};
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 );}
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色之内的位图