www.gusucode.com > VC++开发的电路板画图设计软件源代码源码程序 > VC++开发的电路板画图设计软件源代码源码程序\code\mysplash.cpp

    //Download by http://www.NewXing.com
// mysplash.cpp : implementation file
//
#include "stdafx.h"
#include "pointtest.h"
#include "mysplash.h"
#include "ddraw.h"
#include <math.h>
#include "ddutil.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// mysplash
	LPDIRECTDRAW            lpDD;           // DirectDraw对象
	LPDIRECTDRAWSURFACE     lpDDSPrimary;   // 主页面
	LPDIRECTDRAWSURFACE     lpDDSPic1;      // 离屏页面1
	LPDIRECTDRAWSURFACE     lpDDSPic2;      // 离屏页面1
	LPDIRECTDRAWCLIPPER		lpClipper;		//DirectDrawClipper对象

	HINSTANCE	hInst;				//应用程序实例句柄

	int BACKWIDTH=320;		//背景图宽度
	int BACKHEIGHT=240;		//背景图高度

	short * buf1;			//波能数据缓冲区
	short * buf2;			//波能数据缓冲区

	//效果
	BOOL rain=false;		//下雨
	BOOL upripper=true;		//上波源
	BOOL downripper=true;	//下波源

	//函数声明
	BOOL InitSurfaces( void );
	void UpdateFrame(HWND PP);
	void MakeRect(RECT *rect, short left, short top, short right, short bottom);
	void DropStone(int x, int y, int stonesize, int stoneweight);
	HWND ChooseWnd();
	void AdjustWindowSize(HWND hwnd);
	BOOL InitPreviewWindow( HINSTANCE hInstance, int nCmdShow );
	void Say ( LPCSTR word );
	BOOL InitDDraw(HWND PP);
	void FreeObjects( void );
mysplash::mysplash()
{
	Lbutton = FALSE;
	hBitmap.LoadBitmap(IDB_SPLASH);
}

mysplash::~mysplash()
{
	FreeObjects();
}


BEGIN_MESSAGE_MAP(mysplash, CWnd)
	//{{AFX_MSG_MAP(mysplash)
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_TIMER()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// mysplash message handlers

int mysplash::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	CenterWindow(); 
	SetTimer(123,20000,FALSE);
	SetTimer(124,30,FALSE);
	if ( !InitDDraw(m_hWnd))
	{
		MessageBox("error""初始化DirectDraw过程中出错!", "Error", MB_OK );
		FreeObjects();
		return -1;
	}
	return 0;
}

void mysplash::OnPaint() 
{
//	
	CBitmap *hBitmapOld;
	CPaintDC dc(this); // device context for painting
	CDC* pDC = NULL;
	pDC = GetDC();
	CDC* hMemDC = new CDC;
	hMemDC->CreateCompatibleDC(pDC);//建 立 内 存
	hBitmapOld = hMemDC->SelectObject(&hBitmap);//选 择 对 象
	pDC->BitBlt(0,0,320,240,hMemDC,0,0,SRCCOPY); 
	//显 示 真 彩 位 图
	hMemDC->SelectObject(hBitmapOld);//删 除 位 图
	delete hMemDC;
	ReleaseDC(pDC);

}
BOOL mysplash::Create(CWnd*  pParentWnd)
{// 建 立 显 示 位 图 的 弹 出 窗 口
	return CreateEx(0,AfxRegisterWndClass(0,AfxGetApp()->LoadStandardCursor(IDC_ARROW)),NULL,WS_POPUP|WS_VISIBLE,0,0,320,240,pParentWnd->GetSafeHwnd(),NULL);
}

void mysplash::OnLButtonDown(UINT nFlags, CPoint point)
{
	DestroyWindow();
/*	Lbutton = TRUE;
	int x,y;
	RECT rect;
	GetClientRect(&rect);
	x=point.x*BACKWIDTH/(rect.right-rect.left);
	y=point.y*BACKHEIGHT/(rect.bottom-rect.top);
	DropStone(x, y, 3, 16);*/
	CWnd::OnLButtonDown(nFlags, point);
}

