Fly_网络聊天与五子棋

Fly_网络聊天与五子棋

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

当初WinXP下开发,现在在Win7下有点变形。

客户端



服务器端



ReadMe.txt(也许可以称之为文档)

 1 功能:
 2 网络对战五子棋与网络聊天。
 3
 4
 5 开发工具:
 6 VS2008 中的 C ++ , 即VC9. 0
 7
 8
 9 平台:
10 Windows,需VC9.0运行时支持(相关VC  * .dll 已放在Release目录下,不需另外安装)。
11
12
13 技术:
14 WinSock;
15 Win32 Api;
16 对话框(用Win32 Api 函数处理);
17 多线程(用事件内核对象实现共享资源互斥访问);
18 用C ++ 类模块化封装,易于维护;
19 使用预编译指令,一份代码可编译为服务器端或客户端(由DetermineServerClient.h中的宏SERVER_DEFINED是否定义决定)。
20
21
22 注意:
23 ServerIP.inf 中放服务器ip地址,服务器先启动。
24 Fly_命名.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 "
 7 using   namespace  std;
 8
 9
10 IN_ADDR GetServerIP( VOID );
11
12
13 #endif
14




GetServerIP.cpp

 1 #include  " GetServerIP.h "
 2
 3
 4 IN_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
 20 LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
 21 #pragma code_page( 936 )
 22 #endif   // _WIN32
 23
 24 #ifdef APSTUDIO_INVOKED
 25 /**/ /////////////////////////////////////////////////////////////////////////////
 26 //
 27 //  TEXTINCLUDE
 28 //
 29
 30 1  TEXTINCLUDE 
 31 BEGIN
 32      " resource.h\0 "
 33 END
 34
 35 2  TEXTINCLUDE 
 36 BEGIN
 37      " #include  "" afxres.h "" \r\n "
 38      " \0 "
 39 END
 40
 41 3  TEXTINCLUDE 
 42 BEGIN
 43      " \r\n "
 44      " \0 "
 45 END
 46
 47 #endif      //  APSTUDIO_INVOKED
 48
 49
 50 /**/ /////////////////////////////////////////////////////////////////////////////
 51 //
 52 //  Dialog
 53 //
 54
 55 IDD_DIALOG_MAIN DIALOGEX  0 0 587 343
 56 STYLE DS_SETFONT  |  DS_MODALFRAME  |  DS_SETFOREGROUND  |  DS_3DLOOK  |  DS_CENTER  |  WS_MINIMIZEBOX  |  WS_POPUP  |  WS_VISIBLE  |  WS_CAPTION  |  WS_SYSMENU
 57 EXSTYLE WS_EX_CLIENTEDGE  |  WS_EX_STATICEDGE
 58 FONT  9 " 楷体_GB2312 " 400 0 0x86
 59 BEGIN
 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
 69 END
 70
 71
 72 /**/ /////////////////////////////////////////////////////////////////////////////
 73 //
 74 //  DESIGNINFO
 75 //
 76
 77 #ifdef APSTUDIO_INVOKED
 78 GUIDELINES DESIGNINFO 
 79 BEGIN
 80     IDD_DIALOG_MAIN, DIALOG
 81     BEGIN
 82         LEFTMARGIN,  8
 83         RIGHTMARGIN,  579
 84         TOPMARGIN,  8
 85         BOTTOMMARGIN,  336
 86     END
 87 END
 88 #endif      //  APSTUDIO_INVOKED
 89
 90
 91 /**/ /////////////////////////////////////////////////////////////////////////////
 92 //
 93 //  Bitmap
 94 //
 95
 96 IDB_CHESSBOARD          BITMAP                   " Resource\\Chessboard.bmp "
 97 IDB_CHESSMAN_BLACK      BITMAP                   " Resource\\ChessmanBlack.bmp "
 98 IDB_CHESSMAN_WHITE      BITMAP                   " Resource\\ChessmanWhite.bmp "
 99 IDB_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.
108 IDI_ICON                ICON                     " Resource\\Icon.ico "
109
110 /**/ /////////////////////////////////////////////////////////////////////////////
111 //
112 //  Cursor
113 //
114
115 IDC_HAND_BLACK          CURSOR                   " Resource\\HandBlack.cur "
116 IDC_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 // --------------------------------------------------------------------------------------------------------
 27 HWND            hDialog  =   0 ;
 28 CMutexString    ms;
 29 CClientServer   cs;
 30
 31 // --------------------------------------------------------------------------------------------------------
 32 UINT __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 // --------------------------------------------------------------------------------------------------------
 87 INT_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 // --------------------------------------------------------------------------------------------------------
415 int  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
 8 class  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
 4 CWsServer::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
