📄 tictac1.cpp
字号:
//======================================================================
// TicTac1 - Simple tic-tac-toe game
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <commctrl.h> // Command bar includes
#include "tictac1.h" // Program-specific stuff
//----------------------------------------------------------------------
// Global data
//
const TCHAR szAppName[] = TEXT ("TicTac1");
HINSTANCE hInst; // Program instance handle
// State data for game
RECT rectBoard = {0, 0, 0, 0}; // Used to place game board.
RECT rectPrompt; // Used to place prompt.
BYTE bBoard[9]; // Keeps track of X's and O's.
BYTE bTurn = 0; // Keeps track of the turn.
// Message dispatch table for MainWindowProc
const struct decodeUINT MainMessages[] = {
WM_SIZE, DoSizeMain,
WM_PAINT, DoPaintMain,
WM_LBUTTONUP, DoLButtonUpMain,
WM_DESTROY, DoDestroyMain,
};
//======================================================================
//
// Program entry point
//
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow) {
MSG msg;
HWND hwndMain;
// Initialize this instance.
hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow);
if (hwndMain == 0)
return 0x10;
// Application message loop
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
// Instance cleanup
return TermInstance (hInstance, msg.wParam);
}
//----------------------------------------------------------------------
// InitInstance - Instance initialization
//
HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine, int nCmdShow) {
WNDCLASS wc;
HWND hWnd;
// Save program instance handle in global variable.
hInst = hInstance;
#if defined(WIN32_PLATFORM_PSPC)
// If Pocket PC, allow only one instance of the application.
hWnd = FindWindow (szAppName, NULL);
if (hWnd) {
SetForegroundWindow ((HWND)(((DWORD)hWnd) | 0x01));
return 0;
}
#endif
// Register application main window class.
wc.style = 0; // Window style
wc.lpfnWndProc = MainWndProc; // Callback function
wc.cbClsExtra = 0; // Extra class data
wc.cbWndExtra = 0; // Extra window data
wc.hInstance = hInstance; // Owner handle
wc.hIcon = NULL, // Application icon
wc.hCursor = LoadCursor (NULL, IDC_ARROW);// Default cursor
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = NULL; // Menu name
wc.lpszClassName = szAppName; // Window class name
if (RegisterClass (&wc) == 0) return 0;
// Create main window.
hWnd = CreateWindowEx (WS_EX_NODRAG, szAppName, TEXT ("TicTac1"),
WS_VISIBLE | WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
// Return fail code if window not created.
if (!IsWindow (hWnd)) return 0;
// Standard show and update calls
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
return hWnd;
}
//----------------------------------------------------------------------
// TermInstance - Program cleanup
//
int TermInstance (HINSTANCE hInstance, int nDefRC) {
return nDefRC;
}
//======================================================================
// Message handling procedures for MainWindow
//
//----------------------------------------------------------------------
// MainWndProc - Callback function for application window
//
LRESULT CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
INT i;
//
// Search message list to see if we need to handle this
// message. If in list, call procedure.
//
for (i = 0; i < dim(MainMessages); i++) {
if (wMsg == MainMessages[i].Code)
return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);
}
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
//----------------------------------------------------------------------
// DoSizeMain - Process WM_SIZE message for window.
//
LRESULT DoSizeMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
RECT rect;
INT i;
// Adjust the size of the client rect to take into account
// the command bar height.
GetClientRect (hWnd, &rect);
// Initialize the board rectangle if not yet initialized.
if (rectBoard.right == 0) {
// Initialize the board.
for (i = 0; i < dim(bBoard); i++)
bBoard[i] = 0;
}
// Define the playing board rect.
rectBoard = rect;
rectPrompt = rect;
// Layout depends on portrait or landscape screen.
if (rect.right - rect.left > rect.bottom - rect.top) {
rectBoard.left += 20;
rectBoard.top += 10;
rectBoard.bottom -= 10;
rectBoard.right = rectBoard.bottom - rectBoard.top + 10;
rectPrompt.left = rectBoard.right + 10;
} else {
rectBoard.left += 20;
rectBoard.right -= 20;
rectBoard.top += 10;
rectBoard.bottom = rectBoard.right - rectBoard.left + 10;
rectPrompt.top = rectBoard.bottom + 10;
}
return 0;
}
//----------------------------------------------------------------------
// DoPaintMain - Process WM_PAINT message for window.
//
LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
PAINTSTRUCT ps;
RECT rect;
HFONT hFont, hOldFont;
HDC hdc;
GetClientRect (hWnd, &rect);
hdc = BeginPaint (hWnd, &ps);
// Draw the board.
DrawBoard (hdc, &rectBoard);
// Write the prompt to the screen.
hFont = (HFONT)GetStockObject (SYSTEM_FONT);
hOldFont = (HFONT)SelectObject (hdc, hFont);
if (bTurn == 0)
DrawText (hdc, TEXT (" X's turn"), -1, &rectPrompt,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
else
DrawText (hdc, TEXT (" O's turn"), -1, &rectPrompt,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
SelectObject (hdc, hOldFont);
EndPaint (hWnd, &ps);
return 0;
}
//----------------------------------------------------------------------
// DoLButtonUpMain - Process WM_LBUTTONUP message for window.
//
LRESULT DoLButtonUpMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
POINT pt;
INT cx, cy, nCell = 0;
pt.x = LOWORD (lParam);
pt.y = HIWORD (lParam);
// See if pen on board. If so, determine which cell.
if (PtInRect (&rectBoard, pt)){
// Normalize point to upper left corner of board.
pt.x -= rectBoard.left;
pt.y -= rectBoard.top;
// Compute size of each cell.
cx = (rectBoard.right - rectBoard.left)/3;
cy = (rectBoard.bottom - rectBoard.top)/3;
// Find column.
nCell = (pt.x / cx);
// Find row.
nCell += (pt.y / cy) * 3;
// If cell empty, fill it with mark.
if (bBoard[nCell] == 0) {
if (bTurn) {
bBoard[nCell] = 2;
bTurn = 0;
} else {
bBoard[nCell] = 1;
bTurn = 1;
}
InvalidateRect (hWnd, NULL, FALSE);
} else {
// Inform the user of the filled cell.
MessageBeep (0);
return 0;
}
}
return 0;
}
//----------------------------------------------------------------------
// DoDestroyMain - Process WM_DESTROY message for window.
//
LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
PostQuitMessage (0);
return 0;
}
//======================================================================
// Game-specific routines
//
//----------------------------------------------------------------------
// DrawXO - Draw a single X or O in a square.
//
void DrawXO (HDC hdc, HPEN hPen, RECT *prect, INT nCell, INT nType) {
POINT pt[2];
INT cx, cy;
RECT rect;
cx = (prect->right - prect->left)/3;
cy = (prect->bottom - prect->top)/3;
// Compute the dimensions of the target cell.
rect.left = (cx * (nCell % 3) + prect->left) + 10;
rect.right = rect.right = rect.left + cx - 20;
rect.top = cy * (nCell / 3) + prect->top + 10;
rect.bottom = rect.top + cy - 20;
// Draw an X ?
if (nType == 1) {
pt[0].x = rect.left;
pt[0].y = rect.top;
pt[1].x = rect.right;
pt[1].y = rect.bottom;
Polyline (hdc, pt, 2);
pt[0].x = rect.right;
pt[1].x = rect.left;
Polyline (hdc, pt, 2);
// How about an O ?
} else if (nType == 2) {
Ellipse (hdc, rect.left, rect.top, rect.right, rect.bottom);
}
return;
}
//----------------------------------------------------------------------
// DrawBoard - Draw the tic-tac-toe board.
// VK_MENU
void DrawBoard (HDC hdc, RECT *prect) {
HPEN hPen, hOldPen;
POINT pt[2];
LOGPEN lp;
INT i, cx, cy;
// Create a nice thick pen.
lp.lopnStyle = PS_SOLID;
lp.lopnWidth.x = 5;
lp.lopnWidth.y = 5;
lp.lopnColor = RGB (0, 0, 0);
hPen = CreatePenIndirect (&lp);
hOldPen = (HPEN)SelectObject (hdc, hPen);
cx = (prect->right - prect->left)/3;
cy = (prect->bottom - prect->top)/3;
// Draw lines down.
pt[0].x = cx + prect->left;
pt[1].x = cx + prect->left;
pt[0].y = prect->top;
pt[1].y = prect->bottom;
Polyline (hdc, pt, 2);
pt[0].x += cx;
pt[1].x += cx;
Polyline (hdc, pt, 2);
// Draw lines across.
pt[0].x = prect->left;
pt[1].x = prect->right;
pt[0].y = cy + prect->top;
pt[1].y = cy + prect->top;
Polyline (hdc, pt, 2);
pt[0].y += cy;
pt[1].y += cy;
Polyline (hdc, pt, 2);
// Fill in X's and O's.
for (i = 0; i < dim (bBoard); i++)
DrawXO (hdc, hPen, &rectBoard, i, bBoard[i]);
SelectObject (hdc, hOldPen);
DeleteObject (hPen);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -