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

📄 ztscards.c

📁 ztscards
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "ztsCards.h"

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[] = "CardsWin";
	HANDLE	hAccel;
	HWND	hwnd;
	MSG	msg;
	WNDCLASS	wc;

	hInst = hInstance;
 	wc.style	= CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; //CS_DBLCLKS 风格是为了窗口能接收到 WM_LBUTTONDBLCLK 消息
 	wc.lpfnWndProc	= WndProc;
	wc.cbClsExtra	= 0;
	wc.cbWndExtra	= 0;
	wc.hInstance	= hInstance;
	wc.hIcon	= LoadIcon (hInstance, MAKEINTRESOURCE(IDI_MAIN));
  	wc.hCursor	= LoadCursor (NULL, IDC_ARROW) ;
 	wc.hbrBackground= CreateSolidBrush ( RGB(0,0x7a,0) );
  	wc.lpszMenuName	= (LPCSTR)IDM_MAIN;
	wc.lpszClassName= szAppName;

	RegisterClass (&wc);
	hwnd = CreateWindowEx(0,
			szAppName,
			"ZTS's 空当接龙 1.0",
			WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT,
			CW_USEDEFAULT,
			640,
			480,
			NULL,
			NULL,
			hInstance,
			NULL);
     
	ShowWindow (hwnd, iCmdShow);
	UpdateWindow (hwnd);

	hAccel = LoadAccelerators (hInstance, MAKEINTRESOURCE(IDA_MAIN));
	while (GetMessage (&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator (hwnd, hAccel, &msg))
		{
			TranslateMessage (&msg) ;
			DispatchMessage (&msg) ;
		}
	}
	return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT	ps;
	RECT*		pRect;
	char		buf[80];
	MCI_OPEN_PARMS	mciOpen;
	MCI_PLAY_PARMS	mciPlay;
	MCIERROR		mciError;
     
	switch (uMsg)
	{
	case WM_CREATE:
		cdtInit (&nCardWidth, &nCardHeight);
		OnCreate (hWnd);
		if (BkgroundMusic[0] != '1')
		{
			mciOpen.lpstrDeviceType = "MPEGVideo";
			mciOpen.lpstrElementName = BkgroundMusic;
			mciError = mciSendCommand (0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD)&mciOpen);
			if (!mciError)
			{
				mciSendCommand (mciOpen.wDeviceID, MCI_PLAY, MCI_DGV_PLAY_REPEAT, (DWORD)&mciPlay);
			}
		}
		return 0;

	case WM_PAINT:
		BeginPaint (hWnd, &ps);
		OnPaint (hWnd, ps.hdc);
		EndPaint (hWnd, &ps);
		return 0;

	case WM_COMMAND:
		switch (LOWORD (wParam))
		{
		case IDM_GAME_START:	//开局
			if (bPlaying)
			{//如果正在游戏中
				if (MessageBox (hWnd, "是否放弃本局?", "ZTS's 空当接龙", MB_YESNO | MB_ICONQUESTION) == IDNO)
					break;
				cur_losses++;
				lost++;
				if (stype == -1)
					streak++;
				else
				{
					stype = -1;
					streak = 1;
				}
				if (stype == -1)
				{
					if (streak > losses)
						losses = streak;
				}
			}
			bPlaying = TRUE;
			EnableMenuItem (GetMenu (hWnd), IDM_GAME_RESTART, MF_ENABLED);
			nNum = GenerateNum ();
			wsprintf (buf, "ZTS's 空当接龙 1.0 #%d", nNum);
			SetWindowText (hWnd, buf);
			SetCardsOrder (nNum);
			InvalidateRect (hWnd, NULL, TRUE);
			break;

		case IDM_GAME_SELECT:	//选局...
			nNum = GenerateNum ();
			if (bPlaying)
			{//如果正在游戏中
				if (MessageBox (hWnd, "是否放弃本局?", "ZTS's 空当接龙", MB_YESNO | MB_ICONQUESTION) == IDNO)
					break;
				cur_losses++;
				lost++;
				if (stype == -1)
					streak++;
				else
				{
					stype = -1;
					streak = 1;
				}
				if (stype == -1)
				{
					if (streak > losses)
						losses = streak;
				}
			}
			if (DialogBoxParam (hInst, MAKEINTRESOURCE(DLG_SELECTNUM), hWnd, DlgSelectNumProc, 0))
			{//如果按了“确定”按钮
				bPlaying = TRUE;
				EnableMenuItem (GetMenu (hWnd), IDM_GAME_RESTART, MF_ENABLED);
				wsprintf (buf, "ZTS's 空当接龙 1.0 #%d", nNum);
				SetWindowText (hWnd, buf);
				SetCardsOrder (nNum);
				InvalidateRect (hWnd, NULL, TRUE);
			}
			break;

		case IDM_GAME_RESTART:	//重玩
			if (bPlaying)
			{//如果正在游戏中
				if (MessageBox (hWnd, "是否放弃本局?", "ZTS's 空当接龙", MB_YESNO | MB_ICONQUESTION) == IDNO)
					break;
				cur_losses++;
				lost++;
				if (stype == -1)
					streak++;
				else
				{
					stype = -1;
					streak = 1;
				}
				if (stype == -1)
				{
					if (streak > losses)
						losses = streak;
				}
			}
			bPlaying = TRUE;
			SetCardsOrder (nNum);
			InvalidateRect (hWnd, NULL, TRUE);
			break;

		case IDM_GAME_SCORE:	//战况...
			DialogBoxParam (hInst, MAKEINTRESOURCE(DLG_SCORE), hWnd, DlgScoreProc, 0);
			break;

		case IDM_GAME_OPTION:	//选项...
			DialogBoxParam (hInst, MAKEINTRESOURCE(DLG_OPTION), hWnd, DlgOptionProc, 0);
			break;

		case IDM_GAME_UNDO:	//撤销
			break;

		case IDM_GAME_EXIT:	//退出
			SendMessage (hWnd, WM_CLOSE, 0, 0);
			break;

		case IDM_HELP_ABOUT:	//关于...
			MessageBox (hWnd, "界面和操作方式完全模仿 Windows 自带的空当接龙\n\n编程:一块三毛钱\n信箱:crazy_soft@163.net\n主页:zhongts.yeah.net", "ZTS's 空当接龙 1.0", MB_OK);
			break;
		}
		return 0;

	case WM_MOUSEMOVE:
		OnMouseMove (hWnd, LOWORD (lParam), HIWORD (lParam));
		break;

	case WM_LBUTTONDOWN:
		OnLbuttonDown (hWnd, LOWORD (lParam), HIWORD (lParam));
		break;

	//要想在鼠标双击时接收到该消息需要在注册窗口类时加上 CS_DBLCLKS 风格
	case WM_LBUTTONDBLCLK:
		OnLbuttonDblclk (hWnd, LOWORD (lParam), HIWORD (lParam));
		break;

	case WM_RBUTTONDOWN:
		OnRbuttonDown (hWnd, LOWORD (lParam), HIWORD (lParam));
		break;

	case WM_RBUTTONUP:
		OnRbuttonUp (hWnd);
		break;

//===================================================\	限制窗口的宽度在 640px
	case WM_SIZING:
		pRect = (LPRECT)lParam;
		if ((wParam == WMSZ_BOTTOMRIGHT) ||
			(wParam == WMSZ_RIGHT) ||
			(wParam == WMSZ_TOPRIGHT))
			pRect->right = pRect->left + 640;
		else
			pRect->left = pRect->right - 640;
		return 0;

	case WM_SIZE:
		if (wParam == SIZE_MAXIMIZED)
			MoveWindow (hWnd, 0, 0, 640, GetSystemMetrics (SM_CYSCREEN), TRUE);
		return 0;
//===================================================/

	case WM_CLOSE:
		if (bPlaying)
		{//如果正在游戏中
			if (MessageBox (hWnd, "是否放弃本局?", "ZTS's 空当接龙", MB_YESNO | MB_ICONQUESTION) == IDNO)
				return 0;
			cur_losses++;
			lost++;
			if (stype == -1)
				streak++;
			else
			{
				stype = -1;
				streak = 1;
			}
			if (stype == -1)
			{
				if (streak > losses)
					losses = streak;
			}
		}

		wsprintf (buf, "%d", bErrorMessage);
		WritePrivateProfileString ("Option", "ErrorMsg", buf, iniFile);
		wsprintf (buf, "%d", bQuickMoveCard);
		WritePrivateProfileString ("Option", "QuickMove", buf, iniFile);
		wsprintf (buf, "%d", bCanMouseDblclk);
		WritePrivateProfileString ("Option", "Dblclk", buf, iniFile);

		wsprintf (buf, "%d", won);
		WritePrivateProfileString ("Score", "won", buf, iniFile);
		wsprintf (buf, "%d", lost);
		WritePrivateProfileString ("Score", "lost", buf, iniFile);
		wsprintf (buf, "%d", wins);
		WritePrivateProfileString ("Score", "wins", buf, iniFile);
		wsprintf (buf, "%d", losses);
		WritePrivateProfileString ("Score", "losses", buf, iniFile);
		wsprintf (buf, "%d", streak);
		WritePrivateProfileString ("Score", "streak", buf, iniFile);
		wsprintf (buf, "%d", stype);
		WritePrivateProfileString ("Score", "stype", buf, iniFile);
		
		DestroyWindow (hWnd);
		return 0;

	case WM_DESTROY:
		cdtTerm();
		PostQuitMessage (0);
		return 0;
	}
	return DefWindowProc (hWnd, uMsg, wParam, lParam);
}


//处理 WM_CREATE 消息//////////////////////////////////////////////////////////
void OnCreate (HWND hWnd)
{
	int	i, j;
	HDC	hdc, hMemDC;
	DWORD	hPen_Old, hBrush_Old, hBmp_Old;
	char	buf[MAX_PATH];

	GetModuleFileName (hInst, iniFile, MAX_PATH);
	i = lstrlen (iniFile);
	iniFile[i-3] = 'i';
	iniFile[i-2] = 'n';
	iniFile[i-1] = 'i';	//buf = "可执行文件所在目录\ztsCard.ini"

	//读取 ini 文件中的设置参数
	GetPrivateProfileString ("Option", "ErrorMsg", "1", buf, MAX_PATH, iniFile);
	bErrorMessage = (buf[0] == '1') ? TRUE : FALSE;
	GetPrivateProfileString ("Option", "QuickMove", "1", buf, MAX_PATH, iniFile);
	bQuickMoveCard = (buf[0] == '1') ? TRUE : FALSE;
	GetPrivateProfileString ("Option", "Dblclk", "1", buf, MAX_PATH, iniFile);
	bCanMouseDblclk = (buf[0] == '1') ? TRUE : FALSE;

	//读取 ini 文件中的战况
	won = GetPrivateProfileInt ("Score", "won", 0, iniFile);
	lost = GetPrivateProfileInt ("Score", "lost", 0, iniFile);
	wins = GetPrivateProfileInt ("Score", "wins", 0, iniFile);
	losses = GetPrivateProfileInt ("Score", "losses", 0, iniFile);
	streak = GetPrivateProfileInt ("Score", "streak", 0, iniFile);
	stype = GetPrivateProfileInt ("Score", "stype", 0, iniFile);

	//背景音乐,算作一个彩蛋
	GetPrivateProfileString ("Option", "Music", "1", BkgroundMusic, MAX_PATH, iniFile);

	cur_losses = 0;
	cur_wins = 0;
	bPlaying = FALSE;
	bRbuttonDown = FALSE;
	ColumnSelected = -1;

	//初始化左右空当
	for (i=0; i<4; i++)
	{
		SpaceLeft[i] = -1;
		SpaceRight[i] = -1;
	}
	//初始化每列牌
	for (i=0;i<8;i++)
	for (j=0;j<21;j++)
		Cards[i][j] = -1;

	EnableMenuItem (GetMenu (hWnd), IDM_GAME_RESTART, MF_GRAYED);
	EnableMenuItem (GetMenu (hWnd), IDM_GAME_UNDO, MF_GRAYED);

	//创建一个绿色的画笔和一个深绿色的刷子
	hPen_Green = CreatePen (0, 1, RGB (0, 0xff, 0));
	hBrush_Bground = CreateSolidBrush (RGB (0, 0x7a, 0));

//===================================================\	绘制表示空当的位图
	hdc = GetDC (hWnd);
	hMemDC = CreateCompatibleDC (hdc);
	hBmpSpace = CreateCompatibleBitmap (hdc, nCardWidth, nCardHeight);
	hBmp_Old = (DWORD) SelectObject (hMemDC, hBmpSpace);
	hBrush_Old = (DWORD) SelectObject (hMemDC, hBrush_Bground);
	hPen_Old = (DWORD) SelectObject (hMemDC, GetStockObject (BLACK_PEN));

	//绘制位图的背景和凸凹框
	PatBlt (hMemDC, 0, 0, nCardWidth, nCardHeight, PATCOPY);
	MoveToEx (hMemDC, 0, nCardHeight, NULL);
	LineTo (hMemDC, 0, 0);
	LineTo (hMemDC, nCardWidth, 0);
	SelectObject (hMemDC, hPen_Green);
	MoveToEx (hMemDC, nCardWidth-1, 1, NULL);
	LineTo (hMemDC, nCardWidth-1, nCardHeight-1);
	LineTo (hMemDC, 1, nCardHeight-1);

	SelectObject (hMemDC, (HPEN)hPen_Old);
	SelectObject (hMemDC, (HBRUSH)hBrush_Old);
	SelectObject (hMemDC, (HBITMAP)hBmp_Old);
	DeleteDC (hMemDC);
	ReleaseDC (hWnd, hdc);
//===================================================/
}