void mysplash::OnTimer(UINT nIDEvent) 
{
	if(nIDEvent == 124)
		UpdateFrame(m_hWnd);
	if(nIDEvent == 123)
		DestroyWindow();
	CWnd::OnTimer(nIDEvent);
}
//*******************************************************************
//函数:FreeObject
//功能:释放我们用过的所有DirectDraw对象
//*******************************************************************
void FreeObjects( void )
{
    if( lpDD != NULL )//释放DirectDraw对象
    {
        if( lpDDSPrimary != NULL )//释放主页面。
        {
            lpDDSPrimary->Release();
            lpDDSPrimary = NULL;
        }
        if( lpDDSPic1 != NULL )//释放离屏页面。
        {
            lpDDSPic1->Release();
            lpDDSPic1 = NULL;
        }
        if( lpDDSPic2 != NULL )
        {
            lpDDSPic2->Release();
            lpDDSPic2 = NULL;
        }
		if (lpClipper!=NULL)
		{
			lpClipper->Release();
			lpClipper=NULL;
		}
        lpDD->Release();
        lpDD = NULL;
    }
	delete buf1;
	delete buf2;
} 

//*******************************************************************
//函数:RestoreAll
//功能:页面丢失后,恢复页面内存
//*******************************************************************
HRESULT RestoreAll( void )
{
    HRESULT     ddrval;

	//恢复主页面,这也将恢复换页链中的所有页面
    ddrval = lpDDSPrimary->Restore();
    ddrval = lpDDSPic1->Restore();
    ddrval = lpDDSPic2->Restore();

	InitSurfaces();//重新绘制页面图象
    return ddrval;
}

//******************************************************************
//函数:InitDDraw()
//功能:初始化DirectDraw环境,
//******************************************************************
BOOL InitDDraw(HWND PP)
{
    DDSURFACEDESC       ddsd;
    HRESULT             ddrval;

    //创建DirectDraw对象
	ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
    if( ddrval != DD_OK )
        return FALSE;

    ddrval = lpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL);
    if( ddrval != DD_OK )
        return FALSE;

    ddsd.dwSize = sizeof( ddsd );
    ddsd.dwFlags = DDSD_CAPS ;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

    ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
    if( ddrval != DD_OK )
        return FALSE;

	ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |DDSCAPS_SYSTEMMEMORY ;
	ddsd.dwWidth = BACKWIDTH;
    ddsd.dwHeight = BACKHEIGHT;

    if (lpDD->CreateSurface(&ddsd, &lpDDSPic1, NULL) != DD_OK)
		return FALSE;
    if (lpDD->CreateSurface(&ddsd, &lpDDSPic2, NULL) != DD_OK)
		return FALSE;

	lpDD->CreateClipper(0, &lpClipper, NULL);
	lpClipper->SetHWnd(0, PP);
	lpDDSPrimary->SetClipper(lpClipper);

	if( !InitSurfaces() )
        return FALSE;

    return TRUE;
}

//******************************************************************
//函数:InitSurfaces()
//功能:初始化页面图象
//******************************************************************
BOOL InitSurfaces( void )
{
    DDReLoadBitmap(lpDDSPic1, MAKEINTRESOURCE(IDB_SPLASH));

    buf1 = new short[BACKWIDTH*BACKHEIGHT];
	buf2 = new short[BACKWIDTH*BACKHEIGHT];
	ZeroMemory(buf1, BACKWIDTH*BACKHEIGHT*sizeof(short));
	ZeroMemory(buf2, BACKWIDTH*BACKHEIGHT*sizeof(short));

	for (int i=0; i<10; i++)
		DropStone(BACKWIDTH*i/10, BACKHEIGHT/2, 3, 16);

    return TRUE;
}

//*******************************************************
//计算波能数据缓冲区
//*******************************************************
void RippleSpread()
{
	for (int i=BACKWIDTH; i<BACKWIDTH*BACKHEIGHT-BACKWIDTH; i++)
	{
		//波能扩散
		buf2[i] = ((buf1[i-1]+
					buf1[i+1]+
					buf1[i-BACKWIDTH]+
					buf1[i+BACKWIDTH])
					>>1)
					- buf2[i];
		//波能衰减
		buf2[i] -= buf2[i]>>5;
	}

	//交换波能数据缓冲区
	short *ptmp =buf1;
	buf1 = buf2;
	buf2 = ptmp;
}

//*******************************************************
//根据波能数据缓冲区对离屏页面进行渲染
//*******************************************************
void RenderRipple()
{
	//锁定两个离屏页面
	DDSURFACEDESC ddsd1, ddsd2;
	ddsd1.dwSize = sizeof (DDSURFACEDESC);
	ddsd2.dwSize = sizeof(DDSURFACEDESC);
	lpDDSPic1->Lock(NULL, &ddsd1, DDLOCK_WAIT, NULL);
	lpDDSPic2->Lock(NULL, &ddsd2, DDLOCK_WAIT, NULL);

	//取得页面象素位深度,和页面内存指针
	int depth=ddsd1.ddpfPixelFormat.dwRGBBitCount/8;
	BYTE *Bitmap1 = (BYTE*)ddsd1.lpSurface;
	BYTE *Bitmap2 = (BYTE*)ddsd2.lpSurface;
	
	//下面进行页面渲染
	int xoff, yoff;
	int k = BACKWIDTH;
	for (int i=1; i<BACKHEIGHT-1; i++)
	{
		for (int j=0; j<BACKWIDTH; j++)
		{
			//计算偏移量
			xoff = buf1[k-1]-buf1[k+1];
			yoff = buf1[k-BACKWIDTH]-buf1[k+BACKWIDTH];

			//判断坐标是否在窗口范围内
			if ((i+yoff )< 0 ) {k++; continue;}
			if ((i+yoff )> BACKHEIGHT) {k++; continue;}
			if ((j+xoff )< 0 ) {k++; continue;}
			if ((j+xoff )> BACKWIDTH ) {k++; continue;}

			//计算出偏移象素和原始象素的内存地址偏移量
			int pos1, pos2;
			pos1=ddsd1.lPitch*(i+yoff)+ depth*(j+xoff);
			pos2=ddsd2.lPitch*i+ depth*j;

			//复制象素
			for (int d=0; d<depth; d++)
				Bitmap2[pos2++]=Bitmap1[pos1++];
			k++;
		}
	}
	//解锁页面
	lpDDSPic1->Unlock(&ddsd1);
	lpDDSPic2->Unlock(&ddsd2);
}

//********************************************************
//更新屏幕
//********************************************************
void UpdateFrame(HWND PP)
{
	//随机增加波源
	if (rain==TRUE)
	DropStone(
			(int)(BACKWIDTH*((short)rand()/32767.0)),
			(int)(BACKHEIGHT*((short)rand()/32767.0)),
			3,
			16
			);
	if (downripper==TRUE)
	DropStone(
			(int)(BACKWIDTH*((short)rand()/32767.0)),
			BACKHEIGHT-3,
			3,
			16
			);
	if (upripper==TRUE)
	DropStone(
			(int)(BACKWIDTH*((short)rand()/32767.0)),
			3,
			3,
			16
			);

	RippleSpread();//计算波能数据缓冲区
	RenderRipple();//页面渲染

	//将离屏页面图象Blit到主页面
	RECT Window;
	POINT pt;
	GetClientRect(PP, &Window);
	pt.x=pt.y=0;
	ClientToScreen(PP, &pt);
	OffsetRect(&Window, pt.x, pt.y);
	lpDDSPrimary->Blt(&Window, lpDDSPic2, NULL, DDBLT_WAIT, NULL);
	//lpDDSPrimary->BltFast(pt.x,pt.y, lpDDSPic2, &Window,DDBLTFAST_WAIT );
}

void MakeRect(RECT *rect, short left, short top, short width, short height)
{
	rect->left=left;
	rect->top=top;
	rect->right=left+width;
	rect->bottom=top+height;
}

//*****************************************************
//增加波源
//*****************************************************
void DropStone(int x,//x坐标
			   int y,//y坐标
			   int stonesize,//波源半径
			   int stoneweight)//波源能量
{
	//判断坐标是否在屏幕范围内
	if ((x+stonesize)>BACKWIDTH || 
		(y+stonesize)>BACKHEIGHT||
		(x-stonesize)<0||
		(y-stonesize)<0)
		return;

	for (int posx=x-stonesize; posx<x+stonesize; posx++)
		for (int posy=y-stonesize; posy<y+stonesize; posy++)
			if ((posx-x)*(posx-x) + (posy-y)*(posy-y) < stonesize*stonesize)
				buf1[BACKWIDTH*posy+posx] = -stoneweight;
}

BOOL mysplash::PreTranslateMessage(MSG* pMsg) 
{
/*	switch(pMsg->message){
	case WM_ACTIVATEAPP:
		UpdateFrame(m_hWnd);
		break;
	}*/
	return CWnd::PreTranslateMessage(pMsg);
}

void mysplash::OnMouseMove(UINT nFlags, CPoint point) 
{
//	if(Lbutton){
		int x,y;
		RECT rect;
		GetClientRect(&rect);
		x=point.x*BACKWIDTH/(rect.right-rect.left);
		y=point.y*BACKHEIGHT/(rect.bottom-rect.top);
		DropStone(x, y, 3, 16);
//	}*/
	CWnd::OnMouseMove(nFlags, point);
}

void mysplash::OnLButtonUp(UINT nFlags, CPoint point) 
{
//	if(!Lbutton) return;
//	Lbutton = FALSE;
	CWnd::OnLButtonUp(nFlags, point);
}