#ifndef __MEM_DC__H__
#define __MEM_DC__H__
//防止重复编译
class CMemDC : public CDC
{
CSize m_size;
public:
~CMemDC()
{
DeleteDC();
}
CMemDC()
{
m_size.cx = m_size.cy=0;
}
CMemDC(UINT nBitmap,CDC* pDC=NULL)
{
LoadBitmap(nBitmap,pDC);
}
CMemDC(LPCSTR szFile,CDC* pDC=NULL)
{
LoadBitmap(szFile,pDC);
}
CMemDC(int cx,int cy,CDC* pDC=NULL)
{
Create(cx,cy,pDC);
}
BOOL DeleteDC()
{
if(!GetSafeHdc())
return FALSE;
CBitmap* pBitmap = GetCurrentBitmap();
if(pBitmap)
pBitmap ->DeleteObject();
return CDC::DeleteDC();
}
int GetWidth(){return m_size.cx;}
int GetHeight(){return m_size.cy;}
BOOL Create(int cx,int cy,CDC* pDC=NULL)
{//创建空白位图
CBitmap bmp;
if(!bmp.CreateCompatibleBitmap(pDC,cx,cy))
return FALSE;
m_size.cx = cx;
m_size.cy = cy;
CreateCompatibleDC(pDC);
SelectObject(&bmp);
return TRUE;
}
BOOL LoadBitmap(UINT nBitmap,CDC* pDC=NULL)
{//进程内位图资源加载
CBitmap bmp;
if(!bmp.LoadBitmap(nBitmap))
return FALSE;
BITMAP bm;
bmp.GetBitmap(&bm);
m_size.cx = bm.bmWidth;
m_size.cy = bm.bmHeight;
CreateCompatibleDC(pDC);
SelectObject(&bmp);
return TRUE;
}
BOOL LoadBitmap(LPCSTR szFile,CDC* pDC=NULL)
{//进程外位图图片文件加载
HBITMAP hBitmap = (HBITMAP)LoadImage(NULL,szFile,IMAGE_BITMAP,
0,0,LR_LOADFROMFILE);
if(!hBitmap)
return FALSE;
BITMAP bm;
GetObject(hBitmap,sizeof(bm),&bm);
m_size.cx = bm.bmWidth;
m_size.cy = bm.bmHeight;
CreateCompatibleDC(pDC);
SelectObject(hBitmap);
return TRUE;
}
void BitTrans(
int nXDest, // 目标起点X
int nYDest, // 目标起点Y
int nWidthDest, // 目标宽度
int nHeightDest,// 目标高度
CDC* pDC, // 目标DC
int nXSrc, // 来源起点X
int nYSrc, // 来源起点Y
COLORREF crTrans// 透明色
)
{
CMemDC dcImage(nWidthDest, nHeightDest,pDC);//临时DC
CBitmap bmpMask;
bmpMask.CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);
// 创建单色掩码位图
CDC dcMask;//掩码DC
dcMask.CreateCompatibleDC(pDC);
dcMask.SelectObject(bmpMask);
//将载入位图的内存DC中的位图,拷贝到临时DC中
dcImage.BitBlt( 0, 0, nWidthDest, nHeightDest, this, nXSrc, nYSrc, SRCCOPY);
// 设置临时DC的透明色
dcImage.SetBkColor(crTrans);
//掩码DC的透明区域为白色其它区域为黑色
dcMask.BitBlt(0, 0, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCCOPY);
//临时DC透明区域为黑色,其它区域保持不变
dcImage.SetBkColor(RGB(0,0,0));
dcImage.SetTextColor(RGB(255,255,255));
dcImage.BitBlt( 0, 0, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);
// 目标DC透明部分保持屏幕不变,其它部分变成黑色
pDC ->SetBkColor(RGB(255,255,255));
pDC ->SetTextColor(RGB(0,0,0));
pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);
pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCPAINT);
}
void StretchTrans(
int nXDest, // 目标起点X
int nYDest, // 目标起点Y
int nWidthDest, // 目标宽度
int nHeightDest, // 目标高度
CDC* pDC, // 目标DC
int nXSrc, // 来源起点X
int nYSrc, // 来源起点Y
int nWidthSrc, // 来源宽度
int nHeightSrc, // 来源高度
COLORREF crTrans // 透明色
)
{
CMemDC dcImage(nWidthDest, nHeightDest,pDC);//临时DC
CBitmap bmpMask;
// 创建单色掩码位图
bmpMask.CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);
CDC dcMask;
dcMask.CreateCompatibleDC(pDC);
dcMask.SelectObject(bmpMask);
// 将载入位图的内存DC中的位图,拷贝到临时DC中
if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
dcImage.BitBlt(0, 0, nWidthDest, nHeightDest, this, nXSrc, nYSrc, SRCCOPY);
else
dcImage.StretchBlt(0, 0, nWidthDest, nHeightDest,
this, nXSrc, nYSrc, nWidthSrc, nHeightSrc, SRCCOPY);
// 设置临时DC的透明色
dcImage.SetBkColor( crTrans);
//掩码DC的透明区域为白色其它区域为黑色
dcMask.BitBlt(0,0,nWidthDest, nHeightDest,&dcImage,0,0,SRCCOPY);
//临时DC透明区域为黑色,其它区域保持不变
dcImage.SetBkColor(RGB(0,0,0));
dcImage.SetTextColor(RGB(255,255,255));
dcImage.BitBlt(0, 0, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);
// 目标DC透明部分保持屏幕不变,其它部分变成黑色
pDC ->SetBkColor(RGB(255,255,255));
pDC ->SetTextColor(RGB(0,0,0));
pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);
pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCPAINT);
}
};
#endif
// FlyDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Fly.h"
#include "FlyDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CFlyDlg dialog
CFlyDlg::CFlyDlg(CWnd* pParent /*=NULL*/)
: CDialog(CFlyDlg::IDD, pParent)
{
m_nIndex=0;
m_pos.x = m_pos.y=0;
//{{AFX_DATA_INIT(CFlyDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CFlyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFlyDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CFlyDlg, CDialog)
//{{AFX_MSG_MAP(CFlyDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_WM_ERASEBKGND()
ON_WM_NCPAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFlyDlg message handlers
BOOL CFlyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_dcBack.LoadBitmap("./Flys/Back.bmp");
int i = 0;
CString str;
while(i<COUNT)
{
str.Format("./Flys/%03d.bmp",i+1);
m_dc[i].LoadBitmap(str);
++i;
}
SetTimer(0,64,NULL);
int cx = GetSystemMetrics(SM_CXSCREEN);
int cy = GetSystemMetrics(SM_CYSCREEN);
MoveWindow(0,0,cx,cy,FALSE);
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CFlyDlg::OnPaint()
{
CPaintDC dc(this);
OnDraw(&dc);
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.http://www.fodizi.com/fofa/list/248.htm
HCURSOR CFlyDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//为什么画面上方会产生秘密文字???
void CFlyDlg::OnTimer(UINT nIDEvent)
{
CClientDC dc(this);
Invalidate(FALSE);
CDialog::OnTimer(nIDEvent);
}
void CFlyDlg::OnDraw(CDC *pDC)
{
CRect rect;
GetClientRect(rect);
CMemDC mdc(rect.Width(),rect.Height(),pDC);
mdc.FillSolidRect(0,0,rect.right,rect.Height(),RGB(255,0,0));
m_dcBack.StretchTrans(0,0,rect.right,rect.bottom,&mdc,0,0,m_dcBack.GetWidth(),
m_dcBack.GetHeight(),RGB(0,0,0));
//m_dcBack.BitTrans(0,0,rect.right,rect.bottom,&mdc,0,0,RGB(0,0,0));
// dc.BitBlt(0,0,m_dcBack.GetWidth(),m_dcBack.GetHeight(),&m_dcBack,0,0,SRCCOPY);
static int cx = m_dc[m_nIndex].GetWidth();//static变量第一次进入函数式初始化
static int cy = m_dc[m_nIndex].GetHeight();//离开函数数值不丢失
static dx=5,dy=5;//运动方向
m_dc[m_nIndex].BitTrans(m_pos.x,m_pos.y,cx,cy,&mdc,0,0,RGB(1,1,1));
pDC ->BitBlt(0,0,mdc.GetWidth(),mdc.GetHeight(),&mdc,0,0,SRCCOPY);
m_pos.Offset(dx,dy);
if(m_pos.x + cx> rect.right || m_pos.x <0)
dx*=-1;
if(m_pos.y + cy> rect.bottom || m_pos.y < 0)
dy *=-1;
if(++m_nIndex>COUNT)
m_nIndex=0;
}
BOOL CFlyDlg::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CFlyDlg::OnNcPaint()
{
}