📄 texiccb.cpp
字号:
// TExicCB.cpp: implementation of the TExicCB class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TExicCB.h"
#include "bank.h"
LRESULT CALLBACK Look(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
char cc[32];
switch (message)
{
case WM_INITDIALOG:
SetDlgItemText(hDlg,A_B1,itoa(GetIni().Time[0],cc,10));
SetDlgItemText(hDlg,A_B2,itoa(GetIni().Time[1],cc,10));
SetDlgItemText(hDlg,A_B3,itoa(GetIni().Time[2],cc,10));
SetDlgItemText(hDlg,N_1,GetIni().Name[0]);
SetDlgItemText(hDlg,N_2,GetIni().Name[1]);
SetDlgItemText(hDlg,N_3,GetIni().Name[2]);
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
LRESULT CALLBACK GxGx(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
SetDlgItemText(hDlg,602,GetIni().Name[GetIni().Difficulty]);
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
GetDlgItemText(hDlg,602,GetIni().Name[GetIni().Difficulty],63);
}
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
LRESULT CALLBACK Set(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
char cc[128];
switch (message)
{
case WM_INITDIALOG:
SetDlgItemText(hDlg,A_H,itoa(GetIni().Height,cc,10));
SetDlgItemText(hDlg,A_W,itoa(GetIni().Width,cc,10));
SetDlgItemText(hDlg,A_N,itoa(GetIni().Mines,cc,10));
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
int w,h,n;
GetDlgItemText(hDlg,A_H,cc,10);
w=atoi(cc);
GetDlgItemText(hDlg,A_W,cc,10);
h=atoi(cc);
GetDlgItemText(hDlg,A_N,cc,10);
n=atoi(cc);
if(w<10 || w>N_X)
{
MessageBox(hDlg,"宽度:10 ~ 60","",MB_OK);
return false;
}
if(h<10 || h>N_Y)
{
MessageBox(hDlg,"高度:10 ~ 48","",MB_OK);
return false;
}
if(h>w*h/4)
{
MessageBox(hDlg,"地雷数太多","",MB_OK);
return false;
}
GetIni().Height=h;
GetIni().Width=w;
GetIni().Mines=n;
}
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
TData::TData()
{
Reset();
}
int TData::Mine()
{
return GetIni().Mines;
}
int TData::W()
{
return GetIni().Width;
}
int TData::H()
{
return GetIni().Height;
}
void TData::Reset()
{
int i,x,y,n;
for(x=0;x<N_X;x++)for(y=0;y<N_Y;y++)
{
d[x][y].mine=0;
d[x][y].state=S_Null;
}
n=Mine();
int a=W()*H();
for(i=0;n>0 && i<a;i++)
{
d[i/H()][i%H()].mine=(rand()%(a-i)<n)?1:0;
if(d[i/H()][i%H()].mine)n--;
}
}
SQ& TData::GetD(int i)
{
return d[i%W()][i/W()];
}
SQ& TData::GetD(int x,int y)
{
return d[x][y];
}
bool TData::Inside(int x,int y)
{
return x>=0 && y>=0 && x<W() && y<H();
}
int TData::GetReset()//返回示标志地雷数
{
int x,y,n=0;
for(x=0;x<W();x++)for(y=0;y<H();y++)
{
if(d[x][y].state==S_Mark)n++;
}
return GetIni().Mines-n;
}
bool TData::OK()//全部打开
{
int x,y;
for(x=0;x<W();x++)for(y=0;y<H();y++)
{
if(d[x][y].mine==0 && d[x][y].state!=S_Open)return false;
}
return true;
}
void TData::MarkAll()//是地雷的全部标志
{
int x,y;
for(x=0;x<W();x++)for(y=0;y<H();y++)
{
if(d[x][y].mine)
d[x][y].state=S_Mark;
}
}
int TData::Getint(int x,int y)//应该显示的数字
{
int n=0;
for(int i=0;i<9;i++)
{
if(i==4)continue;
if(IsMine(x-1+i/3,y-1+i%3))n++;
}
return n;
}
int TData::GetMark(int x,int y)//周围已标志的数量
{
int n=0;
for(int i=0;i<9;i++)
{
if(i==4)continue;
if(IsState(S_Mark,x-1+i/3,y-1+i%3))n++;
}
return n;
}
bool TData::IsState(unsigned int state,int i)
{
if(!Inside(i%W(),i/W()))return false;
return d[i%W()][i/W()].state==state;
}
bool TData::IsState(unsigned int state,int x,int y)
{
if(!Inside(x,y))return false;
return d[x][y].state==state;
}
bool TData::IsMine(int x,int y)
{
if(!Inside(x,y))return false;
return d[x][y].mine!=0;
}
bool TData::IsNumb(int x,int y)
{
if(!Inside(x,y))return false;
return d[x][y].mine==0;
}
TExicCB::TExicCB()
:TExic()
{
srand( (unsigned)time( 0 ) );
m_posMouse=-1;
m_bHitHead=false;
m_Sec=0;
m_Over=false;
m_Begin=false;
}
void TExicCB::Init()
{
m_DC32=CreateCompatibleDC(0);
m_bmp32=LoadBitmap(m_hIns,MAKEINTRESOURCE(IDB_32));
SelectObject(m_DC32,m_bmp32);
m_DC24=CreateCompatibleDC(0);
m_bmp24=LoadBitmap(m_hIns,MAKEINTRESOURCE(IDB_24));
SelectObject(m_DC24,m_bmp24);
m_DC123=CreateCompatibleDC(0);
m_bmp123=LoadBitmap(m_hIns,MAKEINTRESOURCE(IDB_123));
SelectObject(m_DC123,m_bmp123);
m_DCHead=CreateCompatibleDC(0);
m_bmpHead=LoadBitmap(m_hIns,MAKEINTRESOURCE(IDB_HEAD));
SelectObject(m_DCHead,m_bmpHead);
m_X0=GetIni().x0;
m_Y0=GetIni().y0;
m_Data.Reset();
}
TExicCB::~TExicCB()
{
DeleteDC(m_DC32);
DeleteObject(m_bmp32);
DeleteDC(m_DC24);
DeleteObject(m_bmp24);
DeleteDC(m_DC123);
DeleteObject(m_bmp123);
DeleteDC(m_DCHead);
DeleteObject(m_bmpHead);
}
void TExicCB::Close(HWND hwnd)
{
KillTimer(hwnd,1000);
}
void TExicCB::SetupWindow(HWND hwnd)
{
TExic::SetupWindow(hwnd);
}
void TExicCB::UpBox(TDC &dc, int l, int t, int w, int h, bool bDown)
{
static HPEN bl=(HPEN)GetStockObject(BLACK_PEN);
static HPEN wh=(HPEN)GetStockObject(WHITE_PEN);
int r=l+w;
int b=t+h;
dc.SelectObject(bDown?bl:wh);
dc.MoveTo(l,b);
dc.LineTo(l,t);
dc.LineTo(r,t);
dc.SelectObject(bDown?wh:bl);
dc.LineTo(r,b);
dc.LineTo(l,b);
}
void TExicCB::OnDraw(TDC& dc)
{
RECT r;
GetWindowRect(m_hWnd,&r);
SetBkColor(dc.m_hDC,0xc0c0c0);
int x0=m_X0,y0=m_Y0;
int x,y;
int nBmp=15;
for(x=0;x<m_Data.W();x++)for(y=0;y<m_Data.H();y++)
Draw(dc,x,y,-1);
UpBox(dc,m_X0-1,m_Y0-2,GetIni().uint*GetIni().Width+2,GetIni().uint*GetIni().Height+2,true);//主框
UpBox(dc,5,5,GetIni().uint*GetIni().Width+m_X0-5,m_Y0-11,true);//上框
POINT p;
for(int i=0;i<2;i++)
{
p=GetPos(i+1);
int nn=i==0?m_Data.GetReset():m_Sec;
UpBox(dc,p.x+79,p.y+46,-79,-47);
int hhh=100;
for(int j=0;j<3;j++)
{
if(nn<0)
{
nn=-nn;
BitBlt(dc.m_hDC,p.x+26*j,p.y,26,46,m_DC123,0,11*46,SRCCOPY);
nn%=hhh;
hhh/=10;
continue;
}
BitBlt(dc.m_hDC,p.x+26*j,p.y,26,46,m_DC123,0,nn/hhh*46,SRCCOPY);
nn%=hhh;
hhh/=10;
}
}
p=GetPos(3);
BitBlt(dc.m_hDC,p.x,p.y,46,48,m_DCHead,0,m_bHitHead?0:48,SRCCOPY);
}
void TExicCB::OnTimer(HWND hwnd,UINT id)
{
time_t t;
time(&t);
m_Sec=t-m_tBegin;
InvalidateRect(m_hWnd,0,FALSE);
}
UINT TExicCB::OnKeyDown(HWND hwnd,UINT key)
{
return 1;
}
UINT TExicCB::OnChar(HWND hwnd,char c)
{
return 1;
}
UINT TExicCB::OnMessage(HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam)
{
POINT p;
p.x=lParam&0xFFFF;
p.y=lParam>>16;
switch(message)
{
case WM_MOUSEMOVE:
OnMouseMove(wParam,p);
break;
case WM_LBUTTONDOWN:
OnLButtonDown(wParam,p);
break;
case WM_LBUTTONUP:
OnLButtonUp(wParam,p);
break;
case WM_RBUTTONDOWN:
OnRButtonDown(wParam,p);
break;
case WM_RBUTTONUP:
OnRButtonUp(wParam,p);
break;
case WM_TIMER:
OnTimer(hwnd,wParam);
break;
case WM_MOVE:
GetIni().Xpos = (int)(short) LOWORD(lParam); // horizontal position
GetIni().Ypos = (int)(short) HIWORD(lParam); // vertical position ;
break;
}
return TExic::OnMessage(hwnd,message,wParam,lParam);
}
UINT TExicCB::OnCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
switch(wParam)
{
case ID_RESTART:
break;
case A_BEGIN:
OnBegin();
break;
case D_24:
GetIni().uint=24;
OnBegin();
RedrawWindow();
break;
case D_32:
GetIni().uint=32;
OnBegin();
RedrawWindow();
break;
case A_1:
GetIni().Height=8;
GetIni().Width =8;
GetIni().Mines=10;
GetIni().Difficulty=0;
RedrawWindow();
break;
case A_2:
GetIni().Height=16;
GetIni().Width =16;
GetIni().Mines=40;
GetIni().Difficulty=1;
RedrawWindow();
break;
case A_3:
GetIni().Height=16;
GetIni().Width=30;
GetIni().Mines=99;
GetIni().Difficulty=2;
RedrawWindow();
break;
case A_4:
if(DialogBox(m_hIns, (LPCTSTR)ID_DEF, m_hWnd, (DLGPROC)Set)==IDOK)
{
GetIni().Difficulty=3;
RedrawWindow();
}
break;
case A_RECORD:
DialogBox(m_hIns, (LPCTSTR)ID_REC, m_hWnd, (DLGPROC)Look);
break;
}
return 0;
}
UINT TExicCB::OnSize(HWND hwnd, WPARAM wParam, int x,int y)
{
return 0;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
void TExicCB::Draw(TDC &dc, int x, int y,int n32)
{
if(n32<0)switch(m_Data.d[x][y].state )
{
case S_Null:
n32=(m_Over&&m_Data.d[x][y].mine)?5
:0;
break;
case S_Open:
n32=(m_Over&&m_Data.d[x][y].mine)?3
:m_Data.d[x][y].mine?5:15-m_Data.Getint(x,y);
break;
case S_Mark:
n32=(m_Over && !m_Data.d[x][y].mine)?4
:1;
break;
case S_Test:
n32=m_Data.d[x][y].mine?5:0;
break;
case S_Down:
default:
n32=15;
break;
}
switch(GetIni().uint)
{
case 32:
BitBlt(dc.m_hDC,m_X0+x*GetIni().uint,m_Y0+y*GetIni().uint,GetIni().uint,GetIni().uint,m_DC32,0,GetIni().uint*n32,SRCCOPY);
break;
case 24:
BitBlt(dc.m_hDC,m_X0+x*GetIni().uint,m_Y0+y*GetIni().uint,GetIni().uint,GetIni().uint,m_DC24,0,GetIni().uint*n32,SRCCOPY);
break;
}
}
void TExicCB::GameOver()
{
m_Over=true;
KillTimer(m_hWnd,1000);
}
void TExicCB::DoubleDown(int n)
{
int x=n%m_Data.W();
int y=n/m_Data.W();
for(int i=0;i<9;i++)
{
if(m_Data.IsState(S_Null,x-1+i%3,y-1+i/3))
m_Data.GetD(x-1+i%3,y-1+i/3).state=S_Down;
}
InvalidateRect(m_hWnd,0,FALSE);
}
void TExicCB::DoubleUp(int n,bool bDone)
{
int x=n%m_Data.W();
int y=n/m_Data.W();
for(int i=0;i<9;i++)
{
if(m_Data.IsState(S_Down,x-1+i%3,y-1+i/3))
m_Data.GetD(x-1+i%3,y-1+i/3).state=S_Null;
}
if(bDone)//---- 双点击 开始:------------
{
if(m_Data.IsState(S_Open,n))
{//中心必需已打开
if(m_Data.Getint(x,y)==m_Data.GetMark(x,y))
{//--- 标志数 相同
for(i=0;i<9;i++)
{
if(m_Data.IsState(S_Null,x-1+i%3,y-1+i/3))
{
Open(n+(i/3-1)*m_Data.W()+(i%3-1));
}
}
}
}
}
InvalidateRect(m_hWnd,0,FALSE);
}
void TExicCB::LbDown(int n)
{
if(m_Data.IsState(S_Null,n))
{
m_Data.GetD(n).state=S_Down;
InvalidateRect(m_hWnd,0,FALSE);
}
}
void TExicCB::LbUp(int n,bool bDone)
{
if(m_Data.IsState(S_Down,n))
{
m_Data.GetD(n).state=S_Null;
if(bDone)//---- 左击 开始:------------
{
Open(n);
}
InvalidateRect(m_hWnd,0,FALSE);
}
}
void TExicCB::Open(int n)
{
if(m_Over)return;
m_Data.GetD(n).state=S_Open;
if(!m_Begin)
{
m_Begin=true;
time(&m_tBegin);
SetTimer(m_hWnd,1000,500,0);
}
if(m_Data.GetD(n).mine)GameOver();
if(m_Data.Getint(n%m_Data.W(),n/m_Data.W())==0)
{
DoubleUp(n,true);
}
if(m_Data.OK())//完成了
{
m_Data.MarkAll();
GameOver();
InvalidateRect(m_hWnd,0,FALSE);
int d=GetIni().Difficulty;
if(d<3 && GetIni().Time[d]>m_Sec)//-------破纪录------
{
if(DialogBox(m_hIns, (LPCTSTR)ID_GX, m_hWnd, (DLGPROC)GxGx)==IDOK)
{
GetIni().Time[GetIni().Difficulty]=m_Sec;
}
}
}
}
POINT TExicCB::GetPos(int n)
{
POINT p={0,0};
static int yy=11;
int xx[]={15,GetIni().uint*(GetIni().Width)-80};
if(n==1 || n==2)
{
p.x=xx[n-1];
p.y=yy;
return p;
}
if(n==3)
{
p.x=(xx[0]+xx[1])/2+18;
p.y=10;
return p;
}
return p;
}
void TExicCB::OnBegin()
{
//time(&m_tBegin);
KillTimer(m_hWnd,1000);
m_Over=false;
m_Begin=false;
m_Sec=0;
m_Data.Reset();
InvalidateRect(m_hWnd,0,FALSE);
}//--------------------------------鼠标----------------------------------
void TExicCB::OnLButtonDown(UINT nFlags, POINT p)
{
int x=p.x-GetPos(3).x;
int y=p.y-GetPos(3).y;
if(nFlags==1 && x>=0 && x<46 && y>=0 && y<48)//按中人头
{
m_bHitHead=true;
InvalidateRect(m_hWnd,0,FALSE);
}
if(m_Over)return;
if(nFlags==1 && m_posMouse>=0)//单击
{
if(m_Data.GetD(m_posMouse).state==S_Null)
{
m_Data.GetD(m_posMouse).state=S_Down;
InvalidateRect(m_hWnd,0,FALSE);
}
}
if(nFlags==3 && m_posMouse>=0)//双击
{
DoubleDown(m_posMouse);
}
}
void TExicCB::OnLButtonUp(UINT nFlags, POINT p)
{
int x=p.x-GetPos(3).x;
int y=p.y-GetPos(3).y;
if(m_bHitHead && nFlags==0 && x>=0 && x<46 && y>=0 && y<48)//按中人头
{
OnBegin();
}
if(m_bHitHead)//按中人头
{
m_bHitHead=false;
InvalidateRect(m_hWnd,0,FALSE);
}
if(m_Over)return;
if(nFlags==0)//左击放
{
LbUp(m_posMouse,true);
}
if(nFlags==2)//双击放
{
DoubleUp(m_posMouse,true);
}
}
void TExicCB::OnRButtonDown(UINT nFlags, POINT p)
{
if(m_Over)return;
if(nFlags==2 && m_posMouse>=0)//标志
{
if(m_Data.GetD(m_posMouse).state==S_Null)
{
m_Data.GetD(m_posMouse).state=S_Mark;
InvalidateRect(m_hWnd,0,FALSE);
}
else if(m_Data.GetD(m_posMouse).state==S_Mark)
{
m_Data.GetD(m_posMouse).state=S_Null;
InvalidateRect(m_hWnd,0,FALSE);
}
}
if(nFlags==3 && m_posMouse>=0)//双击
{
DoubleDown(m_posMouse);
}
}
void TExicCB::OnRButtonUp(UINT nFlags, POINT p)
{
if(m_Over)return;
if(nFlags==1)//双击放
{
DoubleUp(m_posMouse,true);
LbDown(m_posMouse);
}
}
void TExicCB::OnMouseMove(UINT nFlags, POINT p)
{
int old=m_posMouse;
int x=(p.x-m_X0+GetIni().uint)/GetIni().uint-1;
int y=(p.y-m_Y0+GetIni().uint)/GetIni().uint-1;
m_posMouse=m_Data.Inside(x,y)?(x+y*m_Data.W()):-1;
if(nFlags==14)//作弊 :Ctrl+Shift+右键 移动
{
if(m_Data.IsState(S_Null,m_posMouse) && m_posMouse!=old)
{
m_Data.GetD(m_posMouse).state=S_Test;
InvalidateRect(m_hWnd,0,FALSE);
}
}
if(m_Data.IsState(S_Test,old) && m_posMouse!=old)
{
m_Data.GetD(old).state=S_Null;
InvalidateRect(m_hWnd,0,FALSE);
}
if(old==m_posMouse)return;
if(nFlags==2)return;//旗已标明。
if(old<0 && m_posMouse<0)return;//都没有按中。
if(nFlags==1)//左键按下
{
LbUp(old);
LbDown(m_posMouse);
}
if(nFlags==3)//双键按下
{
DoubleUp(old);
DoubleDown(m_posMouse);
}
}
//-----------------------------------------------------------------------------
void TExicCB::RedrawWindow()
{
m_Data.Reset();
S_ini& d=GetIni();
MoveWindow(m_hWnd,d.Xpos-GetIni().dw,d.Ypos-GetIni().dh,d.WX(),d.WY(),TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -