📄 winproc.cpp
字号:
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 + -