38 CWsServer:: ~ CWsServer() {
39        if( bInitSucceeded ){
40                ::closesocket( socketServer );
41                socketServer = INVALID_SOCKET;
42                ::WSACleanup();
43        }

44}

45
46
47 BOOL 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
 8 class  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
  4 CWsData::CWsData():ts(INVALID_SOCKET) {
  5}

  6
  7 CWsData::CWsData( SOCKET sok ):ts(sok) {
  8}

  9
 10 CWsData:: ~ CWsData() {
 11        if( ts != INVALID_SOCKET ){
 12                ::closesocket( ts );
 13                ts = INVALID_SOCKET;
 14        }

 15}

 16
 17
 18 BOOL 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
 28 BOOL 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
 38 BOOL CWsData::IsSetAlready( VOID ) {
 39        if( ts != INVALID_SOCKET ){
 40                return 1;
 41        }

 42        return 0;
 43}

 44
 45
 46 BOOL 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
 58 BOOL 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
 70 BOOL 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
 77 BOOL 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
 85 BOOL CWsData::CharToDwordHL(  const   char   * pBuf, DWORD  & dw ) {
 86        return CharToDwordHL( pBuf[0], pBuf[1], pBuf[2], pBuf[3], dw );
 87}

 88
 89 BOOL 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
 94 BOOL CWsData::DwordToCharHL( DWORD dw,  char   * pBuf ) {
 95        return DwordToCharHL( dw, pBuf[0], pBuf[1], pBuf[2], pBuf[3] );
 96}

 97
 98 BOOL 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
 8 class  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
 4 CWsClient::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
17 CWsClient:: ~ CWsClient() {
18        if( bInitSucceeded ){
19                ::WSACleanup();
20        }

21}

22
23
24 BOOL 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 "
 6 using   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
17 class  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
 4 CONST UINT CMutexString::MAX_LENGTH  =   1024   *   30   -   2 ;
 5 LPCTSTR    CMutexString::NEW_LINE    =  TEXT( " \r\n " );
 6
 7 // ---------------------------------------------------------------------------------------------------------
 8 CMutexString::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
15 CMutexString:: ~ CMutexString() {
16        ::CloseHandle( hEvent );
17}

18
19 // ----------------------------------------------------------------------------------------------------------
20 VOID CMutexString::GetString( TSTRING  & str ) {
21        ::WaitForSingleObject( hEvent, INFINITE );
22        str = ts;
23        ::SetEvent( hEvent );
24        return;
25}

26
27 VOID CMutexString::ClearString( VOID ) {
28        ::WaitForSingleObject( hEvent, INFINITE );
29        ts = TEXT("");
30        ::SetEvent( hEvent );
31        return;
32}

33
34 VOID CMutexString::GetClearString( TSTRING  & str ) {
35        ::WaitForSingleObject( hEvent, INFINITE );
36        str = ts;
37        ts = TEXT("");
38        ::SetEvent( hEvent );
39        return;
40}

41
42 VOID 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
56 VOID 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
71 VOID 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
16 class  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
 5 CClientServer::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
10 class  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
  4 int  CChessPainter::iTotChessPainter        =   0 ;
  5 HBITMAP CChessPainter::hbmpChessboard      =   0 ;
  6 HBITMAP CChessPainter::hbmpChessmanWhite   =   0 ;
  7 HBITMAP CChessPainter::hbmpChessmanBlack   =   0 ;
  8 HBITMAP CChessPainter::hbmpChessmanMask    =   0 ;
  9 // -----------------------------------------------------------------------------------------------------------
 10 CChessPainter::CChessPainter() {
 11        if++iTotChessPainter == 1 ){
 12                LoadRes();
 13        }

 14        ClearChessboard();
 15}

 16
 17 CChessPainter:: ~ CChessPainter() {
 18        if--iTotChessPainter == 0 ){
 19                FreeRes();
 20        }

 21}

 22 // ----------------------------------------------------------------------------------------------------------
 23 BOOL CChessPainter::ClearChessboard( VOID ) {
 24        ::memset( iChessmanType, 0sizeof(iChessmanType) );
 25        iTotChessmanPut = 0;
 26        iLastX = iLastY = -1;
 27        return 1;
 28}

 29
 30 BOOL 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
 52 BOOL 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
 64 BOOL 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
 74 BOOL 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
115 int   CChessPainter::GetTotChessmanPut( VOID ) {
116        return iTotChessmanPut;
117}

118
119 BOOL 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
125 BOOL 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 // -------------------------------------------------------------------------------------------------------------
131 BOOL 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
148 BOOL 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

 

你可能感兴趣的:(Fly_网络聊天与五子棋)