📄 mysplash.cpp
字号:
// 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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -