⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winproc.cpp

📁 实现了windows Xp 中自带的扫雷的基本全部功能
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		if (btLandmineMapinfo[x][y]!=0x10) {
			btLandmineMapinfo[x][y]=(BYTE)0x10;
			icBomb++;
		}
	}
	icBomb=0;	
	while (icBomb<iMineBomb) {//设置左下
		x=rand()%ixMine;
		y=rand()%(mineLineNum-iyMine)+iyMine;
		if (btLandmineMapinfo[x][y]!=0x10) {
			btLandmineMapinfo[x][y]=(BYTE)0x10;
			icBomb++;
		}
	}
	icBomb=0;	
	while (icBomb<(mineBomb-3*iMineBomb)) {//设置右下
		x=rand()%(mineRowNum-ixMine)+ixMine;
		y=rand()%(mineLineNum-iyMine)+iyMine;
		if (btLandmineMapinfo[x][y]!=0x10) {
			btLandmineMapinfo[x][y]=(BYTE)0x10;
			icBomb++;
		}	
	}
	rcMine=CreateRect(MAIN_LEFTSTND,MAIN_TOPSTND,mineRowNum*MINE_BITMAP_WIDTH,mineLineNum*MINE_BITMAP_HEIGHT,FALSE);
	InvalidateRect(hWnd,&rcMine,FALSE);
	return TRUE;
}


/*###########################################################
功能:得到鼠标的位置和状态
参数:窗口句柄、实例句柄、x坐标、y坐标、当前类型
返回值:当前鼠标的信息结构体
###########################################################*/
tagMouseState getMousePosition(HWND hWnd,HINSTANCE hInstance,int cxMousePos,int cyMousePos){
	tagMouseState state;
	//雷区,得到雷区的位置
	if (cxMousePos>MAIN_LEFTSTND&&cxMousePos<(MAIN_LEFTSTND+mineRowNum*MINE_BITMAP_WIDTH)&&cyMousePos>MAIN_TOPSTND&&cyMousePos<(MAIN_TOPSTND+mineLineNum*MINE_BITMAP_HEIGHT)){	
		state.mXpos=(int)floor((cxMousePos-MAIN_LEFTSTND)/MINE_BITMAP_WIDTH);
		state.mYpos=(int)floor((cyMousePos-MAIN_TOPSTND)/MINE_BITMAP_HEIGHT);
		state.mNowPostion=MOUSE_ON_MINE;
	} else if (cxMousePos>=(MAIN_LEFTSTND+(mineRowNum*MINE_BITMAP_WIDTH-FACE_BITMAP_WIDTH)/2)&&cxMousePos<=(MAIN_LEFTSTND+(mineRowNum*MINE_BITMAP_WIDTH-FACE_BITMAP_WIDTH)/2+FACE_BITMAP_WIDTH)&&cyMousePos>=((MAIN_TOPSTND-FACE_BITMAP_HEIGHT)/2)&&cyMousePos<=((MAIN_TOPSTND-FACE_BITMAP_HEIGHT)/2+FACE_BITMAP_HEIGHT)) {
		state.mNowPostion=MOUSE_ON_FACE;//表情区
	}else{//其他区域
		state.mXpos=cxMousePos>MAIN_LEFTSTND?(int)floor((cxMousePos-MAIN_LEFTSTND)/MINE_BITMAP_WIDTH):-2;
		state.mXpos=cxMousePos<(MAIN_LEFTSTND+mineRowNum*MINE_BITMAP_WIDTH)?state.mXpos:mineRowNum+1;
		state.mYpos=cyMousePos>MAIN_TOPSTND?(int)floor((cyMousePos-MAIN_TOPSTND)/MINE_BITMAP_HEIGHT):-2;
		state.mYpos=cyMousePos<(MAIN_TOPSTND+mineLineNum*MINE_BITMAP_HEIGHT)?state.mYpos:mineLineNum+1;
		state.mNowPostion=MOUSE_ON_OTHER;
	}
	return state;
}

/*###########################################################
功能:左键弹起后改变地图上方格的信息
参数:窗口句柄、实例句柄、鼠标信息
返回值:
###########################################################*/
BOOL OnChangeMineInfo(HWND hWnd,HINSTANCE hInstance,tagMouseState mouse){
	tagMouseState lastMouse;	//上次的鼠标信息
	RECT rcRefresh=CreateRect(mouse.mXpos,mouse.mYpos,1,1,TRUE);	//刷新区域
	if (mouse.mXpos<0||mouse.mYpos<0||mouse.mXpos>=mineRowNum||mouse.mYpos>=mineLineNum) //不在雷区,返回
		return FALSE;
	if (btLandmineMapinfo[mouse.mXpos][mouse.mYpos]>=0x20)		//大于0x20,还原
		OnChangeMineUpon(hWnd,mouse.mXpos,mouse.mYpos,0);	
	if (btLandmineMapinfo[mouse.mXpos][mouse.mYpos]%0x10==0x01||btLandmineMapinfo[mouse.mXpos][mouse.mYpos]%0x10>0x02)
		return FALSE;//棋子或者数字,已翻开的雷等,不处理
	if (btLandmineMapinfo[mouse.mXpos][mouse.mYpos]==0x10||btLandmineMapinfo[mouse.mXpos][mouse.mYpos]==0x12) 	{	
		btLandmineMapinfo[mouse.mXpos][mouse.mYpos]=(BYTE)0x13;	//		设置为爆炸的雷
		setGameLost(hWnd,hInstance);								//		游戏失败
	}	
	else if (btLandmineMapinfo[mouse.mXpos][mouse.mYpos]==0x00||btLandmineMapinfo[mouse.mXpos][mouse.mYpos]==0x02){//不是雷
		btLandmineMapinfo[mouse.mXpos][mouse.mYpos]=0x0f-getRoundMineNum(hWnd,mouse.mXpos,mouse.mYpos);//得到周围的雷数
		openCount--;//空格数减少
		if (btLandmineMapinfo[mouse.mXpos][mouse.mYpos]==0x0f){ //如果是0
			lastMouse=mouse;
			for (int i=0;i<3;i++)
				for (int j=0;j<3;j++){	
					lastMouse.mXpos=mouse.mXpos-1+i;
					lastMouse.mYpos=mouse.mYpos-1+j;
					OnChangeMineInfo(hWnd,hInstance,lastMouse); //递归展开周围,直到数字边界
				}
		}
	}	
	InvalidateRect(hWnd,&rcRefresh,FALSE);	
	return TRUE;
}

/*###########################################################
功能:游戏失败
参数:窗口句柄、实例句柄
返回值:
###########################################################*/

BOOL setGameLost(HWND hWnd,HINSTANCE hInstance){
	RECT rcRefrush=CreateRect(MAIN_LEFTSTND,MAIN_TOPSTND,mineRowNum*MINE_BITMAP_WIDTH,mineLineNum*MINE_BITMAP_HEIGHT,FALSE);
	KillTimer(hWnd,FLAG_TIMECOUNT);	//结束计时器
	if ((flagState&0x0010)!=0x0000){	// 播放声音	
		HRSRC hrWare=FindResource(hInstance,MAKEINTRESOURCE(IDW_WAVE_BOMB),TEXT("WAVE"));
		HGLOBAL hGlobal=LoadResource(hInstance,hrWare);
		PlaySoundW((LPCWSTR)LockResource(hGlobal),NULL,SND_MEMORY|SND_ASYNC);
	}
	for(int i=0;i<mineRowNum;i++){	//展开所有雷
		for(int j=0;j<mineLineNum;j++){
			if (btLandmineMapinfo[i][j]==0x10) btLandmineMapinfo[i][j]=0x15;	//未爆的雷
			if (btLandmineMapinfo[i][j]==0x01) btLandmineMapinfo[i][j]=0x04;	//标错的棋子
		}
	}
	flagState=flagState&0xfffe;
	InvalidateRect(hWnd,&rcRefrush,FALSE);	
	RefreshSmileFaceBmp(hWnd,FACE_TYPE_GRIEF);
	return TRUE;
}

/*###########################################################
功能:获得当前等级窗口的位置和大小信息
参数:窗口句柄
返回值:区域 左上的坐标(left,top)大小(right,bottom)
###########################################################*/
RECT getLevelWindowSize(HWND hWnd){
	RECT rcFrame,rcWindow,rcClient;
	GetWindowRect(hWnd,&rcWindow);
	GetClientRect(hWnd,&rcClient);
	rcFrame.left=rcWindow.left;		//窗口左边位置
	rcFrame.top=rcWindow.top;		//窗口上边位置		
	rcFrame.right=rcClient.left-rcWindow.left+rcWindow.right-rcClient.right+mineRowNum*MINE_BITMAP_WIDTH+MAIN_LEFTSTND+MAIN_RIGHTSTND;//窗口的宽度		
	rcFrame.bottom=rcClient.top-rcWindow.top+rcWindow.bottom-rcClient.bottom+mineLineNum*MINE_BITMAP_HEIGHT+MAIN_TOPSTND+MAIN_BOTTOMSTND;//窗口的高度
	return rcFrame;
}
/*###########################################################
功能:描绘3D边框
参数:HDC,区域、线宽
返回值:
###########################################################*/
BOOL DrawSolidFrame(HDC hDC,RECT rcFrame,int iLighten){
	HPEN hPen;
	for(int iCount=0;iCount<iLighten;iCount++){	
		hPen=CreatePen(PS_SOLID,0,RGB(250,250,250));
		SelectObject(hDC,hPen);
		MoveToEx(hDC,rcFrame.right-iCount-1,rcFrame.top+iCount,NULL);	//右上
		LineTo(hDC,rcFrame.right-iCount-1,rcFrame.bottom-iCount-1);		//右下
		LineTo(hDC,rcFrame.left+iCount,rcFrame.bottom-iCount-1);		//左下
		DeleteObject(hPen);
		hPen=CreatePen(PS_SOLID,0,RGB(8+(flagState&0x0004)*30,8+(flagState&0x0004)*30,8+(flagState&0x0004)*30));
		SelectObject(hDC,hPen);
		LineTo(hDC,rcFrame.left+iCount,rcFrame.top+iCount);				//左上
		LineTo(hDC,rcFrame.right-iCount,rcFrame.top+iCount);			//右上
		DeleteObject(hPen);
	}
	return TRUE;
}

/*###########################################################
功能:	生成一个矩形区域,如果后两个参数为0,得到的是一个雷的大小的区域,否则是两点参数的区域
参数:		
返回值:
###########################################################*/
RECT CreateRect(int left,int top,int width,int height,bool bMine){
	RECT rcReturn;
	rcReturn.left=bMine?MAIN_LEFTSTND+(left-width/2)*MINE_BITMAP_WIDTH:left;
	rcReturn.top=bMine?MAIN_TOPSTND+(top-height/2)*MINE_BITMAP_HEIGHT:top;
	rcReturn.right=bMine?rcReturn.left+width*MINE_BITMAP_WIDTH:left+width;
	rcReturn.bottom=bMine?rcReturn.top+MINE_BITMAP_HEIGHT+height*MINE_BITMAP_HEIGHT:top+height;
	return rcReturn;
}

/*###########################################################
功能:获得周围雷的数目
参数:窗口句柄、所在位置
返回值:周围雷的数目
###########################################################*/
BYTE getRoundMineNum(HWND hWnd,int iCol,int iLn){
	BYTE btNum=0;
	for(int i=iCol-1;i<=iCol+1;i++)
		for(int j=iLn-1;j<=iLn+1;j++)	//大于0x10为雷
			if (btLandmineMapinfo[i][j]>=0x10&&i>=0&&j>=0&&i<mineRowNum&&j<mineLineNum) btNum++;
	return btNum;	
}

/*###########################################################
功能:获得周围旗子的数目
参数:窗口句柄、所在位置
返回值:周围旗子的数目
###########################################################*/
BYTE getRoundFlagNum(HWND hWnd,int iCol,int iLn){
	BYTE btNum=0;
	for(int i=iCol-1;i<=iCol+1;i++)
		for(int j=iLn-1;j<=iLn+1;j++)
			if (btLandmineMapinfo[i][j]%0x10==0x01&&i>=0&&j>=0&&i<mineRowNum&&j<mineLineNum) 
				btNum++;		
	return btNum;	
}

/*###########################################################
功能:刷新表情图片区域
参数:窗口句柄、表情类型
返回值:
###########################################################*/

BOOL RefreshSmileFaceBmp(HWND hWnd,int iFaceType){
	RECT rcRefresh=CreateRect(MAIN_LEFTSTND+(mineRowNum*MINE_BITMAP_WIDTH-FACE_BITMAP_WIDTH)/2,(MAIN_TOPSTND-FACE_BITMAP_HEIGHT)/2,FACE_BITMAP_WIDTH,FACE_BITMAP_HEIGHT,FALSE);
	if ((flagState&0xf000)==iFaceType*0x1000) return FALSE;
	flagState = (flagState&0x0fff)+iFaceType*0x1000;
	InvalidateRect(hWnd,&rcRefresh,FALSE);
	return TRUE;
}

/*###########################################################
功能:鼠标消息处理
参数:窗口句柄、实例句柄、当前鼠标结构体、自定义消息类型
返回值:
###########################################################*/

BOOL OnMouseClick(HWND hWnd,HINSTANCE hInstance,tagMouseState nowMouse,int startMouse){
	static int				lastFace=0,lastXpos,lastYpos;
	static tagMouseState    lastMouse;
	tagMouseState			tempMouse;				//临时鼠标结构体
	TCHAR					lpMessage[255];			//消息字符串
	int						i;					//临时变量
	BYTE					temp;					//临时变量
	RECT					rcRefresh,rcWnd;				//刷新区域
	switch(nowMouse.mNowPostion){
	case MOUSE_ON_MINE:
		if (!(flagState&0x0001)||startMouse==MOUSE_ON_FACE) return 0;
		switch(nowMouse.mButtonMode)
		{
		case BTN_LBUTTONDOWN:
			OnChangeMineDown(hWnd,nowMouse.mXpos,nowMouse.mYpos,0);
			lastXpos=nowMouse.mXpos;
			lastYpos=nowMouse.mYpos;
			RefreshSmileFaceBmp(hWnd,FACE_TYPE_EXCLAIM);
			break;
		case BTN_LBUTTONUP:
			if (!(flagState & 0x0002)){		//未开始计时
				timeCount=1;
				GetClientRect(hWnd,&rcWnd);
				rcRefresh=CreateRect(rcWnd.right-TIME_RIGHTSTND-TIME_WIDTH,TIME_TOPPOS,TIME_WIDTH,TIME_HEIGHT,FALSE);
				InvalidateRect(hWnd,&rcRefresh,FALSE);
				if (SetTimer(hWnd,FLAG_TIMECOUNT,1000,NULL)==0){ //计时器启动失败	
					LoadString(hInstance,IDS_TIMER_ERROR,lpMessage,sizeof(lpMessage));
					if (MessageBox(hWnd,lpMessage,"严重错误!",MB_ICONSTOP)==IDOK) SendMessage(hWnd,WM_DESTROY,NULL,NULL); //退出程序
				}

				OnChangeMineUpon(hWnd,nowMouse.mXpos,nowMouse.mYpos,0);
				if (btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]==0x10||btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]==0x12){
					i=0;	//第一次是雷
					do{	
						if (nowMouse.mYpos+i>=mineRowNum||nowMouse.mXpos+i>=mineLineNum) //交换不能解决,重新生成地图
							CreateRandomMap(hWnd);i=0;//交换位置

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -