高中时候的古董,现在重读,有点累。体会:文档很重要。。。
当初WinXP下开发,现在在Win7下有点变形。
客户端
服务器端
ReadMe.txt(也许可以称之为文档)
1功能:
2网络对战五子棋与网络聊天。
3
4
5开发工具:
6VS2008 中的 C++, 即VC9.0。
7
8
9平台:
10Windows,需VC9.0运行时支持(相关VC *.dll 已放在Release目录下,不需另外安装)。
11
12
13技术:
14WinSock;
15Win32 Api;
16对话框(用Win32 Api 函数处理);
17多线程(用事件内核对象实现共享资源互斥访问);
18用C++类模块化封装,易于维护;
19使用预编译指令,一份代码可编译为服务器端或客户端(由DetermineServerClient.h中的宏SERVER_DEFINED是否定义决定)。
20
21
22注意:
23ServerIP.inf 中放服务器ip地址,服务器先启动。
24Fly_命名.exe 为辅助程序,放在Release或Debug目录下,根据预编译指令将Fly.exe改名为Fly Server.exe 或 Fly Client.exe。
25
26
27不足:
28最近落子无标记。
29无判断输赢模块。
30光标未使用。
31设置功能未加。
32聊天记录框中对方与自己用相同的字体及颜色。
33
34
35
36开发用时近两个星期,其中一个星期多用于边学边写对话框部分。
37
resource.h
1//{{NO_DEPENDENCIES}}
2// Microsoft Visual C++ generated include file.
3// Used by Fly.rc
4//
5#define IDD_DIALOG_MAIN 101
6#define IDB_CHESSBOARD 102
7#define IDB_CHESSMAN_BLACK 103
8#define IDB_CHESSMAN_WHITE 104
9#define IDB_CHESSMAN_MASK 105
10#define IDI_ICON 106
11#define IDC_HAND_BLACK 107
12#define IDC_HAND_WHITE 108
13#define IDC_EDIT_CHAT_INPUT 1001
14#define IDC_EDIT_CHAT_BOARD 1002
15#define IDC_STATIC_CHESSBOARD 1003
16#define IDC_BUTTON_SEND 1004
17#define IDC_BUTTON_ASK_FOR_REPUT_CHESSMAN 1005
18#define IDC_BUTTON_ASK_FOR_NEW_GAME 1006
19#define IDC_BUTTON_CLEAR_CHAT_RECORD 1007
20#define IDC_BUTTON_HELP 1008
21#define IDC_BUTTON_SET 1009
22
23// Next default values for new objects
24//
25#ifdef APSTUDIO_INVOKED
26#ifndef APSTUDIO_READONLY_SYMBOLS
27#define _APS_NEXT_RESOURCE_VALUE 109
28#define _APS_NEXT_COMMAND_VALUE 40001
29#define _APS_NEXT_CONTROL_VALUE 1010
30#define _APS_NEXT_SYMED_VALUE 101
31#endif
32#endif
33
GetServerIP.h
1#ifndef GETSERVERIP_H_INCLUDED
2#define GETSERVERIP_H_INCLUDED
3
4
5#include "winsock2.h"
6#include "fstream"
7using namespace std;
8
9
10IN_ADDR GetServerIP( VOID );
11
12
13#endif
14
GetServerIP.cpp
1#include "GetServerIP.h"
2
3
4IN_ADDR GetServerIP( VOID ){
5 IN_ADDR inaddr;
6 ::memset( &inaddr, 0, sizeof(inaddr) );
7
8 ifstream fin;
9 const int LEN = 20;
10 char szIp[LEN]={0};
11 int i, dots=0;
12 BOOL bOk = 1;
13
14 fin.open( "ServerIP.inf" );
15 if( fin.fail() ){
16 return inaddr;
17 }
18 fin.getline( szIp, LEN-1 );
19 fin.close();
20
21 for( i=0; szIp[i]; ++i ){
22 if( i > 14 ){
23 bOk = 0; break;
24 }
25 if( szIp[i] == '.' ){
26 if( (++dots>3) || (szIp[i+1]=='.') ){
27 bOk = 0; break;
28 }
29 }
30 else{
31 if( (szIp[i]<'0') || ('9'<szIp[i]) ){
32 bOk = 0; break;
33 }
34 }
35 }
36 if( bOk ){
37 inaddr.S_un.S_addr = ::inet_addr( szIp );
38 }
39 return inaddr;
40}
41
Fly.rc
1// Microsoft Visual C++ generated resource script.
2//
3#include "resource.h"
4
5#define APSTUDIO_READONLY_SYMBOLS
6/**////////////////////////////////////////////////////////////////////////////// 7//
8// Generated from the TEXTINCLUDE 2 resource.
9//
10#include "afxres.h"
11
12/**////////////////////////////////////////////////////////////////////////////// 13#undef APSTUDIO_READONLY_SYMBOLS
14
15/**////////////////////////////////////////////////////////////////////////////// 16// Chinese (P.R.C.) resources
17
18#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
19#ifdef _WIN32
20LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
21#pragma code_page(936)
22#endif //_WIN32
23
24#ifdef APSTUDIO_INVOKED
25/**////////////////////////////////////////////////////////////////////////////// 26//
27// TEXTINCLUDE
28//
29
301 TEXTINCLUDE
31BEGIN
32 "resource.h\0"
33END
34
352 TEXTINCLUDE
36BEGIN
37 "#include ""afxres.h""\r\n"
38 "\0"
39END
40
413 TEXTINCLUDE
42BEGIN
43 "\r\n"
44 "\0"
45END
46
47#endif // APSTUDIO_INVOKED
48
49
50/**////////////////////////////////////////////////////////////////////////////// 51//
52// Dialog
53//
54
55IDD_DIALOG_MAIN DIALOGEX 0, 0, 587, 343
56STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
57EXSTYLE WS_EX_CLIENTEDGE | WS_EX_STATICEDGE
58FONT 9, "楷体_GB2312", 400, 0, 0x86
59BEGIN
60 CONTROL "",IDC_STATIC_CHESSBOARD,"Static",SS_OWNERDRAW | SS_NOTIFY | SS_SUNKEN | WS_BORDER,8,8,304,304,WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE
61 EDITTEXT IDC_EDIT_CHAT_BOARD,322,8,257,200,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | ES_WANTRETURN | WS_VSCROLL | NOT WS_TABSTOP,WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE
62 EDITTEXT IDC_EDIT_CHAT_INPUT,322,216,257,96,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL | NOT WS_TABSTOP,WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE
63 PUSHBUTTON "发送",IDC_BUTTON_SEND,517,322,50,14,BS_CENTER | BS_VCENTER | NOT WS_TABSTOP
64 PUSHBUTTON "请求悔棋",IDC_BUTTON_ASK_FOR_REPUT_CHESSMAN,21,322,50,14,BS_CENTER | BS_VCENTER | NOT WS_TABSTOP
65 PUSHBUTTON "请求新开一局",IDC_BUTTON_ASK_FOR_NEW_GAME,79,322,67,14,BS_CENTER | BS_VCENTER | NOT WS_TABSTOP
66 PUSHBUTTON "清除聊天记录",IDC_BUTTON_CLEAR_CHAT_RECORD,439,322,67,14,BS_CENTER | BS_VCENTER | NOT WS_TABSTOP
67 PUSHBUTTON "帮助",IDC_BUTTON_HELP,229,322,50,14,BS_CENTER | BS_VCENTER | NOT WS_TABSTOP
68 PUSHBUTTON "设置",IDC_BUTTON_SET,297,322,50,14,BS_CENTER | BS_VCENTER | NOT WS_TABSTOP
69END
70
71
72/**////////////////////////////////////////////////////////////////////////////// 73//
74// DESIGNINFO
75//
76
77#ifdef APSTUDIO_INVOKED
78GUIDELINES DESIGNINFO
79BEGIN
80 IDD_DIALOG_MAIN, DIALOG
81 BEGIN
82 LEFTMARGIN, 8
83 RIGHTMARGIN, 579
84 TOPMARGIN, 8
85 BOTTOMMARGIN, 336
86 END
87END
88#endif // APSTUDIO_INVOKED
89
90
91/**////////////////////////////////////////////////////////////////////////////// 92//
93// Bitmap
94//
95
96IDB_CHESSBOARD BITMAP "Resource\\Chessboard.bmp"
97IDB_CHESSMAN_BLACK BITMAP "Resource\\ChessmanBlack.bmp"
98IDB_CHESSMAN_WHITE BITMAP "Resource\\ChessmanWhite.bmp"
99IDB_CHESSMAN_MASK BITMAP "Resource\\ChessmanMask.bmp"
100
101/**//////////////////////////////////////////////////////////////////////////////102//
103// Icon
104//
105
106// Icon with lowest ID value placed first to ensure application icon
107// remains consistent on all systems.
108IDI_ICON ICON "Resource\\Icon.ico"
109
110/**//////////////////////////////////////////////////////////////////////////////111//
112// Cursor
113//
114
115IDC_HAND_BLACK CURSOR "Resource\\HandBlack.cur"
116IDC_HAND_WHITE CURSOR "Resource\\HandWhite.cur"
117#endif // Chinese (P.R.C.) resources
118/**//////////////////////////////////////////////////////////////////////////////119
120
121
122#ifndef APSTUDIO_INVOKED
123/**//////////////////////////////////////////////////////////////////////////////124//
125// Generated from the TEXTINCLUDE 3 resource.
126//
127
128
129/**//////////////////////////////////////////////////////////////////////////////130#endif // not APSTUDIO_INVOKED
131
132
Fly.cpp
1#include "resource.h"
2#include "winsock2.h"
3#include "windowsx.h"
4#include "process.h"
5
6#include "DetermineServerClient.h"
7#include "ChessCommon.h"
8#include "CMutexString.h"
9#include "CChessPainter.h"
10#include "CClientServer.h"
11
12
13#pragma comment( lib, "ws2_32.lib" )
14
15
16#ifdef SERVER_DEFINED
17#define CHESS_TYPE_PLAYER CHESS_TYPE_WHITE
18#define CHESS_TYPE_ENEMY CHESS_TYPE_BLACK
19#define MAIN_NAME TEXT(" Fly --- 服务器端")
20#else
21#define CHESS_TYPE_PLAYER CHESS_TYPE_BLACK
22#define CHESS_TYPE_ENEMY CHESS_TYPE_WHITE
23#define MAIN_NAME TEXT(" Fly --- 客户端")
24#endif
25
26//--------------------------------------------------------------------------------------------------------
27HWND hDialog = 0;
28CMutexString ms;
29CClientServer cs;
30
31//--------------------------------------------------------------------------------------------------------
32UINT __stdcall DealCmdReceived( LPVOID ){
33 ::PostMessage( hDialog, WM_NET_STATE, WPARAM_INIT_ING, 0 );
34 if( ! cs.Initialize() ){
35 ::PostMessage( hDialog, WM_NET_STATE, WPARAM_INIT_FAILED, 0 );
36 return 0;
37 }
38 ::PostMessage( hDialog, WM_NET_STATE, WPARAM_INIT_SUCCEEDED, 0 );
39
40 DWORD dwCmdType, dwPos;
41 char CmdParam[CMD_PARAM_LEN+2];
42 int cbParam;
43 while( cs.ReceiveCmd( dwCmdType, CmdParam, cbParam ) ){
44 switch( dwCmdType ){
45 case CMD_PUT_CHESSMAN :
46 ::CWsData::CharToDwordHL( CmdParam, dwPos );
47 ::PostMessage( hDialog, WM_CHESSMAN, WPARAM_PUT_ENEMY_CHESSMAN, dwPos );
48 break;
49 case CMD_CHAT_WORDS_CONTINUE :
50 CmdParam[cbParam+1] = CmdParam[cbParam] = 0;
51 ms.AppendString( LPCTSTR(CmdParam), 0 );
52 ::PostMessage( hDialog, WM_CHAT_WORDS, WPARAM_CHAT_WORDS_RECV_CONTINUE, 0 );
53 break;
54 case CMD_CHAT_WORDS :
55 CmdParam[cbParam+1] = CmdParam[cbParam] = 0;
56 ms.AppendString( LPCTSTR(CmdParam) );
57 ::PostMessage( hDialog, WM_CHAT_WORDS, WPARAM_CHAT_WORDS_RECV, 0 );
58 break;
59 case CMD_ASK_FOR_REPUT_CHESSMAN :
60 ::PostMessage( hDialog, WM_CHESSMAN, WPARAM_ENEMY_ASK_FOR_REPUT_CHESSMAN, 0 );
61 break;
62 case CMD_AGREE_REPUT_CHESSMAN :
63 ::PostMessage( hDialog, WM_CHESSMAN, WPARAM_ENEMY_AGREE_REPUT_CHESSMAN, 0 );
64 break;
65 case CMD_DISAGREE_REPUT_CHESSMAN :
66 ::PostMessage( hDialog, WM_CHESSMAN, WPARAM_ENEMY_DISAGREE_REPUT_CHESSMAN, 0 );
67 break;
68 case CMD_ASK_FOR_NEW_GAME :
69 ::PostMessage( hDialog, WM_GAME, WPARAM_ENEMY_ASK_FOR_NEW_GAME, 0 );
70 break;
71 case CMD_AGREE_NEW_GAME :
72 ::PostMessage( hDialog, WM_GAME, WPARAM_ENEMY_AGREE_NEW_GAME, 0 );
73 break;
74 case CMD_DISAGREE_NEW_GAME :
75 ::PostMessage( hDialog, WM_GAME, WPARAM_ENEMY_DISAGREE_NEW_GAME, 0 );
76 break;
77 case CMD_BYE :
78 ::PostMessage( hDialog, WM_BYE, WPARAM_BYE_RECV, 0 );
79 return 0;
80 }
81 }
82 ::PostMessage( hDialog, WM_NET_STATE, WPARAM_ERROR, 0 );
83 return 0;
84}
85
86//--------------------------------------------------------------------------------------------------------
87INT_PTR CALLBACK DialogMainProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ){
88 static const int MAX_LEN = 1024 * 31;
89 static TCHAR szText[MAX_LEN];
90 static UINT uLength;
91 static CChessPainter cp;
92 static TSTRING ts;
93 static int ix, iy, result;
94 static BOOL bCantPutChessman = 0, bShouldSendBye = 1;
95 static BOOL bCanReputChessman = 0, bCanNewGame = 0, bCanSend = 0, bCanClear = 0;
96 static HWND hwndChessboard = 0;
97 static DWORD dwPos;
98 static POINT pt;
99 static HFONT hFont = 0;
100 static HICON hIcon = 0;
101
102 switch( uMsg ){
103 case WM_CHESSMAN :
104 switch( wParam ){
105 case WPARAM_PUT_PLAYER_CHESSMAN :
106 if( bCantPutChessman ){
107 return 1;
108 }
109 ix = GET_X_LPARAM(lParam);
110 iy = GET_Y_LPARAM(lParam);
111 if( cp.PutChessman( ix, iy, CHESS_TYPE_PLAYER ) ){
112 bCantPutChessman = 1;
113 if( ! bCanReputChessman ){
114 bCanReputChessman = 1;
115 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_ASK_FOR_REPUT_CHESSMAN ), 1 );
116 }
117 if( ! bCanNewGame ){
118 bCanNewGame = 1;
119 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_ASK_FOR_NEW_GAME ), 1 );
120 }
121 if( cs.SendCmd_PutChessman( ix, iy ) ){
122 cp.PaintChess( hwndChessboard );
123 }
124 else{
125 ::SendMessage( hDlg, WM_NET_STATE, WPARAM_ERROR, 0 );
126 }
127 }
128 return 1;
129 case WPARAM_PUT_ENEMY_CHESSMAN :
130 ix = GET_X_LPARAM(lParam);
131 iy = GET_Y_LPARAM(lParam);
132 if( cp.PutChessman( ix, iy, CHESS_TYPE_ENEMY ) ){
133 bCantPutChessman = 0;
134 if( ! bCanReputChessman ){
135 bCanReputChessman = 1;
136 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_ASK_FOR_REPUT_CHESSMAN ), 1 );
137 }
138 if( ! bCanNewGame ){
139 bCanNewGame = 1;
140 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_ASK_FOR_NEW_GAME ), 1 );
141 }
142 cp.PaintChess( hwndChessboard );
143 }
144 return 1;
145 case WPARAM_PLAYER_ASK_FOR_REPUT_CHESSMAN :
146 if( ! cs.SendCmd_AskForReputChessman() ){
147 ::SendMessage( hDlg, WM_NET_STATE, WPARAM_ERROR, 0 );
148 }
149 return 1;
150 case WPARAM_ENEMY_ASK_FOR_REPUT_CHESSMAN :
151 result = ::MessageBox( hDlg, TEXT("同意我悔棋吗?"), TEXT("对方发出悔棋请求"), MB_YESNO | MB_ICONQUESTION );
152 if( result == IDYES ){
153 if( cs.SendCmd_AgreeReputChessman() ){
154 bCanReputChessman = 0;
155 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_ASK_FOR_REPUT_CHESSMAN ), 0 );
156 ::SendMessage( hDlg, WM_CHESSMAN, WPARAM_ENEMY_AGREE_REPUT_CHESSMAN, 0 );
157 }
158 else{
159 ::SendMessage( hDlg, WM_NET_STATE, WPARAM_ERROR, 0 );
160 }
161 }
162 else{
163 if( ! cs.SendCmd_DisgreeReputChessman() ){
164 ::SendMessage( hDlg, WM_NET_STATE, WPARAM_ERROR, 0 );
165 }
166 }
167 return 1;
168 case WPARAM_ENEMY_AGREE_REPUT_CHESSMAN :
169 if( cp.EraseLastChessman( 1 ) ){
170 bCantPutChessman = ! bCantPutChessman;
171 if( (cp.GetTotChessmanPut()==0) && (bCanNewGame) ){
172 bCanNewGame = 0;
173 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_ASK_FOR_NEW_GAME ), 0 );
174 }
175 cp.PaintChess( hwndChessboard );
176 }
177 return 1;
178 case WPARAM_ENEMY_DISAGREE_REPUT_CHESSMAN :
179 ::MessageBox( hDlg, TEXT("对方不同意悔棋"), TEXT("提示"), MB_OK );
180 return 1;
181 }
182 return 1;
183
184 case WM_CHAT_WORDS :
185 switch( wParam ){
186 case WPARAM_CHAT_WORDS_SEND :
187 uLength = ::GetDlgItemText( hDlg, IDC_EDIT_CHAT_INPUT, szText, MAX_LEN );
188 if( uLength <= 0 ){
189 return 1;
190 }
191 if( ! cs.SendCmd_ChatWords( (char*)szText, uLength*sizeof(TCHAR) ) ){
192 ::SendMessage( hDlg, WM_NET_STATE, WPARAM_ERROR, 0 );
193 }
194 ::SetDlgItemText( hDlg, IDC_EDIT_CHAT_INPUT, TEXT("") );
195 ms.AppendGetString( ts, szText );
196 ::SetDlgItemText( hDlg, IDC_EDIT_CHAT_BOARD, ts.c_str() );
197 if( ! bCanClear ){
198 bCanClear = 1;
199 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_CLEAR_CHAT_RECORD ), 1 );
200 }
201 return 1;
202 case WPARAM_CHAT_WORDS_RECV_CONTINUE :
203 return 1;
204 case WPARAM_CHAT_WORDS_RECV :
205 ms.GetString( ts );
206 if( ts.length() <= 0 ){
207 return 1;
208 }
209 ::SetDlgItemText( hDlg, IDC_EDIT_CHAT_BOARD, ts.c_str() );
210 if( ! bCanClear ){
211 bCanClear = 1;
212 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_CLEAR_CHAT_RECORD ), 1 );
213 }
214 return 1;
215 }
216 return 1;
217
218 case WM_COMMAND :
219 switch ( LOWORD( wParam ) ){
220 case IDC_BUTTON_ASK_FOR_REPUT_CHESSMAN :
221 bCanReputChessman = 0;
222 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_ASK_FOR_REPUT_CHESSMAN ), 0 );
223 ::SendMessage( hDlg, WM_CHESSMAN, WPARAM_PLAYER_ASK_FOR_REPUT_CHESSMAN, 0 );
224 return 1;
225 case IDC_BUTTON_ASK_FOR_NEW_GAME :
226 bCanNewGame = 0;
227 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_ASK_FOR_NEW_GAME ), 0 );
228 ::SendMessage( hDlg, WM_GAME, WPARAM_PLAYER_ASK_FOR_NEW_GAME, 0 );
229 return 1;
230 case IDC_BUTTON_HELP :
231::MessageBox( hDlg, TEXT("\
232目前没有帮助信息\n\
233\n\n\n\
234********************\n\
235**** 作者:赵杰 ****\n\
236********************\n\
237"), TEXT("帮助"), MB_OK );
238 return 1;
239 case IDC_BUTTON_SET :
240 ::MessageBox( hDlg, TEXT("尚未增加此功能"), TEXT("设置"), MB_OK );
241 return 1;
242 case IDC_BUTTON_CLEAR_CHAT_RECORD :
243 ms.ClearString();
244 bCanClear = 0;
245 ::EnableWindow( (HWND)lParam, 0 );
246 ::SetDlgItemText( hDlg, IDC_EDIT_CHAT_BOARD, TEXT("") );
247 return 1;
248 case IDC_BUTTON_SEND :
249 bCanSend = 0;
250 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_SEND ), 0 );
251 ::SendMessage( hDlg, WM_CHAT_WORDS, WPARAM_CHAT_WORDS_SEND, 0 );
252 return 1;
253 case IDC_STATIC_CHESSBOARD :
254 switch( HIWORD(wParam) ){
255 case STN_CLICKED :
256 dwPos = ::GetMessagePos();
257 pt.x = GET_X_LPARAM( dwPos );
258 pt.y = GET_Y_LPARAM( dwPos );
259 ::ScreenToClient( hwndChessboard, &pt );
260 cp.PosClientToBoard( pt.x, pt.y, ix, iy );
261 ::SendMessage( hDlg, WM_CHESSMAN, WPARAM_PUT_PLAYER_CHESSMAN, MAKELPARAM(ix,iy) );
262 return 1;
263 }
264 return 0;
265 case IDC_EDIT_CHAT_INPUT :
266 switch( HIWORD(wParam) ){
267 case EN_UPDATE :
268 result = ::GetWindowTextLength( ::GetDlgItem(hDlg,IDC_EDIT_CHAT_INPUT) );
269 if( result <= 0 ){
270 if( bCanSend ){
271 bCanSend = 0;
272 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_SEND ), 0 );
273 }
274 }
275 else{
276 if( ! bCanSend ){
277 bCanSend = 1;
278 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_SEND ), 1 );
279 }
280 }
281 return 1;
282 }
283 return 0;
284 }
285 return 0;
286
287 case WM_DRAWITEM :
288 cp.PaintChess( LPDRAWITEMSTRUCT(lParam)->hDC );
289 return 1;
290
291 case WM_NET_STATE :
292 switch( wParam ){
293 case WPARAM_INIT_ING :
294 ms.AppendString( TEXT("正在等待连接") );
295 ::SendMessage( hDlg, WM_CHAT_WORDS, WPARAM_CHAT_WORDS_RECV, 0 );
296 return 1;
297 case WPARAM_INIT_FAILED :
298 bShouldSendBye = 0;
299 ::MessageBox( hDlg, TEXT("连接失败"), TEXT("提示"), MB_OK );
300 ::PostMessage( hDlg, WM_CLOSE, 0, 0 );
301 return 1;
302 case WPARAM_INIT_SUCCEEDED :
303 ms.AppendString( TEXT("连接成功") );
304 ::SendMessage( hDlg, WM_CHAT_WORDS, WPARAM_CHAT_WORDS_RECV, 0 );
305 return 1;
306 case WPARAM_ERROR :
307 bShouldSendBye = 0;
308 ::MessageBox( hDlg, TEXT("未连接"), TEXT("提示"), MB_OK );
309 ::PostMessage( hDlg, WM_CLOSE, 0, 0 );
310 return 1;
311 }
312 return 1;
313
314 case WM_GAME :
315 switch( wParam ){
316 case WPARAM_PLAYER_ASK_FOR_NEW_GAME :
317 if( ! cs.SendCmd_AskForNewGame() ){
318 ::SendMessage( hDlg, WM_NET_STATE, WPARAM_ERROR, 0 );
319 }
320 return 1;
321 case WPARAM_ENEMY_ASK_FOR_NEW_GAME :
322 result = ::MessageBox( hDlg, TEXT("同意新开一局吗?"), TEXT("对方发出新开一局请求"), MB_YESNO | MB_ICONQUESTION );
323 if( result == IDYES ){
324 if( cs.SendCmd_AgreeNewGame() ){
325 bCanNewGame = 0;
326 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_ASK_FOR_NEW_GAME ), 0 );
327 ::SendMessage( hDlg, WM_GAME, WPARAM_ENEMY_AGREE_NEW_GAME, 0 );
328 }
329 else{
330 ::SendMessage( hDlg, WM_NET_STATE, WPARAM_ERROR, 0 );
331 }
332 }
333 else{
334 if( ! cs.SendCmd_DisgreeNewGame() ){
335 ::SendMessage( hDlg, WM_NET_STATE, WPARAM_ERROR, 0 );
336 }
337 }
338 return 1;
339 case WPARAM_ENEMY_AGREE_NEW_GAME :
340 bCantPutChessman = 0;
341 cp.ClearChessboard();
342 cp.PaintChess( hwndChessboard );
343 if( bCanReputChessman ){
344 bCanReputChessman = 0;
345 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_ASK_FOR_REPUT_CHESSMAN ), 0 );
346 }
347 return 1;
348 case WPARAM_ENEMY_DISAGREE_NEW_GAME :
349 ::MessageBox( hDlg, TEXT("对方不同意新开一局"), TEXT("提示"), MB_OK );
350 return 1;
351 }
352 return 1;
353
354 case WM_BYE :
355 switch( wParam ){
356 case WPARAM_BYE_SEND :
357 if( ! cs.SendCmd_Bye() ){
358 ::SendMessage( hDlg, WM_NET_STATE, WPARAM_ERROR, 0 );
359 }
360 bShouldSendBye = 0;
361 ::PostMessage( hDlg, WM_CLOSE, 0, 0 );
362 return 1;
363 case WPARAM_BYE_RECV :
364 bShouldSendBye = 0;
365 ::MessageBox( hDlg, TEXT("对方断开连接"), TEXT("提示"), MB_OK );
366 ::PostMessage( hDlg, WM_CLOSE, 0, 0 );
367 return 1;
368 }
369 return 1;
370
371 case WM_INITDIALOG :
372 ::CloseHandle( (HANDLE)::_beginthreadex( 0, 0, ::DealCmdReceived, 0, 0, 0 ) );
373 hDialog = hDlg;
374 hwndChessboard = ::GetDlgItem( hDlg, IDC_STATIC_CHESSBOARD );
375 ::SetWindowText( hDlg, MAIN_NAME );
376 {
377 HWND hWnd;
378 ::LOGFONT lf;
379 hWnd = ::GetDlgItem( hDlg, IDC_EDIT_CHAT_INPUT );
380 ::GetObject( GetWindowFont(hWnd), sizeof(lf), &lf );
381 lf.lfHeight = lf.lfHeight * 9 / 5;
382 lf.lfWeight = lf.lfWeight * 9 / 5;
383 hFont = ::CreateFontIndirect( &lf );
384 SetWindowFont( hWnd, hFont, 0 );
385 SetWindowFont( ::GetDlgItem( hDlg, IDC_EDIT_CHAT_BOARD ), hFont, 0 );
386 }
387 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_ASK_FOR_REPUT_CHESSMAN ), 0 );
388 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_ASK_FOR_NEW_GAME ), 0 );
389 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_SEND ), 0 );
390 ::EnableWindow( ::GetDlgItem( hDlg, IDC_BUTTON_CLEAR_CHAT_RECORD ), 0 );
391 hIcon = ::LoadIcon( ::GetModuleHandle(0), MAKEINTRESOURCE( IDI_ICON ) );
392 ::SendMessage( hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon );
393 ::SendMessage( hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon );
394 return 1;
395
396 case WM_CLOSE :
397 if( bShouldSendBye ){
398 ::SendMessage( hDlg, WM_BYE, WPARAM_BYE_SEND, 0 );
399 }
400 if( hFont ){
401 ::DeleteFont( hFont );
402 hFont = 0;
403 }
404 if( hIcon ){
405 ::DeleteObject( hIcon );
406 hIcon = 0;
407 }
408 ::EndDialog( hDlg, 0 );
409 return 0;
410 }
411 return 0;
412}
413
414//--------------------------------------------------------------------------------------------------------
415int WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int ){
416 ::DialogBoxParam( hInst, MAKEINTRESOURCE(IDD_DIALOG_MAIN), ::GetDesktopWindow(), ::DialogMainProc, 0 );
417 return 0;
418}
419
DetermineServerClient.h
1#ifndef DETERMINESERVERCLIENT_H_INCLUDED
2#define DETERMINESERVERCLIENT_H_INCLUDED
3
4
5//****************************************************************************
6//****** 若 SERVER_DEFINED 宏定义,则编译为服务器端,否则编译为客户端 ********
7
8//#define SERVER_DEFINED
9
10//****************************************************************************
11
12
13#endif
14
CWsServer.h
1#ifndef CWSSERVER_H_INCLUDED
2#define CWSSERVER_H_INCLUDED
3
4
5#include "winsock2.h"
6
7
8class CWsServer
9{
10public :
11 CWsServer( USHORT portServer );
12 ~CWsServer();
13
14 BOOL ConnectClientServer( SOCKET &socketClient, SOCKADDR_IN *pAddrClient=0 );
15
16private :
17 SOCKET socketServer;
18 BOOL bInitSucceeded;
19};
20
21
22#endif
23
CWsServer.cpp
1#include "CWsServer.h"
2
3
4CWsServer::CWsServer( USHORT portServer ):socketServer(INVALID_SOCKET),bInitSucceeded(0){
5 WSADATA wsaData;
6 SOCKADDR_IN addrServer;
7 if( ::WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) ){
8 return;
9 }
10
11 socketServer = ::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
12 if( socketServer == INVALID_SOCKET ){
13 ::WSACleanup();
14 return;
15 }
16
17 ::memset( &addrServer, 0, sizeof(addrServer) );
18 addrServer.sin_family = AF_INET;
19 addrServer.sin_port = portServer;
20 addrServer.sin_addr.S_un.S_addr = INADDR_ANY;
21 if( ::bind( socketServer, (sockaddr*)&addrServer, sizeof(addrServer) ) ){
22 ::closesocket( socketServer );
23 socketServer = INVALID_SOCKET;
24 ::WSACleanup();
25 return;
26 }
27
28 if( ::listen( socketServer, 1 ) ){
29 ::closesocket( socketServer );
30 socketServer = INVALID_SOCKET;
31 ::WSACleanup();
32 return;
33 }
34
35 bInitSucceeded = 1;
36}
37
38CWsServer::~CWsServer(){
39 if( bInitSucceeded ){
40 ::closesocket( socketServer );
41 socketServer = INVALID_SOCKET;
42 ::WSACleanup();
43 }
44}
45
46
47BOOL CWsServer::ConnectClientServer( SOCKET &socketClient, SOCKADDR_IN *pAddrClient ){
48 if( ! bInitSucceeded ){
49 return 0;
50 }
51 /**//*if( socketClient != INVALID_SOCKET ){
52 return 0;
53 }*/
54 SOCKADDR_IN addrClient;
55 int addrLen = sizeof(addrClient);
56 socketClient = ::accept( socketServer, (sockaddr*)&addrClient, &addrLen );
57 if( socketClient == INVALID_SOCKET ){
58 return 0;
59 }
60 if( pAddrClient ){
61 *pAddrClient = addrClient;
62 }
63 return 1;
64}
65
CWsData.h
1#ifndef CWSDATA_H_INCLUDED
2#define CWSDATA_H_INCLUDED
3
4
5#include "winsock2.h"
6
7
8class CWsData
9{
10public :
11 CWsData();
12 CWsData( SOCKET sok );
13 ~CWsData();
14
15 BOOL SetSocket( BOOL bCloseBeforeSet, SOCKET sok );
16 BOOL SetSocket( SOCKET sok, BOOL bFailIfSetAlready=1 );
17 BOOL IsSetAlready( VOID );
18
19 BOOL ReceiveData( char *pBuf, int cbToRecv );
20 BOOL SendData( const char *pBuf, int cbToSend );
21 BOOL ReceiveDword( DWORD &dw );
22 BOOL SendDword( DWORD dw );
23
24 static BOOL CharToDwordHL( const char *pBuf, DWORD &dw );
25 static BOOL CharToDwordHL( char d3, char d2, char d1, char d0, DWORD &dw );
26 static BOOL DwordToCharHL( DWORD dw, char *pBuf );
27 static BOOL DwordToCharHL( DWORD dw, char &d3, char &d2, char &d1, char &d0 );
28
29private :
30 SOCKET ts;
31};
32
33
34#endif
35
CWsData.cpp
1#include "CWsData.h"
2
3
4CWsData::CWsData():ts(INVALID_SOCKET){
5}
6
7CWsData::CWsData( SOCKET sok ):ts(sok){
8}
9
10CWsData::~CWsData(){
11 if( ts != INVALID_SOCKET ){
12 ::closesocket( ts );
13 ts = INVALID_SOCKET;
14 }
15}
16
17
18BOOL CWsData::SetSocket( BOOL bCloseBeforeSet, SOCKET sok ){
19 if( bCloseBeforeSet ){
20 if( ts != INVALID_SOCKET ){
21 ::closesocket( ts );
22 }
23 }
24 ts = sok;
25 return 1;
26}
27
28BOOL CWsData::SetSocket( SOCKET sok, BOOL bFailIfSetAlready ){
29 if( bFailIfSetAlready ){
30 if( ts != INVALID_SOCKET ){
31 return 0;
32 }
33 }
34 ts = sok;
35 return 1;
36}
37
38BOOL CWsData::IsSetAlready( VOID ){
39 if( ts != INVALID_SOCKET ){
40 return 1;
41 }
42 return 0;
43}
44
45
46BOOL CWsData::ReceiveData( char *pBuf, int cbToRecv ){
47 int iTotRecv=0, iRecv;
48 while( iTotRecv < cbToRecv ){
49 iRecv = ::recv( ts, pBuf+iTotRecv, cbToRecv-iTotRecv, 0 );
50 if( iRecv <= 0 ){
51 return 0;
52 }
53 iTotRecv += iRecv;
54 }
55 return 1;
56}
57
58BOOL CWsData::SendData( const char *pBuf, int cbToSend ){
59 int iTotSend=0, iSend;
60 while( iTotSend < cbToSend ){
61 iSend = ::send( ts, pBuf+iTotSend, cbToSend-iTotSend, 0 );
62 if( iSend <= 0 ){
63 return 0;
64 }
65 iTotSend += iSend;
66 }
67 return 1;
68}
69
70BOOL CWsData::ReceiveDword( DWORD &dw ){
71 char ch[4];
72 if( ! ReceiveData( ch, 4 ) ) return 0;
73 if( ! CharToDwordHL( ch, dw ) ) return 0;
74 return 1;
75}
76
77BOOL CWsData::SendDword( DWORD dw ){
78 char ch[4];
79 if( ! DwordToCharHL( dw, ch ) ) return 0;
80 if( ! SendData( ch, 4 ) ) return 0;
81 return 1;
82}
83
84
85BOOL CWsData::CharToDwordHL( const char *pBuf, DWORD &dw ){
86 return CharToDwordHL( pBuf[0], pBuf[1], pBuf[2], pBuf[3], dw );
87}
88
89BOOL CWsData::CharToDwordHL( char d3, char d2, char d1, char d0, DWORD &dw ){
90 dw = (DWORD(d3&0xffff)<<24) | (DWORD(d2&0xffff)<<16) | (DWORD(d1&0xffff)<<8) | DWORD(d0&0xffff);
91 return 1;
92}
93
94BOOL CWsData::DwordToCharHL( DWORD dw, char *pBuf ){
95 return DwordToCharHL( dw, pBuf[0], pBuf[1], pBuf[2], pBuf[3] );
96}
97
98BOOL CWsData::DwordToCharHL( DWORD dw, char &d3, char &d2, char &d1, char &d0 ){
99 d3 = char((dw>>24)&0xffff);
100 d2 = char((dw>>16)&0xffff);
101 d1 = char((dw>> 8)&0xffff);
102 d0 = char( dw &0xffff);
103 return 1;
104}
105
CWsClient.h
1#ifndef CWSCLIENT_H_INCLUDED
2#define CWSCLIENT_H_INCLUDED
3
4
5#include "winsock2.h"
6
7
8class CWsClient
9{
10public :
11 CWsClient( USHORT portServer, IN_ADDR inaddrServer );
12 ~CWsClient();
13
14 BOOL ConnectClientServer( SOCKET &socketServer, SOCKADDR_IN *pAddrServer=0 );
15
16private :
17 SOCKADDR_IN addrServer;
18 BOOL bInitSucceeded;
19};
20
21
22#endif
23
CWsClient.cpp
1#include "CWsClient.h"
2
3
4CWsClient::CWsClient( USHORT portServer, IN_ADDR inaddrServer ):bInitSucceeded(0){
5 WSADATA wsaData;
6 if( ::WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) ){
7 return;
8 }
9 ::memset( &addrServer, 0, sizeof(addrServer) );
10 addrServer.sin_family = AF_INET;
11 addrServer.sin_port = portServer;
12 addrServer.sin_addr = inaddrServer;
13
14 bInitSucceeded = 1;
15}
16
17CWsClient::~CWsClient(){
18 if( bInitSucceeded ){
19 ::WSACleanup();
20 }
21}
22
23
24BOOL CWsClient::ConnectClientServer( SOCKET &socketServer, SOCKADDR_IN *pAddrServer ){
25 if( ! bInitSucceeded ){
26 return 0;
27 }
28 /**//*if( socketServer != INVALID_SOCKET ){
29 return 0;
30 }*/
31 socketServer = ::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
32 if( socketServer == INVALID_SOCKET ){
33 return 0;
34 }
35
36 if( pAddrServer ){
37 *pAddrServer = addrServer;
38 }
39 if( ::connect( socketServer, (sockaddr*)&addrServer, sizeof(addrServer) ) ){
40 return 0;
41 }
42 return 1;
43}
44
CMutexString.h
1#ifndef CMUTEXSTRING_H_INCLUDED
2#define CMUTEXSTRING_H_INCLUDED
3
4
5#include "string"
6using namespace std;
7#ifdef UNICODE
8#define TSTRING wstring
9#else
10#define TSTRING string
11#endif
12
13
14#include "winsock2.h"
15
16
17class CMutexString
18{
19public :
20 CMutexString( UINT maxLength=MAX_LENGTH );
21 ~CMutexString();
22
23 VOID GetString( TSTRING &str );
24 VOID ClearString( VOID );
25 VOID GetClearString( TSTRING &str );
26 VOID AppendString( LPCTSTR str, BOOL bEndAppendNewLine=1 );
27 VOID AppendGetString( TSTRING &tstr, LPCTSTR c_str, BOOL bEndAppendNewLine=1 );
28 VOID AppendGetClearString( TSTRING &tstr, LPCTSTR c_str, BOOL bEndAppendNewLine=1 );
29
30private :
31 TSTRING ts;
32 HANDLE hEvent;
33 UINT uMaxLength;
34
35 static CONST UINT MAX_LENGTH;
36 static LPCTSTR NEW_LINE;
37};
38
39
40#endif
41
CMutexString.cpp
1#include "CMutexString.h"
2
3
4CONST UINT CMutexString::MAX_LENGTH = 1024 * 30 - 2;
5LPCTSTR CMutexString::NEW_LINE = TEXT("\r\n");
6
7//---------------------------------------------------------------------------------------------------------
8CMutexString::CMutexString( UINT maxLength ):ts(TEXT("")),hEvent(0),uMaxLength(maxLength){
9 if( uMaxLength > MAX_LENGTH ){
10 uMaxLength = MAX_LENGTH;
11 }
12 hEvent = ::CreateEvent( 0, 0, 1, 0 );
13}
14
15CMutexString::~CMutexString(){
16 ::CloseHandle( hEvent );
17}
18
19//----------------------------------------------------------------------------------------------------------
20VOID CMutexString::GetString( TSTRING &str ){
21 ::WaitForSingleObject( hEvent, INFINITE );
22 str = ts;
23 ::SetEvent( hEvent );
24 return;
25}
26
27VOID CMutexString::ClearString( VOID ){
28 ::WaitForSingleObject( hEvent, INFINITE );
29 ts = TEXT("");
30 ::SetEvent( hEvent );
31 return;
32}
33
34VOID CMutexString::GetClearString( TSTRING &str ){
35 ::WaitForSingleObject( hEvent, INFINITE );
36 str = ts;
37 ts = TEXT("");
38 ::SetEvent( hEvent );
39 return;
40}
41
42VOID CMutexString::AppendString( LPCTSTR str, BOOL bEndAppendNewLine ){
43 ::WaitForSingleObject( hEvent, INFINITE );
44 ts += str;
45 if( bEndAppendNewLine ){
46 ts += NEW_LINE;
47 }
48 UINT uL = ts.length();
49 if( uL > uMaxLength ){
50 ts.erase( 0, uL - uMaxLength );
51 }
52 ::SetEvent( hEvent );
53 return;
54}
55
56VOID CMutexString::AppendGetString( TSTRING &tstr, LPCTSTR c_str, BOOL bEndAppendNewLine ){
57 ::WaitForSingleObject( hEvent, INFINITE );
58 ts += c_str;
59 if( bEndAppendNewLine ){
60 ts += NEW_LINE;
61 }
62 UINT uL = ts.length();
63 if( uL > uMaxLength ){
64 ts.erase( 0, uL - uMaxLength );
65 }
66 tstr = ts;
67 ::SetEvent( hEvent );
68 return;
69}
70
71VOID CMutexString::AppendGetClearString( TSTRING &tstr, LPCTSTR c_str, BOOL bEndAppendNewLine ){
72 ::WaitForSingleObject( hEvent, INFINITE );
73 ts += c_str;
74 if( bEndAppendNewLine ){
75 ts += NEW_LINE;
76 }
77 UINT uL = ts.length();
78 if( uL > uMaxLength ){
79 ts.erase( 0, uL - uMaxLength );
80 }
81 tstr = ts;
82 ts = TEXT("");
83 ::SetEvent( hEvent );
84 return;
85}
86
ChessCommon.h
1/**//*
2服务器端 白棋,客户端 黑棋。
3
4网络信息:
5前四字节依次为 DWORD 的高到低字节,表示此条信息的字节数(不含此四字节);
6再四字节依次为 DWORD 的高到低字节,表示指令类型:落子,聊天,请求悔棋,请求新开一局,等等
7之后为指令的参数,参数最大长度为 CMD_PARAM_LEN 字节
8 落子:坐标同 LPARAM ——棋盘(0..14),而非窗口。
9*/
10
11#ifndef CHESSCOMMON_H_INCLUDED
12#define CHESSCOMMON_H_INCLUDED
13
14
15// 网络
16#define SERVER_PORT 35536
17
18
19// 命令
20#define CMD_PARAM_LEN 1024
21#define CMD_BYE 0
22#define CMD_PUT_CHESSMAN 1
23#define CMD_CHAT_WORDS 2
24#define CMD_CHAT_WORDS_CONTINUE 3
25#define CMD_ASK_FOR_REPUT_CHESSMAN 4
26#define CMD_AGREE_REPUT_CHESSMAN 5
27#define CMD_DISAGREE_REPUT_CHESSMAN 6
28#define CMD_ASK_FOR_NEW_GAME 7
29#define CMD_AGREE_NEW_GAME 8
30#define CMD_DISAGREE_NEW_GAME 9
31
32
33// 消息
34#define WM_NET_STATE (WM_USER+1)
35#define WPARAM_INIT_ING 0
36#define WPARAM_INIT_FAILED 1
37#define WPARAM_INIT_SUCCEEDED 2
38#define WPARAM_ERROR 3
39
40#define WM_BYE (WM_USER+2)
41#define WPARAM_BYE_SEND 0
42#define WPARAM_BYE_RECV 1
43
44#define WM_CHESSMAN (WM_USER+3)
45#define WPARAM_PUT_PLAYER_CHESSMAN 0
46#define WPARAM_PUT_ENEMY_CHESSMAN 1
47#define WPARAM_PLAYER_ASK_FOR_REPUT_CHESSMAN 2
48#define WPARAM_ENEMY_ASK_FOR_REPUT_CHESSMAN 3
49#define WPARAM_ENEMY_AGREE_REPUT_CHESSMAN 4
50#define WPARAM_ENEMY_DISAGREE_REPUT_CHESSMAN 5
51
52#define WM_CHAT_WORDS (WM_USER+4)
53#define WPARAM_CHAT_WORDS_SEND 0
54#define WPARAM_CHAT_WORDS_RECV 1
55#define WPARAM_CHAT_WORDS_RECV_CONTINUE 2
56
57#define WM_GAME (WM_USER+5)
58#define WPARAM_PLAYER_ASK_FOR_NEW_GAME 0
59#define WPARAM_ENEMY_ASK_FOR_NEW_GAME 1
60#define WPARAM_ENEMY_AGREE_NEW_GAME 2
61#define WPARAM_ENEMY_DISAGREE_NEW_GAME 3
62
63
64
65// 下棋界面
66#define CHESS_DIST_LT 20
67#define CHESS_QUAD_LEN 29
68#define CHESS_CHESSMAN_LEN 28
69#define CHESS_CHESSMAN_HALF_LEN (CHESS_CHESSMAN_LEN/2)
70#define CHESS_BOARD_LEN 446
71#define CHESS_BOARD_LEFT 0
72#define CHESS_BOARD_TOP 0
73#define CHESS_POINT_NUM_HV 15
74#define CHESS_TYPE_SPACE 0
75#define CHESS_TYPE_BLACK 1
76#define CHESS_TYPE_WHITE 2
77#define CHESS_TYPE_TOTAL 3
78
79
80#endif
81
CClientServer.h
1#ifndef CCLIENTSERVER_H_INCLUDED
2#define CCLIENTSERVER_H_INCLUDED
3
4
5#include "DetermineServerClient.h"
6#include "ChessCommon.h"
7#include "CWsData.h"
8#ifdef SERVER_DEFINED
9#include "CWsServer.h"
10#else
11#include "CWsClient.h"
12#include "GetServerIP.h"
13#endif
14
15
16class CClientServer
17{
18public :
19 CClientServer();
20 ~CClientServer();
21
22 BOOL Initialize( VOID );
23 BOOL IsInitSucceeded( VOID );
24
25 BOOL SendCmd_Bye( VOID );
26 BOOL SendCmd_PutChessman( DWORD dwX, DWORD dwY );
27 BOOL SendCmd_ChatWords( const char *szWords, int cbWords );
28 BOOL SendCmd_AskForReputChessman( VOID );
29 BOOL SendCmd_AgreeReputChessman( VOID );
30 BOOL SendCmd_DisgreeReputChessman( VOID );
31 BOOL SendCmd_AskForNewGame( VOID );
32 BOOL SendCmd_AgreeNewGame( VOID );
33 BOOL SendCmd_DisgreeNewGame( VOID );
34
35 BOOL SendCmd( DWORD dwCmdType, const char *CmdParam=0, int cbParam=0 );
36 BOOL ReceiveCmd( DWORD &dwCmdType, char *CmdParam, int &cbParam );
37
38private :
39 CWsData data;
40 #ifdef SERVER_DEFINED
41 CWsServer cs;
42 #else
43 CWsClient cs;
44 #endif
45 BOOL bInitSucceeded;
46};
47
48
49#endif
50
CClientServer.cpp
1#include "CClientServer.h"
2
3
4#ifdef SERVER_DEFINED
5CClientServer::CClientServer():cs(SERVER_PORT),bInitSucceeded(0){
6#else
7CClientServer::CClientServer():cs(SERVER_PORT,::GetServerIP()),bInitSucceeded(0){
8#endif
9}
10
11CClientServer::~CClientServer(){
12}
13
14//------------------------------------------------------------------------------------------------
15BOOL CClientServer::Initialize( VOID ){
16 bInitSucceeded = 0;
17 SOCKET sok = INVALID_SOCKET;
18 if( ! cs.ConnectClientServer( sok ) ) return 0;
19 if( ! data.SetSocket( sok ) ) return 0;
20 bInitSucceeded = 1;
21 return 1;
22}
23
24BOOL CClientServer::IsInitSucceeded( VOID ){
25 return bInitSucceeded;
26}
27
28//------------------------------------------------------------------------------------------------
29BOOL CClientServer::SendCmd_Bye( VOID ){
30 return SendCmd( CMD_BYE );
31}
32
33BOOL CClientServer::SendCmd_PutChessman( DWORD dwX, DWORD dwY ){
34 char sz[4];
35 ::CWsData::DwordToCharHL( MAKELPARAM( dwX, dwY ), sz );
36 return SendCmd( CMD_PUT_CHESSMAN, sz, 4 );
37}
38
39BOOL CClientServer::SendCmd_ChatWords( const char *szWords, int cbWords ){
40 int i=0;
41 while( cbWords > CMD_PARAM_LEN ){
42 if( ! SendCmd( CMD_CHAT_WORDS_CONTINUE, szWords+i, CMD_PARAM_LEN ) ){
43 return 0;
44 }
45 i += CMD_PARAM_LEN;
46 cbWords -= CMD_PARAM_LEN;
47 }
48 return SendCmd( CMD_CHAT_WORDS, szWords+i, cbWords );
49}
50
51BOOL CClientServer::SendCmd_AskForReputChessman( VOID ){
52 return SendCmd( CMD_ASK_FOR_REPUT_CHESSMAN );
53}
54
55BOOL CClientServer::SendCmd_AgreeReputChessman( VOID ){
56 return SendCmd( CMD_AGREE_REPUT_CHESSMAN );
57}
58
59BOOL CClientServer::SendCmd_DisgreeReputChessman( VOID ){
60 return SendCmd( CMD_DISAGREE_REPUT_CHESSMAN );
61}
62
63BOOL CClientServer::SendCmd_AskForNewGame( VOID ){
64 return SendCmd( CMD_ASK_FOR_NEW_GAME );
65}
66
67BOOL CClientServer::SendCmd_AgreeNewGame( VOID ){
68 return SendCmd( CMD_AGREE_NEW_GAME );
69}
70
71BOOL CClientServer::SendCmd_DisgreeNewGame( VOID ){
72 return SendCmd( CMD_DISAGREE_NEW_GAME );
73}
74
75//-----------------------------------------------------------------------------------------------------------
76BOOL CClientServer::SendCmd( DWORD dwCmdType, const char *CmdParam, int cbParam ){
77 if( ! bInitSucceeded ) return 0;
78 if( cbParam < 0 ) return 0;
79 if( ! data.SendDword( cbParam+4 ) ) return 0;
80 if( ! data.SendDword( dwCmdType ) ) return 0;
81 if( CmdParam && (cbParam>0) ){
82 if( ! data.SendData( CmdParam, cbParam ) ) return 0;
83 }
84 return 1;
85}
86
87BOOL CClientServer::ReceiveCmd( DWORD &dwCmdType, char *CmdParam, int &cbParam ){
88 if( ! bInitSucceeded ) return 0;
89 DWORD dwLen;
90 if( ! data.ReceiveDword( dwLen ) ) return 0;
91 if( dwLen < 4 ) return 0;
92 if( ! data.ReceiveDword( dwCmdType ) ) return 0;
93 cbParam = dwLen - 4;
94 if( cbParam == 0 ) return 1;
95 if( ! data.ReceiveData( CmdParam, cbParam ) ) return 0;
96 return 1;
97}
98
CChessPainter.h
1#ifndef CCHESSPAINTER_H_INCLUDED
2#define CCHESSPAINTER_H_INCLUDED
3
4
5#include "ChessCommon.h"
6#include "resource.h"
7#include "winsock2.h"
8
9
10class CChessPainter
11{
12public :
13 CChessPainter();
14 ~CChessPainter();
15
16 BOOL ClearChessboard( VOID );
17 BOOL PutChessman( int posX, int posY, int chessmanType, BOOL bIsInBoard=1 );
18 BOOL EraseLastChessman( BOOL bErase=1 );
19 BOOL PaintChess( HWND hWnd );
20 BOOL PaintChess( HDC hdcWnd );
21 int GetTotChessmanPut( VOID );
22 BOOL PosClientToBoard( int xClient, int yClient, int &xBoard, int &yBoard );
23 BOOL PosBoardToClient( int xBoard, int yBoard, int &xClient, int &yClient );
24
25private :
26 BOOL LoadRes( VOID );
27 BOOL FreeRes( VOID );
28
29 int iChessmanType[CHESS_POINT_NUM_HV][CHESS_POINT_NUM_HV];
30 int iLastX, iLastY, iTotChessmanPut;
31
32 static int iTotChessPainter;
33 static HBITMAP hbmpChessboard, hbmpChessmanWhite, hbmpChessmanBlack, hbmpChessmanMask;
34};
35
36
37#endif
38
CChessPainter.cpp
1#include "CChessPainter.h"
2
3
4int CChessPainter::iTotChessPainter = 0;
5HBITMAP CChessPainter::hbmpChessboard = 0;
6HBITMAP CChessPainter::hbmpChessmanWhite = 0;
7HBITMAP CChessPainter::hbmpChessmanBlack = 0;
8HBITMAP CChessPainter::hbmpChessmanMask = 0;
9//-----------------------------------------------------------------------------------------------------------
10CChessPainter::CChessPainter(){
11 if( ++iTotChessPainter == 1 ){
12 LoadRes();
13 }
14 ClearChessboard();
15}
16
17CChessPainter::~CChessPainter(){
18 if( --iTotChessPainter == 0 ){
19 FreeRes();
20 }
21}
22//----------------------------------------------------------------------------------------------------------
23BOOL CChessPainter::ClearChessboard( VOID ){
24 ::memset( iChessmanType, 0, sizeof(iChessmanType) );
25 iTotChessmanPut = 0;
26 iLastX = iLastY = -1;
27 return 1;
28}
29
30BOOL CChessPainter::PutChessman( int posX, int posY, int chessmanType, BOOL bIsInBoard ){
31 if( ! bIsInBoard ){
32 PosClientToBoard( posX, posY, posX, posY );
33 }
34 if( (posX<0) || (CHESS_POINT_NUM_HV<=posX) || (posY<0) || (CHESS_POINT_NUM_HV<=posY) ){
35 return 0;
36 }
37 int ict = iChessmanType[posX][posY];
38 switch( chessmanType ){
39 case CHESS_TYPE_BLACK :
40 case CHESS_TYPE_WHITE :
41 if( ( ict != CHESS_TYPE_WHITE ) && ( ict != CHESS_TYPE_BLACK ) ){
42 iChessmanType[posX][posY] = chessmanType;
43 ++iTotChessmanPut;
44 iLastX = posX;
45 iLastY = posY;
46 return 1;
47 }
48 }
49 return 0;
50}
51
52BOOL CChessPainter::EraseLastChessman( BOOL bErase ){
53 if( (iLastX<0) || (iLastY<0) ){
54 return 0;
55 }
56 if( bErase ){
57 iChessmanType[iLastX][iLastY] = CHESS_TYPE_SPACE;
58 --iTotChessmanPut;
59 iLastX = iLastY = -1;
60 }
61 return 1;
62}
63
64BOOL CChessPainter::PaintChess( HWND hWnd ){
65 HDC hdc = ::GetDC( hWnd );
66 if( hdc == 0 ){
67 return 0;
68 }
69 PaintChess( hdc );
70 ::ReleaseDC( hWnd, hdc );
71 return 1;
72}
73
74BOOL CChessPainter::PaintChess( HDC hdcWnd ){
75 if( hdcWnd == 0 ){
76 return 0;
77 }
78 HDC hdcChessboard, hdcMask, hdcChessman[CHESS_TYPE_TOTAL];
79
80 hdcChessboard = ::CreateCompatibleDC( hdcWnd );
81 hdcMask = ::CreateCompatibleDC( hdcWnd );
82 hdcChessman[CHESS_TYPE_BLACK] = ::CreateCompatibleDC( hdcWnd );
83 hdcChessman[CHESS_TYPE_WHITE] = ::CreateCompatibleDC( hdcWnd );
84
85 ::SelectObject( hdcChessboard, hbmpChessboard );
86 ::SelectObject( hdcMask, hbmpChessmanMask );
87 ::SelectObject( hdcChessman[CHESS_TYPE_BLACK], hbmpChessmanBlack );
88 ::SelectObject( hdcChessman[CHESS_TYPE_WHITE], hbmpChessmanWhite );
89
90 int x, y, tx, ty, t;
91 ::BitBlt( hdcWnd, CHESS_BOARD_LEFT, CHESS_BOARD_TOP, CHESS_BOARD_LEN, CHESS_BOARD_LEN,
92 hdcChessboard, 0, 0, SRCCOPY );
93 for( x=0; x<CHESS_POINT_NUM_HV; ++x ){
94 for( y=0; y<CHESS_POINT_NUM_HV; ++y ){
95 if( t = iChessmanType[x][y] ){
96 // MaskBlt
97 // TransparentBlt
98 tx = x * CHESS_QUAD_LEN + CHESS_DIST_LT + CHESS_BOARD_LEFT - CHESS_CHESSMAN_HALF_LEN;
99 ty = y * CHESS_QUAD_LEN + CHESS_DIST_LT + CHESS_BOARD_TOP - CHESS_CHESSMAN_HALF_LEN;
100 ::BitBlt( hdcWnd, tx, ty, CHESS_CHESSMAN_LEN, CHESS_CHESSMAN_LEN,
101 hdcMask, 0, 0, MERGEPAINT );
102 ::BitBlt( hdcWnd, tx, ty, CHESS_CHESSMAN_LEN, CHESS_CHESSMAN_LEN,
103 hdcChessman[t], 0, 0, SRCAND );
104 }
105 }
106 }
107
108 ::DeleteDC( hdcChessboard );
109 ::DeleteDC( hdcMask );
110 ::DeleteDC( hdcChessman[CHESS_TYPE_BLACK] );
111 ::DeleteDC( hdcChessman[CHESS_TYPE_WHITE] );
112 return 1;
113}
114
115int CChessPainter::GetTotChessmanPut( VOID ){
116 return iTotChessmanPut;
117}
118
119BOOL CChessPainter::PosClientToBoard( int xClient, int yClient, int &xBoard, int &yBoard ){
120 xBoard = ( xClient - CHESS_DIST_LT - CHESS_BOARD_LEFT + CHESS_QUAD_LEN / 2 ) / CHESS_QUAD_LEN;
121 yBoard = ( yClient - CHESS_DIST_LT - CHESS_BOARD_TOP + CHESS_QUAD_LEN / 2 ) / CHESS_QUAD_LEN;
122 return 1;
123}
124
125BOOL CChessPainter::PosBoardToClient( int xBoard, int yBoard, int &xClient, int &yClient ){
126 xClient = xBoard * CHESS_QUAD_LEN + CHESS_DIST_LT + CHESS_BOARD_LEFT;
127 yClient = yBoard * CHESS_QUAD_LEN + CHESS_DIST_LT + CHESS_BOARD_TOP;
128 return 1;
129}
130//-------------------------------------------------------------------------------------------------------------
131BOOL CChessPainter::LoadRes( VOID ){
132 if( hbmpChessboard || hbmpChessmanWhite || hbmpChessmanBlack || hbmpChessmanMask ){
133 return 0;
134 }
135 HINSTANCE hInst = ::GetModuleHandle( 0 );
136 if( hInst == 0 ){
137 return 0;
138 }
139 #define LOAD(h,id) h = ::LoadBitmap( hInst, MAKEINTRESOURCE(id) )
140 LOAD( hbmpChessboard, IDB_CHESSBOARD );
141 LOAD( hbmpChessmanWhite, IDB_CHESSMAN_WHITE );
142 LOAD( hbmpChessmanBlack, IDB_CHESSMAN_BLACK );
143 LOAD( hbmpChessmanMask, IDB_CHESSMAN_MASK );
144 #undef LOAD
145 return 1;
146}
147
148BOOL CChessPainter::FreeRes( VOID ){
149 #define FREE(h) \
150 if( h ){ \
151 ::DeleteObject( h ); \
152 h = 0; \
153 }
154 FREE( hbmpChessboard )
155 FREE( hbmpChessmanWhite )
156 FREE( hbmpChessmanBlack )
157 FREE( hbmpChessmanMask )
158 #undef FREE
159 return 1;
160}
161