/*------------------------------------------------------------
HELLOWIN.C -- Displays "Hello, Windows 98!" in client area
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
#include <stdlib.h>
#include <time.h>
#include <tchar.h>
#include <math.h>
#include "WinMain.h"
#include "resource.h"
#pragma comment( lib,"winmm.lib")
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
BOOL CALLBACK WinDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Mine sweeper") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = NULL;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance,MAKEINTRESOURCE(IDI_MINE)) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
UINT uXPos=GetSystemMetrics(SM_CXSCREEN)/2-200;
UINT uYPos=GetSystemMetrics(SM_CYSCREEN)/2-200;
hwnd = CreateWindow (szAppName, // window class name
TEXT ("扫雷"), // window caption
WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, // window style
uXPos, // initial x position
uYPos, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
//UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HBITMAP hbmpMine;
static HBITMAP hbmpButton;
static HBITMAP hbmpNumber;
static cxClient,cyClient;
static cxBitMap; //cyBitMap;
static RECT rcClient;
static int iBtnRectLeft,iBtnRectTop=16; //存放笑脸按钮左上角的坐标
static CButtonState strButton_State;
static UINT uNumRectLeft; //时间一栏左边的坐标
static CMineArray minearray[100][100];
static UINT uGameState; //游戏状态,0为等待,1为运行,2失败,3胜利
static int iRow,iCol; //游戏雷区的行数、列数
static int oldrow; //存放LBUTTON_DOWN的历史位置
static int oldcol;
static StrLRDownFlag strLRDownFlag;
static int iRemainBrick; //剩余的(没有被翻开的)方砖的数量
static BOOL ClickInButton; //标记是LButton时否在笑脸内部
static BOOL fLRBtnDown; //标记是否L_R_ButtonDown
static int iSpendTime; //用时
static int iLeaveMineNum; //剩下的雷
static bool bMarkful;
static bool bColorful;
static bool bSoundful;
static HINSTANCE hInstance;
static void* pSndDead=NULL; // 失败提示音
static void* pSndVictory=NULL; // 胜利提示音
static void* pSndClock=NULL; // 时钟提示音
HBITMAP hbitmap;
HDC hdc,hdcMem;
PAINTSTRUCT ps ;
switch (message)
{
case WM_CREATE:
{
hInstance=((LPCREATESTRUCT) lParam)->hInstance;
/*********初始化游戏**********/
LoadConfig(uColMax,
uRowMax,
uMineNum,
uLevel,
uPrimary,
uSecond,
uAdvance,
szPrimary,
szSecond,
szAdvance,
bMarkful,
bColorful,
bSoundful);
LoadBitmap(hInstance,hbmpMine,hbmpButton,hbmpNumber,bColorful);
InitGame(uColMax,
uRowMax,
uMineNum,
iRemainBrick,
minearray,
uGameState,
strButton_State,
fLRBtnDown,
iSpendTime,
iLeaveMineNum);
HMENU hMenu=GetMenu(hwnd);
SetCheckedLevel(hMenu,uLevel);
SetCheckedMark(hMenu,bMarkful);
SetCheckedColor(hMenu,bColorful);
SetCheckedSound(hMenu,bSoundful);
if (bSoundful)
{
LoadWaveSrc(pSndDead,pSndVictory,pSndClock);
}
}
return 0;
case WM_SHOWWINDOW:
{
UINT uWidth = LINE_WIDTH+SHELL_L_START_X*2+4+MINE_WIDTH*uColMax;
UINT uHeight = MINEAREA_UP+MINE_HEIGHT*uRowMax+60;
SetWindowPos(hwnd,HWND_TOPMOST, 0, 0,uWidth ,uHeight,
SWP_NOZORDER | SWP_NOMOVE | SWP_NOCOPYBITS );
/****************得到ClientWindow的坐标******************/
GetClientRect(hwnd,&rcClient);
iBtnRectLeft=rcClient.right/2-12; //笑脸的左边的坐标
uNumRectLeft=rcClient.right-56; //计算显示时间一栏左边的坐标
}
return 0;
case WM_SIZE:
cxClient= LOWORD(lParam);
cyClient= HIWORD(lParam);
return 0;
case WM_PAINT: //先把窗口的重画写好
hdc=BeginPaint(hwnd,&ps);
/************产生ClientDc兼容的内存,并装入Client大小的位图**********/
hdcMem=CreateCompatibleDC(hdc);
hbitmap=CreateCompatibleBitmap(hdc,rcClient.right,rcClient.bottom);
SelectObject(hdcMem,hbitmap);
/*****************用灰色填充ClientWindow******************/
FillSolidRect(hdcMem,&rcClient,COLOR_GRAY);
/*****************显示笑脸按钮************************/
DrawButton(hdcMem,iBtnRectLeft,iBtnRectTop,24,24,hbmpButton,0,24*strButton_State.uState);
/****************显示数字*********************/
DrawNumber(hdcMem,uNumRectLeft,hbmpNumber,iSpendTime,iLeaveMineNum);
/*****************绘制两个3d外壳*****************/
DrawShell(hdcMem,rcClient,uColMax,uRowMax);
/********************贴图(把雷区贴满图片)*****************/
DrawMineArea( hdcMem,hbmpMine,uColMax,uRowMax,minearray);
/********************将hdcMem顶到显示器********************/
BitBlt(hdc,0,0,rcClient.right,rcClient.bottom,hdcMem,0,0,SRCCOPY);
DeleteObject(hbitmap);
DeleteDC(hdcMem);
ReleaseDC(hwnd,hdc);
EndPaint(hwnd,&ps);
return 0 ;
case WM_MOUSEMOVE:
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
/*************************************************************/
/***************************左键按下**************************/
/*************************************************************/
if (MK_LBUTTON==wParam)
{
/*************************笑脸的处理**********************************/
/******笑脸区域RECT********/
RECT rect;
rect.left=iBtnRectLeft;
rect.top=iBtnRectTop;
rect.right=iBtnRectLeft+BUTTON_WIDTH;
rect.bottom=iBtnRectTop+BUTTON_HEIGHT;
if (xPos>=iBtnRectLeft && xPos<=iBtnRectLeft+BUTTON_WIDTH && yPos>=iBtnRectTop && yPos<=iBtnRectTop+BUTTON_HEIGHT)
{
if (TRUE==ClickInButton)
{
strButton_State.uState=BUTTON_DOWN;
InvalidateRect(hwnd,&rect,FALSE);
}
}
else
{
if (FALSE==ClickInButton) //确保第一次在笑脸外点击
{
if (GAME_WAITE==uGameState || GAME_RUN==uGameState)
{
strButton_State.uState=BUTTON_CLICK;
InvalidateRect(hwnd,&rect,FALSE);
}
}
else //确保第一次在笑脸内部点击
{
strButton_State.uState=strButton_State.uOldState;
InvalidateRect(hwnd,&rect,FALSE);
}
}
/**************************笑脸区域处理完毕********************************/
/***************************雷区处的处理*******************************/
if (GAME_WAITE==uGameState || GAME_RUN==uGameState)
{
if(FALSE==ClickInButton && FALSE==fLRBtnDown)
OnLButtonDownInMineArea(hwnd,uGameS