coreBugZJ

此 blog 已弃。

Fly_网络聊天与五子棋

高中时候的古董,现在重读,有点累。体会:文档很重要。。。

当初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, 0sizeof(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 = 0break;
24                }

25                if( szIp[i] == '.' ){
26                        if( (++dots>3|| (szIp[i+1]=='.') ){
27                                bOk = 0break;
28                        }

29                }

30                else{
31                        if( (szIp[i]<'0'|| ('9'<szIp[i]) ){
32                                bOk = 0break;
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 00587343
 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"40000x86
 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, 00 );
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, 00 );
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, 00 );
362                        return 1;
363                case WPARAM_BYE_RECV : 
364                        bShouldSendBye = 0;
365                        ::MessageBox( hDlg, TEXT("对方断开连接"), TEXT("提示"), MB_OK );
366                        ::PostMessage( hDlg, WM_CLOSE, 00 );
367                        return 1;
368                }

369                return 1;
370
371        case WM_INITDIALOG : 
372                ::CloseHandle( (HANDLE)::_beginthreadex( 00, ::DealCmdReceived, 000 )  );
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( 22 ), &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, 0sizeof(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( 22 ), &wsaData ) ){
 7                return;
 8        }

 9        ::memset( &addrServer, 0sizeof(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( 0010 );
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=0int 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, 0sizeof(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, 00, 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, 00, MERGEPAINT );
102                                ::BitBlt( hdcWnd, tx, ty, CHESS_CHESSMAN_LEN, CHESS_CHESSMAN_LEN, 
103                                        hdcChessman[t], 00, 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

 

posted on 2011-06-09 21:25 coreBugZJ 阅读(2177) 评论(0)  编辑 收藏 引用 所属分类: Windows


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理