?? mainform1.~cpp
字號(hào):
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "MainForm1.h"
#include "EditForm2.h"
#include "InfoForm3.h"
#include "ChessErr.h"
#include "InputPlyDepth.h"
#include "InputSecPerMove.h"
#include "InputMinPerGame.h"
#include "EndGameDlog.h"
#include "AboutDlog.h"
#include "ColorDlog.h"
#include "PieceValueDlog.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "CDefines.h"
#include "Global.h"
#undef MAXPATH
#define MAXPATH 160
/*
* 全局變量
*/
BYTE ColorSquareColors[3] = { 0, 128, 0 }; /* 綠色 */
bool ShowBestPath = true;
HBRUSH hColorBrush;
HBITMAP PieceBmpArray[7][2];
HBITMAP MaskArray[7];
COLORTYPE ComputerColor;
short LINESIZE;
short CHARSIZE;
bool Editing;
int BORDERSIZE;
bool SoundOn;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
/*
在 #pragma資源聲明里,加入包含定制光標(biāo)的資源文件MyRc.res。
*/
#pragma resource "Chess.res"
#pragma resource "MyRc.res"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
/*
主Form必須負(fù)責(zé)創(chuàng)建子Form,前面兩行分別創(chuàng)建了兩個(gè)子Form,接下來的兩行
將這些子Form放到一個(gè)數(shù)組中。然后,通過一個(gè)循環(huán)依次顯示這些子Form。
使用這項(xiàng)技術(shù)時(shí),不要讓系統(tǒng)自動(dòng)創(chuàng)建這些子Form。為此,需要打開
“Project Options”對(duì)話框,翻到“Form”頁(yè),然后將這些子Form
從列表框移到“Available Forms”列表框中。
*/
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
InfoForm = new TInfoForm(this);
EditForm = new TEditForm(this);
ChildForms[1] = EditForm;
ChildForms[2] = InfoForm;
for (int i=1;i<3;i++)
ChildForms[i]->Show();
SoundOn = true;
FileName = new char[MAXPATH];
WhoseTurn = player;
CurPlayer = red;
ComputerColor = black;
Editing = EditingChessBoard = GotStartSquare = false;
blNewChessGame = true;
}
CheckLevelMenu(LEVELTYPE);
//---------------------------------------------------------------------------
/*
這是主窗體顯示時(shí)事件處理函數(shù)
從資源文件載入光標(biāo)及位圖
由于光標(biāo)及位圖保存在資源文件(.res)內(nèi)有兩個(gè)好處。第一,它可以包含不同類型
的多種資源。第二,C++ Builder可以方便地把一個(gè)資源文件連接入最后的可執(zhí)行
文件。
"::"在變量前表明該變量是全局(外部)變量,
在函數(shù)前表明該函數(shù)是全局(外部)函數(shù)。
*/
void __fastcall TMainForm::FormShow(TObject *Sender)
{
HDC hDC;
hDC = GetDC(MainForm->Handle);
TEXTMETRIC tm;
GetTextMetrics(hDC, &tm);
CHARSIZE = short(tm.tmAveCharWidth);
LINESIZE = short(tm.tmHeight + tm.tmExternalLeading);
ReleaseDC(MainForm->Handle, hDC);
BORDERSIZE = LINESIZE + MYFRAMESIZE;
if ((GetSystemMetrics(SM_CXSCREEN)<800) || (GetSystemMetrics(SM_CYSCREEN)<600))
MessageBox(NULL,"屏幕分辯率低于800X600!","警告",
MB_ICONINFORMATION | MB_OK);
Screen->Cursors[crWaitCursor]=LoadCursor(HInstance, "IDC_WCUR");
//把自定義光標(biāo)裝入Screen對(duì)象
::PieceBmpArray[pawn-1][red]=LoadBitmap(HInstance, "RPawnBmp");
::PieceBmpArray[pawn-1][black] = LoadBitmap(HInstance, "BPawnBmp");
::PieceBmpArray[rook-1][red] = LoadBitmap(HInstance, "RRookBmp");
::PieceBmpArray[rook-1][black] = LoadBitmap(HInstance, "BRookBmp");
::PieceBmpArray[knight-1][black] = LoadBitmap(HInstance, "BKnightBmp");
::PieceBmpArray[bishop-1][black] = LoadBitmap(HInstance, "BBishopBmp");
::PieceBmpArray[assist-1][black] = LoadBitmap(HInstance, "BAssistBmp");
::PieceBmpArray[gunner-1][black] = LoadBitmap(HInstance, "BGunnerBmp");
::PieceBmpArray[knight-1][red] = LoadBitmap(HInstance, "RKnightBmp");
::PieceBmpArray[bishop-1][red] = LoadBitmap(HInstance, "RBishopBmp");
::PieceBmpArray[assist-1][red] = LoadBitmap(HInstance, "RAssistBmp");
::PieceBmpArray[gunner-1][red] = LoadBitmap(HInstance, "RGunnerBmp");
::PieceBmpArray[king-1][red] = LoadBitmap(HInstance, "RKingBmp");
::PieceBmpArray[king-1][black] = LoadBitmap(HInstance, "BKingBmp");
::MaskArray[pawn-1] = LoadBitmap(HInstance, "PMaskBmp");
::MaskArray[rook-1] = LoadBitmap(HInstance, "RMaskBmp");
::MaskArray[knight-1] = LoadBitmap(HInstance, "KTMaskBmp");
::MaskArray[bishop-1] = LoadBitmap(HInstance, "BMaskBmp");
::MaskArray[assist-1] = LoadBitmap(HInstance, "AMaskBmp");
::MaskArray[gunner-1] = LoadBitmap(HInstance, "GMaskBmp");
::MaskArray[king-1] = LoadBitmap(HInstance, "KMaskBmp");
MainWndRect= MainForm->GetClientRect();
MainForm->Menu=TChessMenu; //設(shè)置主窗體主菜單
Talk();
MainForm->CheckLevelMenu(Level);
hColorBrush = CreateSolidBrush(
RGB(ColorSquareColors[0], ColorSquareColors[1], ColorSquareColors[2]));
Dragging = true;
Screen->Cursor = TCursor(crArrow); //分配箭頭光標(biāo)給應(yīng)用程序
ChildForms[2]->BringToFront();
}
//---------------------------------------------------------------------------
/*
設(shè)置主窗體背景
通過文件方式載入位圖。
對(duì)于位圖沒有保存在資源文件(.res)內(nèi),C++ Builder不能把從文件裝入的位圖
連接入最后的可執(zhí)行文件。因此,必須確保在c:\BcbChess下有必需的位圖文件。
很明顯,使用VCL函數(shù)比原始的API函數(shù)要方便得多。使用后,
應(yīng)將Canvas->Brush->Bitmap這個(gè)特性設(shè)為NULL,以釋放位圖。
如果不刪除位圖,將導(dǎo)致程序內(nèi)存不足。
*/
void TMainForm::SetMainWindowBk()
{
Graphics::TBitmap *BLKBrushBmp = new Graphics::TBitmap();
BLKBrushBmp->LoadFromFile("e:\\BKBrush.bmp");
//BLKBrushBmp->LoadFromFile("c:\\BcbChess\\BKBrush.bmp");
MainForm->Canvas->Brush->Bitmap=BLKBrushBmp;
MainForm->Canvas->FillRect(MainForm->GetClientRect());
MainForm->Canvas->Brush->Bitmap=NULL;
delete BLKBrushBmp;
}
//---------------------------------------------------------------------------
/*
主窗體重畫事件處理函數(shù)
ReleaseDC函數(shù)釋放設(shè)備描述句柄,不然,會(huì)導(dǎo)致系統(tǒng)資源不足
*/
void __fastcall TMainForm::FormPaint(TObject *Sender)
{
SetMainWindowBk();
HDC PaintDC = GetDC(MainForm->Handle);
DrawFrame(PaintDC, MainWndRect);
ReleaseDC(MainForm->Handle, PaintDC);
PaintDC = GetDC(InfoForm->Handle);
DrawFrame(PaintDC, InfoAreaRect);
ReleaseDC(InfoForm->Handle, PaintDC);
PrintChessBoard();
}
//---------------------------------------------------------------------------
/*
鼠標(biāo)按下時(shí)事件處理函數(shù)
對(duì)弈狀態(tài)時(shí),按下左鼠標(biāo),可以抓住棋子進(jìn)行移動(dòng),第二次按下時(shí),釋放棋子。
編輯狀態(tài)時(shí),按下左鼠標(biāo),可以使編輯窗體中的棋子透明顯示,第二次在主窗體按下時(shí),
可以添加棋子,再按擊時(shí),擦除棋子。
*/
void __fastcall TMainForm::FormMouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
POINT point;
if (Button != mbLeft)
return;
MouseX=X;
MouseY=Y;
if (EditingChessBoard)
{
DoEdit();
return;
}
if (WhoseTurn == computer && NoComputerMove == false)
return;
point=Point(MouseX,MouseY);
MainForm->ScreenToClient( point);
if (!GotStartSquare)
{
MoveStartSquare = GetValidSquare(point, CurPlayer, true);
if (MoveStartSquare == -1)
return;
GotStartSquare = true;
if (!Dragging)
DrawInvertedBitmap(MoveStartSquare);
else
DragStart(MoveStartSquare, point);
}
else
{
MoveEndSquare = GetValidSquare(point, CurPlayer, false);
GotStartSquare = false;
if (MoveEndSquare == -1)
{
if (Dragging)
DragEnd(false);
Warning("錯(cuò)誤的移動(dòng)!");
DrawNormalBitmap(MoveStartSquare);
return;
}
if (!MoveCheck(MoveStartSquare, MoveEndSquare))
{
if (Dragging)
DragEnd(false);
DrawNormalBitmap(MoveStartSquare);
return;
}
GotValidMove = true;
UndoMove->Enabled = true;
if (GameOver)
EndGame();
else if (NoComputerMove == false)
ComputersTurn();
else if (MultiMove)
{
CurPlayer = (CurPlayer == red) ? black : red;
}
}
}
//---------------------------------------------------------------------------
/*
輪到計(jì)算機(jī)計(jì)算時(shí)的回調(diào)函數(shù)。
程序處于機(jī)器控制狀態(tài)。主菜單發(fā)生改變。光標(biāo)發(fā)生改變。
*/
void TMainForm::ComputersTurn()
{
WhoseTurn = computer;
Screen->Cursor =TCursor(crWaitCursor); //分配等待光標(biāo)給應(yīng)用程序
MainForm->Menu=TChessThinkMenu; //設(shè)置主窗體主菜單
ProgramMove();
MainForm->Menu=TChessMenu; //動(dòng)態(tài)設(shè)置主窗體主菜單
WhoseTurn = player;
Screen->Cursor = TCursor(crArrow); //分配箭頭光標(biāo)給應(yīng)用程序
if (GameOver)
EndGame();
}
//---------------------------------------------------------------------------
/*
主菜單項(xiàng)“新建”事件處理函數(shù)
主窗體進(jìn)入初始對(duì)弈狀態(tài)。同時(shí)清除信息窗體中的提示信息。
*/
void __fastcall TMainForm::NewChessGame1Click(TObject *Sender)
{
Timer1->Enabled=false;
InfoForm->Timer->Caption="時(shí)間:";
UndoMove->Enabled = false;
RedoUndo->Enabled = false;
blNewChessGame = true;
NewChessGame();
PrintChessBoard();
CurPlayer = Player;
ComputerColor = Opponent;
}
//---------------------------------------------------------------------------
/*
自定義IDM_FILENEW消息回調(diào)函數(shù)
按擊動(dòng)態(tài)對(duì)話框“Yes”按鈕發(fā)送一個(gè)消息,相當(dāng)于按擊主菜單項(xiàng)“新建”
*/
void TMainForm::FileNew(TMessage &Msg)
{
MainForm->NewChessGame1Click(NewChessGame1);
}
//---------------------------------------------------------------------------
/*
主菜單項(xiàng)“恢復(fù)”事件處理函數(shù)
調(diào)用公用對(duì)話框打開控件函數(shù),讀入二進(jìn)制棋盤文件。
*/
void __fastcall TMainForm::RestoreGame1Click(TObject *Sender)
{
if(OpenDialog1->Execute())
{
blNewChessGame = false;
RestoreGame(MainForm->OpenDialog1->FileName.c_str());
CurPlayer = Player;
ComputerColor = Opponent;
RedoUndo->Enabled = false; //重下菜單變灰
UndoMove->Enabled = false; //悔棋菜單變灰
}
}
//---------------------------------------------------------------------------
/*
自定義函數(shù)
調(diào)用公用對(duì)話框保存控件函數(shù),寫入二進(jìn)制棋盤文件。
*/
void TMainForm::SaveGameAs()
{
if(SaveDialog1->Execute())
{
blNewChessGame=false;
SaveGame(MainForm->SaveDialog1->FileName.c_str());
}
}
//---------------------------------------------------------------------------
/*
主菜單項(xiàng)“保存”事件處理函數(shù)
調(diào)用公用對(duì)話框保存控件函數(shù),寫入二進(jìn)制棋盤文件。
*/
void __fastcall TMainForm::SaveGame1Click(TObject *Sender)
{
if (blNewChessGame == true)
SaveGameAs();
else
SaveGame(MainForm->SaveDialog1->FileName.c_str());
}
//---------------------------------------------------------------------------
/*
主菜單項(xiàng)“另存為...”事件處理函數(shù)
調(diào)用公用對(duì)話框保存控件函數(shù),寫入二進(jìn)制棋盤文件。
*/
void __fastcall TMainForm::SaveGameAsClick(TObject *Sender)
{
SaveGameAs();
}
//---------------------------------------------------------------------------
/*
自定義消息IDM_ERROR的回調(diào)函數(shù)
動(dòng)態(tài)構(gòu)造、顯示和刪除ChessErrorDlg。
雖然沒有寫TChessErrorDlg的析構(gòu)函數(shù),但當(dāng)刪除它們的Owner時(shí)VCL自動(dòng)刪除
了控件。如果包含非可視化對(duì)象的指針,則需要增加ChessErrorDlg的析構(gòu)函數(shù)。
*/
void TMainForm::EMError(TMessage &Msg)
{
TChessErrorDlg *ChessErrorDlg= new TChessErrorDlg(Application,(AnsiString)buffer);
ChessErrorDlg->ShowModal();
delete ChessErrorDlg;
}
/*
主菜單項(xiàng)“關(guān)于”事件處理函數(shù)
調(diào)用自定義靜態(tài)對(duì)話框函數(shù),無模態(tài)顯示版權(quán)信息。
*/
void __fastcall TMainForm::AboutClick(TObject *Sender)
{
AboutDlg->Show();
}
//---------------------------------------------------------------------------
/*
自定義編輯函數(shù)
讀取光標(biāo)位置,把選擇的棋子在主窗體上的合法位置上顯示出來。
*/
void TMainForm::DoEdit()
{
POINT point;
SQUARETYPE Square;
int SelectedItem;
Modified = true;
point=Point(MouseX,MouseY);
MainForm->ScreenToClient(point);
Square = GetValidSquare(point, black, false);
if (ChessBoard[Square].piece != empty)
{
ChessBoard[Square].piece = empty;
UpdateChessBoard();
return;
}
SelectedItem = EditForm->GetSelectedItem();
ChessBoard[Square].piece = (PIECETYPE)(SelectedItem % 7 + 1);
ChessBoard[Square].color = (SelectedItem < 7) ? red : black;
UpdateChessBoard();
}
//---------------------------------------------------------------------------
/*
菜單項(xiàng)“擺子”的回調(diào)函數(shù)。
EditForm->BringToFront()將編輯子窗體EditForm推到前端。
CheckMenuItem第一個(gè)參數(shù)為菜單句柄,從菜單TChessEditMenu句柄屬性Handle獲取。
第二個(gè)參數(shù)告訴菜單項(xiàng)是用命令I(lǐng)D指明的。
第三個(gè)參數(shù)它告訴菜單項(xiàng)是應(yīng)該執(zhí)行哪一些操作。在這種情況下,
MF_CHECKED告訴CheckMenuItem菜單項(xiàng)被打勾。
MF_UNCHECKED告訴CheckMenuItem菜單項(xiàng)勾被取消。
*/
void __fastcall TMainForm::MovePieceClick(TObject *Sender)
{
SaveChessBoard = new BOARDTYPE[0x99];
if (SaveChessBoard == NULL)
{
Error("沒有足夠的內(nèi)存");
return;
}
memcpy(SaveChessBoard, ChessBoard, sizeof(BOARDTYPE) * 0x99);
Editing = EditingChessBoard = true;
MainForm->Menu=TChessEditMenu; //動(dòng)態(tài)設(shè)置主窗體主菜單
Modified = false;
if (CurPlayer == red)
{
CheckMenuItem(TChessEditMenu->Handle, BlackTurn->Command, MF_UNCHECKED);
CheckMenuItem(TChessEditMenu->Handle, RedTurn->Command, MF_CHECKED);
}
else
{
CheckMenuItem(TChessEditMenu->Handle, BlackTurn->Command, MF_CHECKED);
CheckMenuItem(TChessEditMenu->Handle, RedTurn->Command, MF_UNCHECKED);
}
EditForm->BringToFront();
}
//---------------------------------------------------------------------------
/*
主菜單項(xiàng)“清除”事件處理函數(shù)
把主窗體中棋盤上棋子全部擦除。
*/
void __fastcall TMainForm::ClearClick(TObject *Sender)
{
SQUARETYPE sq;
Modified = true;
for (sq = 0; sq <= 0x98; sq++)
ChessBoard[sq].piece = empty;
UpdateChessBoard();
}
//---------------------------------------------------------------------------
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -