www.pudn.com > WinMine.zip > WinProc.cpp
/*//////////////////////文件说明//////////////////////////
// //
//文件名: WinProc.cpp //
//功 能: 功能函数的定义和实现 //
//作 者: //
// //
////////////////////////////////////////////////////////*/
#include "WinProc.h"
/*###########################################################
功能:主窗口的消息处理回调函数
参数:
返回值:
###########################################################*/
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hDC,hDCMem;
static HICON hIcon; //程序图标句柄
static HINSTANCE hInstance; //程序实例句柄
static HMENU hMenu; //程序主菜单句柄
PAINTSTRUCT ps;
HBRUSH hBrush;
HPEN hPen;
HBITMAP hBmp;
int ix=0,iy=0;
RECT rcWnd,rcRefresh; //窗口区域和刷新区域
static tagMouseState NowMousePos; //鼠标状态结构体
static int mStartMousePos;
HRSRC hrWare; //wave资源句柄
HGLOBAL hGlobal;
LPCTSTR keyWinMine=TEXT("Software\\Microsoft\\winmine\\"); //注册表主键
HKEY hKey,hKeySub; //注册表键句柄
DWORD dwTemp; //临时变量
LPCTSTR lpsTime[3]={TEXT("Time1"),TEXT("Time2"),TEXT("Time3")};
LPCTSTR lpsName[3]={TEXT("Name1"),TEXT("Name2"),TEXT("Name3")};
TCHAR lpAnonymity[255]; //临时变量
DWORD dwSize1=sizeof(DWORD),dwType1=REG_DWORD,dwType2=REG_SZ,dwSize2=sizeof(lpAnonymity);
//###########################################################################################################
switch (message)
{
case WM_CREATE:
hDC=GetDC(hWnd);
hInstance=((LPCREATESTRUCT)lParam)->hInstance;
hMenu=((LPCREATESTRUCT)lParam)->hMenu;
//注册表读取已保存的信息,如果相关键值不存在则创建
if (RegOpenKeyEx(HKEY_CURRENT_USER,keyWinMine,0,KEY_ALL_ACCESS,&hKey)!=ERROR_SUCCESS){
RegCreateKey(HKEY_CURRENT_USER,keyWinMine,&hKey);
}
if (RegQueryValueEx(hKey,TEXT("Height"),NULL,&dwType1,(LPBYTE)&mineLineNum,&dwSize1)!=ERROR_SUCCESS){
mineLineNum=BEGINER_LN_NUM;
RegSetValueEx(hKey,TEXT("Height"),NULL,REG_DWORD,(LPBYTE)&mineLineNum,dwSize1);
}
if (RegQueryValueEx(hKey,TEXT("Width"),NULL,&dwType1,(LPBYTE)&mineRowNum,&dwSize1)!=ERROR_SUCCESS){
mineRowNum=BEGINER_COL_NUM;
RegSetValueEx(hKey,TEXT("Width"),NULL,REG_DWORD,(LPBYTE)&mineRowNum,dwSize1);
}
if (RegQueryValueEx(hKey,TEXT("Mines"),NULL,&dwType1,(LPBYTE)&mineBomb,&dwSize1)!=ERROR_SUCCESS){
mineBomb=BEGINER_BOMB_NUM;
RegSetValueEx(hKey,TEXT("Mines"),NULL,REG_DWORD,(LPBYTE)&mineBomb,dwSize1);
}
if (RegQueryValueEx(hKey,TEXT("Sound"),NULL,&dwType1,(LPBYTE)&dwTemp,&dwSize1)!=ERROR_SUCCESS){
dwTemp=0;
RegSetValueEx(hKey,TEXT("Sound"),NULL,REG_DWORD,(LPBYTE)&dwTemp,dwSize1);
}
flagState=(flagState&0xffef)+dwTemp*FLAG_SOUND;
if (RegQueryValueEx(hKey,TEXT("Difficulty"),NULL,&dwType1,(LPBYTE)&dwTemp,&dwSize1)!=ERROR_SUCCESS){
dwTemp=0;
RegSetValueEx(hKey,TEXT("Difficulty"),NULL,REG_DWORD,(LPBYTE)&dwTemp,dwSize1);
}
flagState=(flagState&0xf0ff)+dwTemp*0x0100;
if (RegQueryValueEx(hKey,TEXT("Mark"),NULL,&dwType1,(LPBYTE)&dwTemp,&dwSize1)!=ERROR_SUCCESS){
dwTemp=1;
RegSetValueEx(hKey,TEXT("Mark"),NULL,REG_DWORD,(LPBYTE)&dwTemp,dwSize1);
}
flagState=(flagState&0xfff7)+dwTemp*FLAG_MARK;
if (RegQueryValueEx(hKey,TEXT("Color"),NULL,&dwType1,(LPBYTE)&dwTemp,&dwSize1)!=ERROR_SUCCESS){
dwTemp=1;
RegSetValueEx(hKey,TEXT("Color"),NULL,REG_DWORD,(LPBYTE)&dwTemp,dwSize1);
}
flagState=(flagState&0xfffb)+dwTemp*FLAG_COLOR;
if (RegQueryValueEx(hKey,TEXT("AlreadyPlayed"),NULL,&dwType1,(LPBYTE)&dwTemp,&dwSize1)!=ERROR_SUCCESS){
dwTemp=1;
RegSetValueEx(hKey,TEXT("AlreadyPlayed"),NULL,REG_DWORD,(LPBYTE)&dwTemp,dwSize1);
}
flagState=(flagState&0xfffe)+1*FLAG_ALREADPLAYED; dwTemp=999;
LoadString(hInstance,IDS_NORMAL_NAME,lpAnonymity,sizeof(lpAnonymity));
for (ix=0;ix<3;ix++){
if (RegOpenKeyEx(hKey,lpsTime[ix],NULL,KEY_WRITE,&hKeySub)!=ERROR_SUCCESS){
RegSetValueEx(hKey,lpsTime[ix],NULL,REG_DWORD,(LPBYTE)&dwTemp,dwSize1);
RegCloseKey(hKeySub);
}
if (RegOpenKeyEx(hKey,lpsName[ix],NULL,KEY_WRITE,&hKeySub)!=ERROR_SUCCESS){
RegSetValueEx(hKey,lpsName[ix],NULL,REG_SZ,(LPBYTE)&lpAnonymity,dwSize2);
RegCloseKey(hKeySub);
}
}//初始化窗口信息
IinitializeMapInfo(hWnd,(flagState&0x0f00)/0x0100,mineRowNum,mineLineNum,mineBomb);
CheckMenuItem(hMenu,IDM_MARK,((flagState&0x0008)==FLAG_MARK) ? MF_CHECKED:MF_UNCHECKED);
CheckMenuItem(hMenu,IDM_COLOR,((flagState&0x0004)==FLAG_COLOR) ? MF_CHECKED:MF_UNCHECKED);
CheckMenuItem(hMenu,IDM_SOUND,((flagState&0x0010)==FLAG_SOUND) ? MF_CHECKED:MF_UNCHECKED);
OnCheckLevelMenu(hMenu,(flagState&0x0f00)/0x0100);
rcWnd=getLevelWindowSize(hWnd);//计算窗口大小,初始化地图数据
if (RegQueryValueEx(hKey,TEXT("Xpos"),NULL,&dwType1,(LPBYTE)&dwTemp,&dwSize1)==ERROR_SUCCESS) rcWnd.left=dwTemp;
if (RegQueryValueEx(hKey,TEXT("Ypos"),NULL,&dwType1,(LPBYTE)&dwTemp,&dwSize1)==ERROR_SUCCESS) rcWnd.top=dwTemp;
CreateRandomMap(hWnd);
MoveWindow(hWnd,rcWnd.left,rcWnd.top,rcWnd.right,rcWnd.bottom,TRUE);
RegCloseKey(hKey);
ReleaseDC(hWnd,hDC);
hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDC_APPICON)) ;
return 0;
case WM_PAINT:
hDC = BeginPaint (hWnd, &ps);
hDCMem= CreateCompatibleDC(hDC);
GetClientRect(hWnd,&rcWnd);
hPen=(HPEN)GetStockObject(NULL_PEN);
SelectObject(hDC,hPen);
hBrush=CreateSolidBrush(RGB(192,192,192));
SelectObject(hDC,hBrush);
Rectangle(hDC,3,3,rcWnd.right+1,rcWnd.bottom+1);//绘制底层背景
DeleteObject(hBrush);
hBrush=CreateSolidBrush(RGB(8+(flagState&0x0004)*30,8+(flagState&0x0004)*30,8+(flagState&0x0004)*30));
SelectObject(hDC,hBrush);
Rectangle(hDC,MAIN_LEFTSTND+(mineRowNum*MINE_BITMAP_WIDTH-FACE_BITMAP_WIDTH)/2-1,(MAIN_TOPSTND-FACE_BITMAP_HEIGHT)/2-1,MAIN_LEFTSTND+(mineRowNum*MINE_BITMAP_WIDTH-FACE_BITMAP_WIDTH)/2+FACE_BITMAP_WIDTH+2,(MAIN_TOPSTND-FACE_BITMAP_HEIGHT)/2+FACE_BITMAP_HEIGHT+2); //绘制表情背景
DeleteObject(hBrush);
DeleteObject(hPen);
//表情贴图
hBmp=LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_SMILE_BLACK+(flagState&0x0004)/0x0004));
SelectObject(hDCMem,hBmp);
BitBlt(hDC,MAIN_LEFTSTND+(mineRowNum*MINE_BITMAP_WIDTH-FACE_BITMAP_WIDTH)/2,(MAIN_TOPSTND-FACE_BITMAP_HEIGHT)/2,FACE_BITMAP_WIDTH,FACE_BITMAP_HEIGHT,hDCMem,0, ((flagState & 0xf000)/0x1000) *FACE_BITMAP_HEIGHT,SRCCOPY);
DeleteObject(hBmp);
//计雷器贴图
hBmp=LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_NUM_BLACK+(flagState&0x0004)/0x0004));
SelectObject(hDCMem,hBmp);
BitBlt(hDC,COUNT_LEFTPOS,COUNT_TOPPOS,NUM_BITMAP_WIDTH,NUM_BITMAP_HEIGHT,hDCMem,0,NUM_BITMAP_HEIGHT*(bombCount<0?0:11-(int)floor(bombCount/100)),SRCCOPY);
BitBlt(hDC,COUNT_LEFTPOS+NUM_BITMAP_WIDTH,COUNT_TOPPOS,NUM_BITMAP_WIDTH,NUM_BITMAP_HEIGHT,hDCMem,0,NUM_BITMAP_HEIGHT*(11-(int)floor((abs(bombCount)-(int)floor(abs(bombCount)/100)*100)/10)),SRCCOPY);
BitBlt(hDC,COUNT_LEFTPOS+NUM_BITMAP_WIDTH*2,COUNT_TOPPOS,NUM_BITMAP_WIDTH,NUM_BITMAP_HEIGHT,hDCMem,0,NUM_BITMAP_HEIGHT*(11-(abs(bombCount)-(int)floor(abs(bombCount)/10)*10)),SRCCOPY);
//计时器贴图
BitBlt(hDC,rcWnd.right-TIME_RIGHTSTND-TIME_WIDTH,TIME_TOPPOS,NUM_BITMAP_WIDTH,NUM_BITMAP_HEIGHT,hDCMem,0,NUM_BITMAP_HEIGHT*(11-(timeCount<1000?(int)floor(timeCount/100):9)),SRCCOPY);
BitBlt(hDC,rcWnd.right-TIME_RIGHTSTND-TIME_WIDTH+NUM_BITMAP_WIDTH,TIME_TOPPOS,NUM_BITMAP_WIDTH,NUM_BITMAP_HEIGHT,hDCMem,0,NUM_BITMAP_HEIGHT*(11-(timeCount<1000?(int)floor((timeCount-(int)floor(timeCount/100)*100)/10):9)),SRCCOPY);
BitBlt(hDC,rcWnd.right-TIME_RIGHTSTND-TIME_WIDTH+NUM_BITMAP_WIDTH*2,TIME_TOPPOS,NUM_BITMAP_WIDTH,NUM_BITMAP_HEIGHT,hDCMem,0,NUM_BITMAP_HEIGHT*(11-(timeCount<1000?(timeCount-(int)floor(timeCount/10)*10):9)),SRCCOPY);
DeleteObject(hBmp);
//立体边框描绘
rcRefresh=CreateRect(MAIN_LEFTSTND-LINE_LIGHTEN_THICK,MAIN_TOPSTND-LINE_LIGHTEN_THICK,rcWnd.right-MAIN_RIGHTSTND-MAIN_LEFTSTND+2*LINE_LIGHTEN_THICK,rcWnd.bottom-MAIN_TOPSTND-MAIN_BOTTOMSTND+2*LINE_LIGHTEN_THICK,FALSE);
DrawSolidFrame(hDC,rcRefresh,LINE_LIGHTEN_THICK);
rcRefresh=CreateRect(FUN_LEFTPOS-LINE_LIGHTEN_THICK,FUN_TOPPOS-LINE_LIGHTEN_THICK,rcWnd.right-FUN_LEFTPOS-FUN_RIGHTSTND+2*LINE_LIGHTEN_THICK,MAIN_TOPSTND-FUN_TOPPOS-FUN_BOTTOMSTND+2*LINE_LIGHTEN_THICK,FALSE);
DrawSolidFrame(hDC,rcRefresh,LINE_LIGHTEN_NORMAL);
rcRefresh=CreateRect(COUNT_LEFTPOS-LINE_LIGHTEN_THIN,COUNT_TOPPOS-LINE_LIGHTEN_THIN,COUNT_WIDTH+2*LINE_LIGHTEN_THIN,COUNT_HEIGHT+2*LINE_LIGHTEN_THIN,FALSE);
DrawSolidFrame(hDC,rcRefresh,LINE_LIGHTEN_THIN);
rcRefresh=CreateRect(rcWnd.right-TIME_RIGHTSTND-TIME_WIDTH-LINE_LIGHTEN_THIN,TIME_TOPPOS-LINE_LIGHTEN_THIN,TIME_WIDTH+2*LINE_LIGHTEN_THIN,TIME_HEIGHT+2*LINE_LIGHTEN_THIN,FALSE);
DrawSolidFrame(hDC,rcRefresh,LINE_LIGHTEN_THIN);
//雷区贴图
hBmp=LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_MINE_BLACK+(flagState&0x0004)/0x0004));
SelectObject(hDCMem,hBmp);
for(ix=0;ixhInstance; //实例句柄
break;
case WM_INITDIALOG: //初始化
//初始化 自定义对话框 为当前数据
SetDlgItemInt(hDlg,IDC_CUSTOM_HEIGHT,mineRowNum,TRUE);
SetDlgItemInt(hDlg,IDC_CUSTOM_WIDTH,mineLineNum,TRUE);
SetDlgItemInt(hDlg,IDC_CUSTOM_BOMB,mineBomb,TRUE);
//初始化排行榜为注册表保存数据,如果没有键值 设置默认
LoadString(hInstance,IDS_SECOND,lpFormat,sizeof(lpFormat));
if (RegOpenKeyEx(HKEY_CURRENT_USER,keyWinMine,0,KEY_READ,&hKey)==ERROR_SUCCESS){
for (i=0;i<3;i++){
if (RegQueryValueEx(hKey,lpsTime[i],NULL,&dwType1,(LPBYTE)&dwTime,&dwSize1)!=ERROR_SUCCESS)//时间
dwTime=999;
sprintf(lpOutput,lpFormat,dwTime); //格式化
SetDlgItemText(hDlg,IDC_BEGINER_TIME+i,(LPCSTR)lpOutput); //显示时间到排行榜对话框
if (RegQueryValueEx(hKey,lpsName[i],NULL,&dwType2,(LPBYTE)&lpBuff,&dwSize2)!=ERROR_SUCCESS)//姓名
LoadString(hInstance,IDS_NORMAL_NAME,lpBuff,sizeof(lpBuff));
SetDlgItemText(hDlg,IDC_BEGINER_NAME+i,(LPCSTR)lpBuff); //显示姓名到排行榜对话框
}
RegCloseKey(hKey);
}
//初始化输入新纪录对话框
LoadString(hInstance,IDS_RECORD_BEGINER+(flagState&0x0f00)/0x0100,lpBuff,sizeof(lpBuff));
SetDlgItemText(hDlg,IDC_RECORD_MSG,lpBuff);
LoadString(hInstance,IDS_NORMAL_NAME,lpBuff,sizeof(lpBuff));
SetDlgItemText(hDlg,IDC_RECORD_NAME,lpBuff);
break;
case WM_COMMAND: //控件消息处理
switch(LOWORD(wParam)){
case IDC_CUSTOM_OK: //自定义确认
//设置长、宽、雷为对话框输入,如果越界设为最值
width=(GetDlgItemInt(hDlg,IDC_CUSTOM_WIDTH,FALSE,TRUE)MIN_LN_NUM?width:MIN_LN_NUM;
height=GetDlgItemInt(hDlg,IDC_CUSTOM_HEIGHT,FALSE,TRUE)MIN_COL_NUM?height:MIN_COL_NUM;
bomb=GetDlgItemInt(hDlg,IDC_CUSTOM_BOMB,FALSE,TRUE)MIN_BOMB_NUM?bomb:MIN_BOMB_NUM;
mineBomb=mineBomb<(mineRowNum*mineLineNum*0.8)?mineBomb:(int)floor(mineRowNum*mineLineNum*0.8);
EndDialog(hDlg,TRUE);
break;
case IDC_CUSTOM_CANCEL: //自定义取消,不处理,关闭
EndDialog(hDlg,FALSE);
break;
case IDC_HEROLIST_OK: //排行榜确定,不处理,关闭
EndDialog(hDlg,TRUE);
break;
case IDC_HEROLIST_RENEW: //排行榜重置,并写入注册表
LoadString(hInstance,IDS_NORMAL_NAME,lpAnonymity,sizeof(lpAnonymity));
if (RegOpenKeyEx(HKEY_CURRENT_USER,keyWinMine,0,KEY_WRITE,&hKey)==ERROR_SUCCESS){
for (i=0;i<3;i++){
dwTime=999;
RegSetValueEx(hKey,lpsTime[i],NULL,dwType1,(LPBYTE)&dwTime,dwSize1);
RegSetValueEx(hKey,lpsName[i],NULL,dwType2,(LPBYTE)&lpAnonymity,dwSize2);
}
RegCloseKey(hKey);
SendMessage(hDlg,WM_INITDIALOG,wParam,lParam);
}
break;
case IDC_RECORD_OK: //输入新纪录确定
GetDlgItemText(hDlg,IDC_RECORD_NAME,lpBuff,sizeof(lpBuff));
if (strlen(lpBuff)>0){ //输入不为空
if (RegOpenKeyEx(HKEY_CURRENT_USER,keyWinMine,0,KEY_WRITE,&hKey)==ERROR_SUCCESS){
RegSetValueEx(hKey,lpsTime[(flagState&0x0f00)/0x0100],NULL,dwType1,(LPBYTE)&timeCount,dwSize1);
RegSetValueEx(hKey,lpsName[(flagState&0x0f00)/0x0100],NULL,dwType2,(LPBYTE)&lpBuff,dwSize2);
RegCloseKey(hKey);
}
}
EndDialog(hDlg,TRUE);
break;
}
}
return FALSE; //不处理的消息返回FALSE
}
/*###########################################################
功能:初始化地图基本信息
参数:窗口句柄、等级、宽、高、雷、标志数、时间计数标志、表情标志
返回值:成功 返回TRUE
###########################################################*/
BOOL IinitializeMapInfo(HWND hWnd,int level,int col,int ln,int bomb){
mineRowNum=(colMIN_COL_NUM) ? col:MIN_COL_NUM;
mineLineNum=(lnMIN_LN_NUM) ? ln:MIN_LN_NUM;
mineBomb=(bombMIN_BOMB_NUM) ? bomb:MIN_BOMB_NUM;
flagState=(flagState & 0xf0ff)+level*0x0100; //设置标志位
flagState=(flagState & 0xfffe)+0x0001;
flagState=flagState & 0xfffd;
flagState=(flagState & 0x0fff)+0x4000;
bombCount=bomb;
timeCount=0;
openCount=mineRowNum*mineLineNum-mineBomb;
KillTimer(hWnd,FLAG_TIMECOUNT); //停止当前已有的计时器
return TRUE;
}
/*###########################################################
//功能:生成随机地图
//参数:窗口句柄
//返回值:
//###########################################################*/
BOOL CreateRandomMap(HWND hWnd){
btLandmineMapinfo[0][0]=(BYTE)0;
DWORD ixMine,iyMine,iMineBomb,icBomb=0,x,y;
RECT rcMine;
for(int i=0;iMAIN_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=0x10&&i>=0&&j>=0&&i=0&&j>=0&&i=mineRowNum||nowMouse.mXpos+i>=mineLineNum) //交换不能解决,重新生成地图
CreateRandomMap(hWnd);i=0;//交换位置
temp=btLandmineMapinfo[mineRowNum-nowMouse.mXpos-i][mineLineNum-nowMouse.mYpos-i];
btLandmineMapinfo[mineRowNum-nowMouse.mXpos-i][mineLineNum-nowMouse.mYpos-i]=btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos];
btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]=temp;
i++;
}while (btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]>=0x10);
}
flagState = (flagState & 0xfffd)+0x0002; //开始计时器
}
RefreshSmileFaceBmp(hWnd,FACE_TYPE_SMILE_POP);
OnChangeMineInfo(hWnd,hInstance,nowMouse); //改变地图信息
break;
case BTN_RBUTTONDOWN:
if (btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]%0x10>0x02) break;//已经翻开,返回
if ((btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]%0x10)<0x01+(flagState & 0x0008)/0x0008)
btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]++;//如果标记:未翻开 -〉棋子-〉问号;如果不标记:未翻开 -〉棋子
else if ((btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]%0x10)==0x01+(flagState & 0x0008)/0x0008)
btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]-=(1+(flagState & 0x0008)/0x0008);//返回为未翻开的状态
else if (btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]%0x10==0x02&&(flagState & 0x0008)==0) {
btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]-=2;
bombCount--;
}
bombCount=bombCount-((btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]%0x10)%2)*(0x01+(((flagState & 0x0008)/0x0008+0x01)%0x02))+(btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]%0x10)/0x02+((flagState & 0x0008)/0x0008+0x01)%0x02;
rcRefresh=CreateRect(nowMouse.mXpos,nowMouse.mYpos,1,1,TRUE);
InvalidateRect(hWnd,&rcRefresh,FALSE);
rcRefresh=CreateRect(COUNT_LEFTPOS,COUNT_TOPPOS,COUNT_WIDTH,COUNT_HEIGHT,FALSE);
InvalidateRect(hWnd,&rcRefresh,FALSE);
break;
case BTN_DBBUTTONDOWN:
OnChangeMineDown(hWnd,nowMouse.mXpos,nowMouse.mYpos,1);
break;
case BTN_DBBUTTONUP:
OnChangeMineUpon(hWnd,nowMouse.mXpos,nowMouse.mYpos,1);
RefreshSmileFaceBmp(hWnd,FACE_TYPE_SMILE_POP);
if (btLandmineMapinfo[nowMouse.mXpos][nowMouse.mYpos]%0x10>6){ //如果是翻开的数字
if (getRoundFlagNum(hWnd,nowMouse.mXpos,nowMouse.mYpos)==getRoundMineNum(hWnd,nowMouse.mXpos,nowMouse.mYpos)){ //两者相等
for (int i=0;i<3;i++) //翻开周围9格(会递归){
for (int j=0;j<3;j++){
tempMouse.mXpos=nowMouse.mXpos-1+i;
tempMouse.mYpos=nowMouse.mYpos-1+j;
OnChangeMineInfo(hWnd,hInstance,tempMouse);
}
}
}
break;
case BTN_LBUTTONMOVING:
if (lastXpos!=nowMouse.mXpos||lastYpos!=nowMouse.mYpos){
OnChangeMineUpon(hWnd,lastXpos,lastYpos,0);
OnChangeMineDown(hWnd,nowMouse.mXpos,nowMouse.mYpos,0);
lastXpos=nowMouse.mXpos;
lastYpos=nowMouse.mYpos;
}
break;
case BTN_DBBUTTONMOVING:
if (lastXpos!=nowMouse.mXpos||lastYpos!=nowMouse.mYpos){
OnChangeMineUpon(hWnd,lastXpos,lastYpos,1);
OnChangeMineDown(hWnd,nowMouse.mXpos,nowMouse.mYpos,1);
lastXpos=nowMouse.mXpos;
lastYpos=nowMouse.mYpos;
}
break;
}
break;
/////////////////////////////////////////////
case MOUSE_ON_FACE:
switch(nowMouse.mButtonMode)
{
case BTN_LBUTTONDOWN:
lastFace=(flagState&0xf000)/0x1000;
RefreshSmileFaceBmp(hWnd,FACE_TYPE_SMILE_PUSH);
break;
case BTN_LBUTTONUP:
case BTN_DBBUTTONUP:
if (flagState&0x0001==0x0000) //游戏未开始则开始
flagState=(flagState&0xfffe)+0x0001;
RefreshSmileFaceBmp(hWnd,FACE_TYPE_SMILE_POP);
IinitializeMapInfo(hWnd,(flagState&0x0f00)/0x0100,mineRowNum,mineLineNum,mineBomb); //??
CreateRandomMap(hWnd);
InvalidateRect(hWnd,NULL,FALSE);
lastFace=0x0004;
break;
}
break;
/////////////////////////////////////////////
case MOUSE_ON_OTHER:
if (startMouse==MOUSE_ON_FACE){
RefreshSmileFaceBmp(hWnd,lastFace);
return FALSE;
}
if (!(flagState&0x0001)) return 0;
switch(nowMouse.mButtonMode)
{
case BTN_LBUTTONDOWN:
case BTN_DBBUTTONDOWN:
RefreshSmileFaceBmp(hWnd,FACE_TYPE_EXCLAIM);
break;
case BTN_RBUTTONUP:
case BTN_LBUTTONUP:
RefreshSmileFaceBmp(hWnd,FACE_TYPE_SMILE_POP);
break;
case BTN_LBUTTONMOVING:
if (lastXpos!=nowMouse.mXpos||lastYpos!=nowMouse.mYpos){
OnChangeMineUpon(hWnd,lastXpos,lastYpos,0);
OnChangeMineDown(hWnd,nowMouse.mXpos,nowMouse.mYpos,0);
lastXpos=nowMouse.mXpos;
lastYpos=nowMouse.mYpos;
}
break;
case BTN_DBBUTTONMOVING:
if (lastXpos!=nowMouse.mXpos||lastYpos!=nowMouse.mYpos){
OnChangeMineUpon(hWnd,lastXpos,lastYpos,1);
OnChangeMineDown(hWnd,nowMouse.mXpos,nowMouse.mYpos,1);
lastXpos=nowMouse.mXpos;
lastYpos=nowMouse.mYpos;
}
break;
}
break;
}
if (openCount==0) setGameSucceed(hWnd,hInstance); //判断结束:空格为0,剩下的都是雷(标记和为标记旗子的)处理游戏成功
return FALSE;
}
/*###########################################################
功能:设置等级改变后菜单的check
参数:菜单句柄、等级
返回值:
###########################################################*/
BOOL OnCheckLevelMenu(HMENU hMenu,int level){
CheckMenuItem(hMenu,IDM_ADVANCED,MF_UNCHECKED);//所有未打钩
CheckMenuItem(hMenu,IDM_INTERMEDIATE,MF_UNCHECKED);
CheckMenuItem(hMenu,IDM_BEGINNER,MF_UNCHECKED);
CheckMenuItem(hMenu,IDM_CUSTOMDEFINE,MF_UNCHECKED);
CheckMenuItem(hMenu,IDM_BEGINNER+level,MF_CHECKED); //钩选当前等级
flagState=((flagState&0xf0ff)+level*0x0100); //改变状态
return TRUE;
}
/*###########################################################
功能:处理游戏成功
参数:
返回值:
###########################################################*/
BOOL setGameSucceed(HWND hWnd,HINSTANCE hInstance){
RECT rcRefresh;
LPCTSTR keyWinMine=TEXT("Software\\Microsoft\\winmine\\");
LONG lErrorID=0;
DWORD dwSize=sizeof(DWORD);
HKEY hKey;
DWORD dwTime;
LPCTSTR lpsLevel[3]={TEXT("Time1"),TEXT("Time2"),TEXT("Time3")};
openCount=-1; //重置空格计数
bombCount=0;
rcRefresh=CreateRect(COUNT_LEFTPOS,COUNT_TOPPOS,COUNT_WIDTH,COUNT_HEIGHT,FALSE); InvalidateRect(hWnd,&rcRefresh,FALSE);
KillTimer(hWnd,FLAG_TIMECOUNT); //结束计数
if ((flagState&0x0010)!=0){
HRSRC hrWare=FindResource(hInstance,MAKEINTRESOURCE(IDW_WAVE_DONE),TEXT("WAVE")); //播放声音资源
HGLOBAL hGlobal=LoadResource(hInstance,hrWare);
PlaySoundW((LPCWSTR)LockResource(hGlobal),NULL,SND_MEMORY|SND_ASYNC);
}
flagState=flagState& 0xfffe; //设置结束状态,未计时
RefreshSmileFaceBmp(hWnd,FACE_TYPE_COOL); //表情-酷
for (int i=0;i=0x10)
{
btLandmineMapinfo[i][j]=0x11;
rcRefresh=CreateRect(i,j,1,1,TRUE);
InvalidateRect(hWnd,&rcRefresh,FALSE);
}
}
}
if ((flagState&0x0f00)>0x0200) return FALSE;//如果登记为自定义,返回,不处理排行和注册表
lErrorID=RegOpenKeyEx(HKEY_CURRENT_USER,keyWinMine,0,KEY_READ,&hKey);//读取当前保存消息
if (lErrorID==ERROR_SUCCESS){
lErrorID=RegQueryValueEx(hKey,lpsLevel[(flagState&0x0f00)/0x0100],NULL,NULL,(LPBYTE)&dwTime,&dwSize);
if (lErrorID==ERROR_SUCCESS){
if (timeCount<(int)dwTime)DialogBox(hInstance,MAKEINTRESOURCE(IDD_RECORDDLG),hWnd,WinDlgProc); //破纪录了//输入新纪录
}
else ErrorMessageBox(hWnd,hInstance,IDS_ERRORID,lErrorID);
}else ErrorMessageBox(hWnd,hInstance,IDS_ERRORID,lErrorID);
RegCloseKey(hKey);
return TRUE;
}
/*###########################################################
功能:错误消息对话框
参数:窗口句柄、实例句柄、消息、消息id
返回值:
###########################################################*/
BOOL ErrorMessageBox(HWND hWnd,HINSTANCE hInstance,UINT IDMessage,UINT IDError){
TCHAR lpFormat[255],lpOutput[255];
if (IDError!=0){
LoadString(hInstance,IDMessage,lpFormat,sizeof(lpFormat));
sprintf(lpOutput,lpFormat,IDError);
}
else LoadString(hInstance,IDMessage,lpOutput,sizeof(lpOutput));
MessageBox(hWnd,lpOutput,"错误",MB_ICONERROR);
return TRUE;
}
/*###########################################################
功能:是方格显示为按下的状态
参数:鼠标位置结构体
返回值:
###########################################################*/
BOOL OnChangeMineDown(HWND hWnd,int xPos,int yPos,int mNum){
RECT rcRefresh;
for (int i=xPos-mNum;i<=xPos+mNum;i++){
for (int j=yPos-mNum;j<=yPos+mNum;j++){
if (i>=0&&i=0&&j=0&&i=0&&j=0x20){
if (btLandmineMapinfo[i][j]%0x10==0x0f) btLandmineMapinfo[i][j]-=0x2f; //0x2f 显示为 0的状态 0x
if (btLandmineMapinfo[i][j]%0x10==0x06) btLandmineMapinfo[i][j]-=0x24;
rcRefresh=CreateRect(i,j,mNum+1,mNum+1,TRUE);
InvalidateRect(hWnd,&rcRefresh,FALSE);
}
}
}
}
return TRUE;
}