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); }