//处理 WM_PAINT 消息///////////////////////////////////////////////////////////
void OnPaint (HWND hWnd, HDC hdc)
{
	DWORD	hPen_Old;
	int	i;

	//画中间的头像
	hPen_Old = (DWORD) SelectObject (hdc, hPen_Green);
	MoveToEx (hdc, x_Logo, y_Logo+36, NULL);
	LineTo (hdc, x_Logo, y_Logo);
	LineTo (hdc, x_Logo+36, y_Logo);
	SelectObject (hdc, GetStockObject (BLACK_PEN));
	LineTo (hdc, x_Logo+36, y_Logo+36);
	LineTo (hdc, x_Logo, y_Logo+36);
	SelectObject (hdc, (HPEN)hPen_Old);
	
	DrawLogo (hdc, 1);
	
	//画空档
	DrawSpaceLeft (hdc);
	DrawSpaceRight (hWnd, hdc);

	//画每列扑克
	for (i=0; i<8; i++)
	{
		DrawColumn (hdc, i, FALSE);
	}
}

//处理 WM_MOUSEMOVE 消息///////////////////////////////////////////////////////
void OnMouseMove (HWND hWnd, int xPos, int yPos)
{
	int	m, n, i, j, t, k;

	//中间头像的偏左或偏右
	if (yPos < nCardHeight)
	{
		if (xPos < 4*nCardWidth)
			DrawLogo (GetDC (hWnd), 0);
		else if (xPos > 348)
			DrawLogo (GetDC (hWnd), 1);
	}

	//可以移动牌的指示光标
	if (ColumnSelected != -1)
	{
		if (yPos < nCardHeight)
		{//空当
			if (xPos < 4*nCardWidth)
			{//左空当
				m = xPos/nCardWidth;
				if (SpaceLeft[m] == -1)
					SetCursor (LoadCursor (NULL, IDC_UPARROW));
			}
			else if (xPos > 348)
			{//右空当
				m = (xPos - 348) / nCardWidth;
				m = 3 - m;

				if (SpaceRight[m] == -1)
				{
					if (ColumnSelected < 8)
					{
						n = CalcColumnCards (ColumnSelected);
						n = Cards[ColumnSelected][n];
					}
					else
					{
						n = SpaceLeft[ColumnSelected-8];
					}

					if ((n / 4) == 0)
						SetCursor (LoadCursor (NULL, IDC_UPARROW));
				}
				else
				{
					if (ColumnSelected < 8)
					{
						n = CalcColumnCards (ColumnSelected);
						n = Cards[ColumnSelected][n];
					}
					else
					{
						n = SpaceLeft[ColumnSelected-8];
					}

					if (n == SpaceRight[m] + 4)
						SetCursor (LoadCursor (NULL, IDC_UPARROW));
				}
			}
		}
		else
		{//列
			m = xPos / (nCardWidth + dxCard);
			n = xPos % (nCardWidth + dxCard);
			i = CalcColumnCards (m);

			if (i == -1)
			{//空列
				if ((n > dxCard) && (yPos > nCardHeight+10))
				{
					SetCursor (LoadCursor (NULL, IDC_UPARROW));
				}
			}
			else if ((n > dxCard) && (yPos > nCardHeight+10) && (yPos < nCardHeight+10+dyCard*i+nCardHeight))
			{
				if (ColumnSelected < 8)
				{
					i = CalcColumnCards (ColumnSelected);
					j = i;
					for ( ; j>=0; j--)
					{
						if (!IsMatch (Cards[ColumnSelected][j-1], Cards[ColumnSelected][j]))
							break;
					}
					j = i - j + 1;	//现在 j 中保存着选中列下端有几张按规则排列的牌
					
					//再计算鼠标按下列的最下面一张牌能不能和上面那几张牌
					//中的任意几张牌构成一个新的规则排列
					k = CalcColumnCards (m);
					for (t=0; t<j; t++)
					{
						if (IsMatch (Cards[m][k], Cards[ColumnSelected][i-t]))
							break;
					}

					if (t != j)
					{
						t++;
						if (CalcSpaceAll(FALSE) >= t)
						{//空当够用
							SetCursor (LoadCursor (hInst, MAKEINTRESOURCE(IDC_DOWNARROW)));
						}
					}
				}
				else
				{
					if (IsMatch (Cards[m][i], SpaceLeft[ColumnSelected-8]))
						SetCursor (LoadCursor (hInst, MAKEINTRESOURCE(IDC_DOWNARROW)));
				}
			}
		}
	}
}

//处理 WM_LBUTTONDOWN 消息/////////////////////////////////////////////////////
void OnLbuttonDown (HWND hWnd, int xPos, int yPos)
{
	int	m, n, i, j, k, t;
	char	buf[80];

	m = xPos / (nCardWidth + dxCard);
	n = xPos % (nCardWidth + dxCard);

	if ((yPos < nCardHeight) && (xPos < 4*nCardWidth))
	{//鼠标落在左边空当上
		m = xPos / nCardWidth;

		if (ColumnSelected == -1)
		{//当前没有选中任何牌
			if (SpaceLeft[m] != -1)
			{//鼠标按下点的空当有牌
				ColumnSelected = m + 8;
				DrawSpaceLeft (GetDC (hWnd));
			}
		}
		else
		{//当前已经选中了某一列牌
			if (ColumnSelected == m+8)
			{//如果再次选中这一空当,则取消该列的选中状态
				ColumnSelected = -1;
				DrawSpaceLeft (GetDC (hWnd));
			}
			else
			{
				if (SpaceLeft[m] == -1)

⌨️ 快捷键说明

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