www.pudn.com > 3D_OnlineGame_Humen.rar > MainWnd.cpp


// MainWnd.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "XMudClient.h" 
#include "MainWnd.h" 
 
#include "midi.h" 
#include "3DSound.h" 
#include "FacePlate.h" 
#include "InterNetMsg.h" 
#include "MenuLoadOldPlay.h" 
#include "MenuCreateNew.h" 
#include "MapInfo.h" 
#include "MainScreen.h" 
#include "D3DRMScreen.h" 
#include "NpcInfo.h" 
#include "InitInternet.h" 
#include "CommandCheck.h" 
#include "TimeAction.h" 
#include "HelpAndVer.h" 
#include "MyMusic.h" 
#include  
#include "MyDInput.h" 
//add header file 
#include "wgs\common.h" 
#include "wgs\wsa_xtra.h" 
#include "wgs\socket.h" 
#include "wgs\WGS.h" 
#include "communicatemsg.h" 
//end 
#include "ErrCode.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
int nSpareTime;		//剩下的時間(單位:秒) 
int nRecTimes;		//接收到的信息次數 
 
extern BOOL bstartrend; 
BOOL g_Show555=FALSE; 
BOOL ShowSystemMessage=FALSE; 
int g_nReceiveMsgState; 
//CString g_csSendToServerMsg; 
//char g_szSrvActiveBuf[2048]; 
int nSrvPort = 6678;//輔助服務器的端口號碼(這個端口號應該由主服務器提供) 
BOOL g_GetSameMove = FALSE; 
 
D3DVECTOR pSysSoundPos = D3DVECTOR(0,0,0); 
RECT			g_rcWindow; 
LPDIRECT3DRM3	g_lpD3DRM; 
int	gnProgramState; 
int g_nGameState; 
float g_fCamfov = 0.2f; 
 
//CInputMsg m_InputMsg; 
CMenuLoadOldPlay m_MenuLoadOldPlay; 
CStartGameMenu m_StartGameMenu; 
CMenuCreateNew m_MenuCreateNew; 
CMainScreen m_MainScreen; 
CMesssageWnd m_MessageWnd; 
 
//HANDLE gInputMesThread; 
BOOL g_bGetInputMessage = FALSE; //打開接收按鍵消息 
CString g_sPlayerName; 
CString g_szInputMsg = _T(""); 
int     g_nInputMsgPos = 0; 
 
CStringList g_szInputMsgList;	//存放各條信息 
static int  nInputPos[MSG_PIECE_NUMBER];	//光標在每行信息中的位置 
static int  nNowInWhere = 0;			//現在在那一條信息中 
BOOL bInsertState = TRUE;	//插入覆蓋狀態 
static BOOL bMsgChanged = TRUE;	//從以前的信息鏈中得到信息後是否改動過 
//如果沒有改動,則這次輸出的信息就不再加入信息鏈中 
static CString szLastMsg;   //保存上一步的信息,供恢復使用 
int g_nSelStart = 0; 
int g_nSelEnd = 0; 
 
extern BOOL g_Redraw2dFace[2]; 
extern BOOL g_Redraw3dFace[2]; 
 
extern HANDLE gSendToSvrThread; 
extern rmfullglobals myglobs; 
extern D3DAppInfo* d3dapp; 
extern LPDIRECT3DRMFRAME3 g_lpplayer; 
extern D3DVECTOR g_CameraPosition; 
extern D3DVECTOR g_lightgammer; 
 
extern char g_tszPathName[256]; 
extern char	g_szErrorMsg[256]; 
extern BOOL	g_bInitSound; 
extern PathInfo info; 
 
extern BOOL	bCloseSocket; 
 
extern TOldMsg m_OldMsg; 
extern CStringList ListCom;//所有命令鏈表 
 
CList quicktalklist; 
CList  chatchannellist; 
CListplayerlist; 
CPlayerInfo * lpPlayerInfo; 
CListskilllist; 
CSkillInfo * lpSkillInfo; 
CListequiplist; 
CListequiprentlist; 
CEquipInfo *lpEquipInfo; 
CList	 maplist;//地圖信息鏈表 
CMapInfo * lpMapInfo; 
CList  animationlist; 
animationCallbackArgs *cb; 
CList  npclist; 
CList npcskilllist; 
CList npcEquiplist; 
CNpcInfo *lpNpcInfo; 
// Nuke +1 
CList npcAsklist; 
 
extern void QuitResolution(void); 
 
extern BOOL		ReadServerMsg(); 
extern SOCKET	hLCltForRSvrSock; 
extern char		szSendBuf[]; 
 
extern BOOL bSelectDefault; 
extern BOOL g_bSoundPaused; 
///////////////////////////////////////////////////////////////////////////// 
// CMainWnd 
 
CMainWnd::CMainWnd() 
{ 
   
} 
 
CMainWnd::~CMainWnd() 
{ 
} 
 
 
BEGIN_MESSAGE_MAP(CMainWnd, CWnd) 
//{{AFX_MSG_MAP(CMainWnd) 
ON_WM_CREATE() 
ON_WM_DESTROY() 
ON_WM_LBUTTONDOWN() 
ON_WM_LBUTTONUP() 
ON_WM_MOUSEMOVE() 
ON_WM_RBUTTONDOWN() 
ON_WM_TIMER() 
ON_WM_CHAR() 
ON_WM_RBUTTONUP() 
ON_WM_LBUTTONDBLCLK() 
//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
void ReadConfigFile(void) 
{ 
  FILE *fp; 
  char  ConfigFile[MAX_PATH]; 
 
  strcpy(ConfigFile,g_tszPathName); 
  strcat(ConfigFile,"\\Config.ini"); 
  if(fp=fopen(ConfigFile,"rb")) 
  { 
    fread(&g_bSoundPaused,sizeof(BOOL),1,fp); 
    fread(&bSelectDefault,sizeof(BOOL),1,fp); 
    fread(&g_lightgammer,sizeof(D3DVECTOR),1,fp); 
    fclose(fp); 
  } 
} 
 
void SaveConfigFile(void) 
{ 
  FILE *fp; 
  char  ConfigFile[MAX_PATH]; 
 
  strcpy(ConfigFile,g_tszPathName); 
  strcat(ConfigFile,"\\Config.ini"); 
  if(fp=fopen(ConfigFile,"wb")) 
  { 
    fwrite(&g_bSoundPaused,sizeof(BOOL),1,fp); 
    fwrite(&bSelectDefault,sizeof(BOOL),1,fp); 
    fwrite(&g_lightgammer,sizeof(D3DVECTOR),1,fp); 
    fclose(fp); 
  } 
} 
///////////////////////////////////////////////////////////////////////////// 
// CMainWnd message handlers 
 
int CMainWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
  if (CWnd::OnCreate(lpCreateStruct) == -1) 
    return -1; 
  srand( timeGetTime() ); 
 
  ReadConfigFile();   
  if(g_bSoundPaused) m_OldMsg.szMusic="MusicON"; 
  else               m_OldMsg.szMusic="MusicOFF"; 
  InitIME(m_hWnd); 
  SetIMEPosition(0,0); 
  DisableIME(m_hWnd); 
 
  ShowCursor(FALSE); 
  GetWindowRect( &g_rcWindow ); 
  myglobs.hWndMain = m_hWnd; 
   
  // TODO: Add your specialized creation code here 
  m_SplashWnd.Create(this);		//創建彈出窗口 
  m_SplashWnd.ShowWindow(SW_SHOW);//顯示彈出窗口 
  m_SplashWnd.UpdateWindow();		//更新彈出窗口 
//  ::DelayTime(2000); 
  ::Sleep(2000);					//進程休眠2秒 
   
  // 
  //初始化音效,裝入全局量的音效,如菜單和對話框的彈出收回,鼠標按下等等 
  // 
  if(!InitSound()) 
  { 
    MessageBox(g_szErrorMsg,"InitSound Error",MB_OK); 
    g_bInitSound = FALSE; 
  } 
  else 
  { 
    g_bInitSound = TRUE; 
  } 
   
  // 根據地圖需要,裝入地圖的音效,並指定音效的播放模式(位置,循環,根據時間片) 
  // 一般指定一個地圖背景音效,6至7個隨機播放的音效(例如鳥叫,風聲等等) 
  // 裝入特定的音效,是指特定的位置放置的音效,不停都在循環的那種,例如某處的水龍頭 
  // 還有一種音效只在觸發的時候才發生的.(一種是永遠都存放在內存的音效,例如鼠標按下,彈出,收起菜單對話框等等 
  //     []還有就是踫到某人某物發出的對話等等. 
   
  // 
  // Create the D3DRM object which are initialized only when the program 
  // starts 
  // 
  if (!CreateD3DRM(myglobs.hWndMain)) 
    return FALSE; 
  // 
  // Call D3DApp to initialize all DD and D3D objects necessary to render. 
  // D3DApp will call the device creation callback which will initialize the 
  // viewport and the sample's render states. 
  // 
  if (!CreateD3DApp(NULL)) 
    return FALSE; 
   
  // 
  // Create the scene to be rendered by calling this sample's BuildScene 
  // 
  AddMediaPath(g_lpD3DRM); 
 
  char cPlayMidiFile[256];		//根據需要從地圖結構中讀出Midi文件 
//  sprintf(cPlayMidiFile,"%s\\midi\\midi%02d.mp3",g_tszPathName,1); 
 
//  g_Music = new CMusicPlayer; 
//  if(g_Music->OpenFile(cPlayMidiFile)) 
//  { 
//    g_Music->Play(); 
//  } 
//  else 
//  { 
    sprintf(cPlayMidiFile,"%s\\midi\\midi%02d.mid",g_tszPathName,1); 
    PlayMidi(cPlayMidiFile); 
    if(g_bSoundPaused) 
    { 
      PauseMidi(); 
    } 
//  } 
  /* 
  if (!D3DAppFullscreen(d3dapp->CurrMode-1)) 
  { 
		ReportD3DAppError(); 
    CleanUpAndPostQuit(); 
    QuitDirectMusic(); 
    QuitResolution(); 
    QuitIME(m_hWnd); 
    exit(1); 
    } 
  */ 
   
  // 
  // 初始化2維的圖象畫面 
  // 
  Free2DSurfaces(); 
  Create2DSurfaces( d3dapp->lpDD ); 
   
  m_SplashWnd.DestroyWindow();	//撤消彈出窗口 
   
  if(Check555or565()) 
  { 
    g_Show555 = TRUE; 
  } 
  else 
  { 
    g_Show555 = FALSE; 
  } 
   
  SetTimer(1,20000,NULL);	//每20秒做一次下修改玩家的精和氣,玩家的飲食 
  //SetTimer(2,900000,NULL); 
  SetTimer(3,5000,NULL);	//每5分鐘檢查以下玩家的狀態(打坐或吐納) 
  SetTimer(TIMER_CURSOR,400,NULL);	//每400毫秒畫光標一次 
  ShowCursor(TRUE); 
  SetCursorPos(DEFULTWND_WIDTH/2,DEFULTWND_HEIGHT/2); 
  g_nGameState = GAME_SETUP; 
  bstartrend = TRUE; 
  return 0; 
} 
 
// 
// CreateD3DRM 
// Create main D3DRM objects which are only initialized once. 
// 
BOOL CreateD3DRM(HWND win) 
{ 
  HRESULT rval; 
   
  // 
  // Create the D3DRM object 
  // 
  LPDIRECT3DRM pD3DRM; 
   
  rval = Direct3DRMCreate(&pD3DRM); 
  if (rval != D3DRM_OK) 
  { 
    Msg("Failed to create Direct3DRM.\n%s", D3DAppErrorToString(rval)); 
    return FALSE; 
  } 
   
  rval = pD3DRM->QueryInterface(IID_IDirect3DRM3, (LPVOID *)&g_lpD3DRM); 
   
  pD3DRM->Release(); 
   
  if (rval != D3DRM_OK) 
  { 
    Msg("Failed to QI for IID_IDirect3DRM3.\n%s", D3DAppErrorToString(rval)); 
    return FALSE; 
  } 
   
  // 
  // 建立主場景和攝像機場景 
  // Create the master scene frame and camera frame 
  // 
  rval = g_lpD3DRM->CreateFrame(NULL, &myglobs.scene); 
  if (rval != D3DRM_OK) 
  { 
    Msg("Failed to create the master scene frame.\n%s", D3DAppErrorToString(rval)); 
    return FALSE; 
  } 
  rval = g_lpD3DRM->CreateFrame(myglobs.scene, &myglobs.camera); 
  if (rval != D3DRM_OK) 
  { 
    Msg("Failed to create the camera's frame.\n%s", D3DAppErrorToString(rval)); 
    return FALSE; 
  } 
  rval = myglobs.camera->SetPosition(myglobs.scene, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0)); 
  if (rval != D3DRM_OK) 
  { 
    Msg("Failed to position the camera in the frame.\n%s", D3DAppErrorToString(rval)); 
    return FALSE; 
  } 
  return TRUE; 
} 
 
// 
// CreateD3DApp 
// Create all DirectDraw and Direct3D objects necessary to begin rendering. 
// Add the list of D3D drivers to the file menu. 
// 
BOOL CreateD3DApp(LPSTR lpCmdLine) 
{ 
  BOOL bOnlySystemMemory, bOnlyEmulation; 
  DWORD flags; 
   
  // 
  // Parse the command line in seach of one of the following options: 
  //     systemmemory  All surfaces should be created in system memory. 
  //                   Hardware DD and D3D devices are disabled, but 
  //                   debugging during the Win16 lock becomes possible. 
  //     emulation     Do not use hardware DD or D3D devices. 
  // 
  bOnlySystemMemory = FALSE; 
  bOnlyEmulation = FALSE; 
  // 
  // Set the flags to pass to the D3DApp creation based on command line 
  // 
  flags = ((bOnlySystemMemory) ? D3DAPP_ONLYSYSTEMMEMORY : 0) | 
    ((bOnlyEmulation) ? (D3DAPP_ONLYD3DEMULATION | 
    D3DAPP_ONLYDDEMULATION) : 0); 
    /* 
    * Create all the DirectDraw and D3D objects neccesary to render.  The 
    * AfterDeviceCreated callback function is called by D3DApp to create the 
    * viewport and the example's execute buffers. 
  */ 
  if (!D3DAppCreateFromHWND(flags, myglobs.hWndMain, 
    myglobs.DDDriver[myglobs.CurrDDDriver].bIsPrimary ? NULL : &myglobs.DDDriver[myglobs.CurrDDDriver].Guid, 
    AfterDeviceCreated, 
    NULL, 
    BeforeDeviceDestroyed, 
    NULL, 
    &d3dapp)) 
  { 
    ReportD3DAppError(); 
    return FALSE; 
  } 
  return TRUE; 
} 
 
// 
// AfterDeviceCreated 
// D3DApp will call this function immediately after the D3D device has been 
// created (or re-created).  D3DApp expects the D3D viewport to be created and 
// returned.  In this case, we will return NULL because we only have a D3DRM 
// viewport.  This is fine as long as we don't use any of the D3D viewport 
// functionality of D3DApp. 
// 
BOOL AfterDeviceCreated(int w, int h, LPDIRECT3DVIEWPORT* lplpViewport, LPVOID lpContext) 
{ 
  HRESULT rval; 
   
  rval = g_lpD3DRM->CreateDeviceFromD3D(d3dapp->lpD3D, d3dapp->lpD3DDevice, &myglobs.dev); 
  if (rval != D3DRM_OK) { 
    Msg("Creation of D3DRM device failed.\n%s", D3DAppErrorToString(rval)); 
    return FALSE; 
  } 
  // 
  // Create the D3DRM viewport using the camera frame.  Set the background 
  // depth to a large number.  The width and height may be slightly 
  // adjusted, so get them from the device to be sure. 
  // 
  w = myglobs.dev->GetWidth(); 
  h = myglobs.dev->GetHeight(); 
   
  //	MAINFACEYPOS 
  //	MAINFACEXPOS 
  //	w = MAINFACEWIELD; 
  //	h = MAINFACEHIGH; 
  rval = g_lpD3DRM->CreateViewport(myglobs.dev, myglobs.camera, 
    0, 0, 
    w,h, 
    &myglobs.view); 
  if (rval != D3DRM_OK) { 
    Msg("Failed to create the D3DRM viewport.\n%s", 
      D3DAppErrorToString(rval)); 
    RELEASE(myglobs.dev); 
    return FALSE; 
  } 
  // 
  //以下的指令是我增加的add line 
  // 
  //	myglobs.dev->SetRenderMode(D3DRMRENDERMODE_BLENDEDTRANSPARENCY| 
  //			D3DRMRENDERMODE_SORTEDTRANSPARENCY);//影子是對于所有的先貼圖的字或者是其他物體都是半透明的 
  //	myglobs.dev->SetRenderMode(D3DRMRENDERMODE_BLENDEDTRANSPARENCY| 
  //			D3DRMRENDERMODE_SORTEDTRANSPARENCY|D3DRENDERSTATE_BLENDENABLE ); 
  rval = myglobs.view->SetBack(800.0f); //D3DVAL(5000.0) 
  if (rval != D3DRM_OK) { 
    Msg("Failed to set the back clipping plane of the D3DRM viewport.\n%s", 
      D3DAppErrorToString(rval)); 
    RELEASE(myglobs.dev); 
    RELEASE(myglobs.view); 
    return FALSE; 
  } 
  rval = myglobs.view->SetFront(1.0f); 
  if (rval != D3DRM_OK) { 
    Msg("Failed to set the front clipping plane of the D3DRM viewport.\n%s", 
      D3DAppErrorToString(rval)); 
    RELEASE(myglobs.dev); 
    RELEASE(myglobs.view); 
    return FALSE; 
  } 
   
  // 
  // Set the render quality, fill mode, lighting state and color shade info 
  // 
  if (!SetRenderState()) 
    return FALSE; 
   
  // 
  // Return NULL for the viewport 
  // 
  *lplpViewport = NULL; 
  // 
  // Create and initialize the surfaces containing the frame rate and 
  // window information 
  // 
  InitFontAndTextBuffers(); 
   
  return TRUE; 
} 
 
// 
// SetRenderState 
// Set the render quality, dither toggle and shade info if any of them has 
// changed 
// 
BOOL SetRenderState(void) 
{ 
  HRESULT rval; 
  /* 
  * Set the number of buffers so D3DRM can keep track of extents properly 
  */ 
  rval = myglobs.dev->SetBufferCount(d3dapp->bFullscreen && d3dapp->bBackBufferInVideo ? 2 : 1); 
  if (rval != D3DRM_OK) 
  { 
    Msg("Setting the buffer count failed.\n%s", D3DAppErrorToString(rval)); 
    return FALSE; 
  } 
   
  // 
  // Set the render quality (light toggle, fill mode, shade mode) 
  // 
  if (myglobs.dev->GetQuality() != myglobs.RenderQuality) 
  { 
    rval = myglobs.dev->SetQuality(myglobs.RenderQuality); 
    if (rval != D3DRM_OK) 
    { 
      Msg("Setting the render quality failed.\n%s", 
        D3DAppErrorToString(rval)); 
      return FALSE; 
    } 
  } 
  // 
  // Set dithering toggle 
  // 
  if (myglobs.dev->GetDither() != myglobs.bDithering) 
  { 
    rval = myglobs.dev->SetDither(myglobs.bDithering); 
    if (rval != D3DRM_OK)  
    { 
      Msg("Setting dither mode failed.\n%s", D3DAppErrorToString(rval)); 
      return FALSE; 
    } 
  } 
  // 
  // Set the texture quality (point or linear filtering) 
  // 
  if (myglobs.dev->GetTextureQuality() != myglobs.TextureQuality)  
  { 
    rval = myglobs.dev->SetTextureQuality(myglobs.TextureQuality); 
    if (rval != D3DRM_OK)  
    { 
      Msg("Setting texture quality failed.\n%s", 
        D3DAppErrorToString(rval)); 
      return FALSE; 
    } 
  } 
  // 
  // Set shade info based on current bits per pixel 
  // 
  switch (d3dapp->ThisMode.bpp) 
  { 
  case 1: 
    if (FAILED(myglobs.dev->SetShades(4))) 
      goto shades_error; 
    if (FAILED(g_lpD3DRM->SetDefaultTextureShades(4))) 
      goto shades_error; 
    break; 
  case 16: 
    if (FAILED(myglobs.dev->SetShades(32))) 
      goto shades_error; 
    if (FAILED(g_lpD3DRM->SetDefaultTextureColors(64))) 
      goto shades_error; 
    if (FAILED(g_lpD3DRM->SetDefaultTextureShades(32))) 
      goto shades_error; 
    break; 
  case 24: 
  case 32: 
    if (FAILED(myglobs.dev->SetShades(256))) 
      goto shades_error; 
    if (FAILED(g_lpD3DRM->SetDefaultTextureColors(64))) 
      goto shades_error; 
    if (FAILED(g_lpD3DRM->SetDefaultTextureShades(256))) 
      goto shades_error; 
    break; 
  } 
  return TRUE; 
shades_error: 
  Msg("A failure occurred while setting color shade information.\n"); 
  return FALSE; 
} 
 
// 
// BeforeDeviceDestroyed 
// D3DApp will call this function before the current D3D device is destroyed 
// to give the app the opportunity to destroy objects it has created with the 
// DD or D3D objects. 
// 
BOOL BeforeDeviceDestroyed(LPVOID lpContext) 
{ 
  RELEASE(myglobs.view); 
  RELEASE(myglobs.dev); 
  return TRUE; 
} 
 
//----------------------------------------------------------------------------- 
// Name: AddMediaPath() 
// Desc: Looks in the system registry to determine the media path for the 
//       sample. Then, it adds that path to the string passed in, checks if the 
//       file exists, and returns a path to the file. 
//----------------------------------------------------------------------------- 
VOID AddMediaPath( LPDIRECT3DRM3 pD3DRM ) 
{ 
  TCHAR  strPath[512]; 
   
  lstrcpy( strPath, g_tszPathName ); 
  lstrcat( strPath, "\\Media" ); 
   
  pD3DRM->AddSearchPath( strPath ); 
   
  return; 
} 
 
//************************************************************************* 
//  Windows message handlers 
//************************************************************************ 
// 
// AppAbout 
// About box message handler 
// 
BOOL FAR PASCAL AppAbout(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
  switch (msg) 
  { 
  case WM_COMMAND: 
    if (LOWORD(wParam) == IDOK) 
    { 
      PlaySoundDS(CLOSEMENU,pSysSoundPos,0);//播放聲音 
      EndDialog(hwnd, TRUE); 
    } 
    break; 
  case WM_INITDIALOG: 
    { 
      PlaySoundDS(OPENMENU,pSysSoundPos,0);//播放聲音 
      return TRUE; 
    } 
    break; 
  } 
  return FALSE; 
} 
 
// 
// 彈出信息輸入框 
// 
DWORD WINAPI DoInputMsg(LPVOID pv) 
{ 
//  m_InputMsg.DoModal(); 
//  PostMessage(myglobs.hWndMain, UM_MSG_ABORT, 0, 0); 
  return 0; 
} 
 
BOOL IsTraditionalChinese(BYTE b1,BYTE b2) 
{ 
  if(b1>=0x81&&b1<=0xFE) 
  { 
    if(b2>=0x40&&b2<=0x7E) return TRUE; 
    if(b2>=0xA1&&b2<=0xFE) return TRUE; 
  } 
  return FALSE; 
} 
 
BOOL IsStringChinese(CString s,long p) 
{ 
  BOOL b; 
  long i; 
  for(i=0;i 5000) 
								iVer = iRandom - VERSION/1000; 
							else 
								iVer = iRandom + VERSION/1000; 
							iRandom++; 
							if(iRandom>9999999) 
								iRandom=0; 
							sprintf(szTemp,"%d",iRandom); 
							sprintf(szTemp+8,"%d",iVer); 
//							ecb_crypt( ); 
							iRet=send(hSock,szTemp,16,0); 
							if(iRet==16){ 
								iRandom++; 
								if(iRandom>9999999) 
									iRandom=0; 
								Identified=1; 
							}else 
								SendMessage(WM_CLOSE,0,0); 
						}else if(Identified==1)	{ 
							int iTemp=atoi(szTemp); 
							if(iTemp==iRandom){ 
								Identified=2; 
								wsprintf(szSendBuf,"%s %s 1",szSysLog,szUserCount); 
								Send(); 
								g_nReceiveMsgState = SVRMSG_SYSLOG; 
							} 
							else 
								SendMessage(WM_CLOSE,0,0); 
						} 
					} 
					else 
						SendMessage(WM_CLOSE,0,0); 
				} 
			} 
			break; 
		case FD_WRITE: 
			{ 
				szSendBuf[0]='\0'; 
				int nReturn=Send(); 
				if(WS_ERROR==nReturn){ 
					Msg("連線傳送資料發生錯誤,稍後再試!"); 
				} 
			} 
			break; 
		case FD_CONNECT: 
			Identified=0; 
			break; 
		case FD_CLOSE: 
			if(!bCloseSocket){ 
				Msg("與人在江湖伺服器失去聯繫!"); 
				QuitDirectMusic(); 
				QuitResolution(); 
				QuitIME(m_hWnd); 
			} 
			else 
				bCloseSocket=FALSE; 
			break; 
		} 
        break; 
  case WM_KEYUP: 
    HandleKeyinUp(wParam,lParam); 
    break; 
  case WM_SYSKEYDOWN: 
  case WM_KEYDOWN: 
    HandleKeyinDown(wParam,lParam); 
		if(g_nGameState==GAME_SERVER){ 
			wgs.ControlAllEdit(wParam); 
			switch(wParam){ 
			case VK_RETURN: 
				if(ERR_LINK==wgs.Enter()){ 
					TCHAR	szTemp[50]; 
					wsprintf(szTemp,"%c12m無法執行連線作業,請檢查網路設定!%c10m",27,27); 
					wgs.AddMessage(szTemp); 
				} 
				break; 
			case VK_TAB: 
				wgs.Tab(); 
				break; 
			case VK_ESCAPE: 
				wgs.Exit(NULL); 
				break; 
			} 
		} 
		else 
    { 
      BOOL bCtrlDown = GetAsyncKeyState(VK_CONTROL)&0x8000; 
      BOOL bShiftDown = GetAsyncKeyState(VK_SHIFT)&0x8000; 
      BOOL bTabDown = GetAsyncKeyState(VK_TAB)&0x8000; 
      switch(wParam){ 
      case VK_RETURN: 
        if(g_nGameState==GAME_MAIN){ 
          if(g_szInputMsg.IsEmpty()) break; 
          if(bMsgChanged){ 
            if(g_szInputMsgList.GetCount() >= MSG_PIECE_NUMBER){ 
              g_szInputMsgList.RemoveHead();  
              g_szInputMsgList.AddTail(g_szInputMsg); 
            }else{ 
              g_szInputMsgList.AddTail(g_szInputMsg); 
            } 
            for(int i=0; i g_szInputMsg.GetLength()){ 
              g_nSelStart = g_szInputMsg.GetLength(); 
            } 
          } 
          g_nInputMsgPos = g_nSelEnd = g_szInputMsg.GetLength(); 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
        } 
        break; 
      case VK_F1: 
        { 
          CHelpAndVer m_HelpAndVer; 
          m_HelpAndVer.DoModal(); 
        } 
        break; 
      case VK_F2: 
        ShowSystemMessage=!ShowSystemMessage; 
        break; 
      case VK_F4: 
        myglobs.bShowFrameRate = !myglobs.bShowFrameRate; 
        g_Redraw3dFace[0] = TRUE; 
        g_Redraw3dFace[1] = TRUE; 
        break; 
      case VK_F5: 
        myglobs.g_bShowMessage = !myglobs.g_bShowMessage; 
        g_Redraw3dFace[0] = TRUE; 
        g_Redraw3dFace[1] = TRUE; 
        break; 
      case VK_F6: 
        if(m_MainScreen.mSecondFD.nShowState == EMT_SHOW_CHINESE){ 
          m_MainScreen.mSecondFD.nShowState = EMT_SHOW_ENGLISH; 
        }else{ 
          m_MainScreen.mSecondFD.nShowState = EMT_SHOW_CHINESE; 
        } 
        m_MainScreen.mSecondFD.bReDraw[0] = TRUE; 
        m_MainScreen.mSecondFD.bReDraw[1] = TRUE; 
        break; 
      case 'A': 
        if(g_nGameState != GAME_MAIN) break; 
        if(bCtrlDown) 
        { 
          g_nSelStart = 0; 
          g_nSelEnd = g_szInputMsg.GetLength(); 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
          bMsgChanged = TRUE; 
        } 
        break; 
      case 'Z': 
        if(g_nGameState != GAME_MAIN) break; 
        if(bCtrlDown) 
        { 
          CString szSwap; 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
          bMsgChanged = TRUE; 
          g_nInputMsgPos = szLastMsg.GetLength(); 
          szSwap = g_szInputMsg; 
          g_szInputMsg = szLastMsg; 
          szLastMsg = szSwap; 
        } 
        break; 
      case 'X': 
      case 'C': 
        if(g_nGameState != GAME_MAIN) break; 
        if(bCtrlDown) // Ctrl-C && Ctrl-X 
        { 
          HANDLE hData; 
          char * lpData; 
           
          //從輸入條得到剪貼板數據 
          CString StrSel; 
          StrSel = g_szInputMsg.Mid(g_nSelStart, g_nSelEnd-g_nSelStart); 
          strcpy(lpszText,(LPCTSTR)StrSel); 
           
          hData = GlobalAlloc(GMEM_DDESHARE, strlen(lpszText)+1); 
          if (!(hData))  
            break; 
          lpData = (char *)GlobalLock(hData); 
          if (!(lpData)) 
            break; 
          strcpy(lpData, lpszText); 
          GlobalUnlock(hData);					 
           
          if (OpenClipboard())  
          { 
            EmptyClipboard(); 
            SetClipboardData(CF_TEXT, hData); 
            CloseClipboard(); 
          } 
          hData = NULL; 
           
          if(wParam == 'X') 
          { 
            CString StrLeft,StrRight; 
            szLastMsg = g_szInputMsg; 
            StrLeft = g_szInputMsg.Left(g_nSelStart); 
            StrRight = g_szInputMsg.Right(g_szInputMsg.GetLength() - g_nSelEnd); 
            g_nInputMsgPos = g_nSelEnd = g_nSelStart; 
            m_MainScreen.bChangeInputMsg[0] = TRUE; 
            m_MainScreen.bChangeInputMsg[1] = TRUE; 
            bMsgChanged = TRUE; 
            g_szInputMsg = StrLeft + StrRight; 
          } 
        } 
        break; 
      case 'V': 
        if(g_nGameState != GAME_MAIN) break; 
        if(bCtrlDown) // Ctrl-V 
        { 
          //得到剪貼板數據 
          HANDLE hClipData; 
          char * lpClipData; 
          int nCopy; 
          int nSourPtr; 
          unsigned char ch,lastCh = 0; 
          CString StrLeft,StrSel,StrRight; 
           
          if (!OpenClipboard())  
            break; 
           
          hClipData = GetClipboardData(CF_TEXT); 
          if (!(hClipData))  
          { 
            CloseClipboard(); 
            break; 
          } 
          lpClipData = (char *)GlobalLock(hClipData); 
          if (!(lpClipData))  
          { 
            CloseClipboard(); 
            break; 
          } 
          //先計算各個字串 
          if(g_nSelStart == g_nSelEnd) 
          { 
            g_nSelStart = g_nSelEnd = g_nInputMsgPos; 
          } 
          szLastMsg = g_szInputMsg; 
          StrLeft = g_szInputMsg.Left(g_nSelStart); 
          StrRight = g_szInputMsg.Right(g_szInputMsg.GetLength() - g_nSelEnd); 
          g_szInputMsg = StrLeft + StrRight; 
          lpszText[0] = 0; 
          //防止不可顯示字元的拷貝 
          for(nSourPtr=nCopy=0; nSourPtr < (signed) GlobalSize(hClipData) ; nSourPtr++) 
          { 
            ch = (unsigned)lpClipData[nSourPtr]; 
            if(ch == 0) 
              break; 
            if(ch < ' ') 
              continue; 
            if(ch == '&') 
              continue; 
            //lastCh存放漢字的區碼. 
            if(lastCh != 0) 
            { 
              if(ch < 64) 
                lastCh = 0; 
            } 
            else if(ch > 160) 
            { 
              lastCh = ch; 
              continue; 
            } 
             
            StrSel = g_szInputMsg; 
            StrSel += lpszText; 
            StrSel += ch; 
            if( lastCh ) 
              StrSel += lastCh; 
            if( GetStrWidth(StrSel, TRUE) <= MSG_WIDTH_LEN ) 
            { 
              if( lastCh ) 
              { 
                lpszText[nCopy++] = (signed)lastCh; 
                lpszText[nCopy++] = (signed)ch; 
                lastCh = 0; 
              } 
              else 
                lpszText[nCopy++] = (signed)ch; 
              lpszText[nCopy] = 0; 
            } 
            else break; 
            lastCh = 0; 
          } 
          lpszText[nCopy] = 0; 
           
          GlobalUnlock(hClipData); 
          CloseClipboard(); 
           
          //加入剪貼板數據到輸入條 
          g_nSelEnd = g_nSelStart; 
          StrSel = lpszText; 
          g_nInputMsgPos = g_nSelStart + StrSel.GetLength(); 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
          bMsgChanged = TRUE; 
          g_szInputMsg = StrLeft + StrSel + StrRight; 
        } 
        break; 
      case VK_UP: // 向上鍵 
        if(g_nGameState != GAME_MAIN) break; 
        if(bCtrlDown) // Ctrl-Up 
        { 
          if (g_fCamfov < 0.3f) break; 
          g_fCamfov -= 0.1f; 
          myglobs.view->SetField( g_fCamfov ); 
        } 
        else 
        { 
          if(nNowInWhere > 0) 
          { 
            if(nNowInWhere < g_szInputMsgList.GetCount()) 
            { 
              nInputPos[nNowInWhere] = g_nInputMsgPos; 
              g_szInputMsgList.GetAt(g_szInputMsgList.FindIndex(nNowInWhere)) = g_szInputMsg; 
            } 
            else 
            { 
              szLastMsg = g_szInputMsg; 
            } 
            nNowInWhere = nNowInWhere - 1; 
            g_szInputMsg = g_szInputMsgList.GetAt(g_szInputMsgList.FindIndex(nNowInWhere)); 
            g_nInputMsgPos = nInputPos[nNowInWhere]; 
            g_nSelStart = 0; 
            g_nSelEnd = g_szInputMsg.GetLength(); 
            bMsgChanged = FALSE; 
            m_MainScreen.bChangeInputMsg[0] = TRUE; 
            m_MainScreen.bChangeInputMsg[1] = TRUE; 
          } 
        } 
        break; 
      case VK_DOWN: // 向下鍵 
        if(g_nGameState != GAME_MAIN) break; 
        if(bCtrlDown) // Ctrl-Down 
        { 
          if (g_fCamfov > 0.3f) break; 
          g_fCamfov += 0.1f; 
          myglobs.view->SetField( g_fCamfov ); 
        } 
        else 
        { 
          if((nNowInWhere) < g_szInputMsgList.GetCount()) 
          { 
            nInputPos[nNowInWhere] = g_nInputMsgPos; 
            g_szInputMsgList.GetAt(g_szInputMsgList.FindIndex(nNowInWhere)) = g_szInputMsg; 
            nNowInWhere = nNowInWhere + 1; 
            if(nNowInWhere == g_szInputMsgList.GetCount()) 
            { 
              g_szInputMsg = szLastMsg; 
              g_nInputMsgPos = szLastMsg.GetLength(); 
              g_nSelStart = 0; 
              g_nSelEnd = 0; 
            } 
            else 
            { 
              g_szInputMsg = g_szInputMsgList.GetAt(g_szInputMsgList.FindIndex(nNowInWhere)); 
              g_nInputMsgPos = nInputPos[nNowInWhere]; 
              g_nSelStart = 0; 
              g_nSelEnd = g_szInputMsg.GetLength(); 
            } 
            bMsgChanged = FALSE; 
            m_MainScreen.bChangeInputMsg[0] = TRUE; 
            m_MainScreen.bChangeInputMsg[1] = TRUE; 
          } 
        } 
        break; 
      case VK_LEFT: // 左 
        if(g_nGameState != GAME_MAIN) break; 
        if((!bCtrlDown)&&(!bShiftDown)&&(g_nSelStart != g_nSelEnd)) 
        { 
          g_nInputMsgPos = g_nSelEnd = g_nSelStart; 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
          break; 
        } 
        if((!bCtrlDown)&&(g_nInputMsgPos <= 0)) 
        { 
          g_nInputMsgPos = 0; 
          break; 
        } 
        if(bShiftDown) 
        { 
          if( g_nSelStart == g_nSelEnd ) 
            g_nSelEnd = g_nInputMsgPos; 
          else if(g_nSelStart == g_nInputMsgPos) 
            g_nSelStart = 10000; 
          else if(g_nSelEnd == g_nInputMsgPos) 
            g_nSelEnd = 10000; 
          else 
            g_nSelEnd = g_nInputMsgPos; 
        } 
        if(!bCtrlDown) // Left 
        { 
          if(IsStringChinese(g_szInputMsg,g_nInputMsgPos)) 
          { 
            g_nInputMsgPos-=2; 
          } 
          else 
          { 
            g_nInputMsgPos--; 
          } 
        } 
        else // Ctrl-Left 
        { 
          iPos++; 
          if(iPos>=360) iPos-=360; 
          SetCammerPos(iPos); 
/* 
          char ch; 
          g_nInputMsgPos--; 
          ch = g_szInputMsg.GetAt(g_nInputMsgPos); 
          if(IsChar(ch)) 
          { 
            do  
            { 
              ch = g_szInputMsg.GetAt(g_nInputMsgPos); 
              if( ! IsChar(ch)) 
              { 
                g_nInputMsgPos++; 
                break; 
              } 
              g_nInputMsgPos--; 
            } while(g_nInputMsgPos >= 0); 
          } 
          else if(IsDBCSLeadByte(ch)) 
          { 
            do  
            { 
              ch = g_szInputMsg.GetAt(g_nInputMsgPos); 
              if( ! IsDBCSLeadByte(ch)) 
              { 
                g_nInputMsgPos++; 
                break; 
              } 
              g_nInputMsgPos--; 
            } while(g_nInputMsgPos >= 0); 
          } 
          if(g_nInputMsgPos < 0) 
          { 
            g_nInputMsgPos = 0; 
          } 
*/ 
        } 
        if(bShiftDown) 
        { 
          if( g_nSelEnd == 10000 ) 
            g_nSelEnd = g_nInputMsgPos; 
          else 
            g_nSelStart = g_nInputMsgPos; 
          if(g_nSelStart > g_nSelEnd) 
          { 
            int nSwap; 
            nSwap = g_nSelStart; 
            g_nSelStart = g_nSelEnd; 
            g_nSelEnd = nSwap; 
          } 
        } 
        if(!bCtrlDown) 
        { 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
        } 
        break; 
      case VK_RIGHT: // 右 
        if(g_nGameState != GAME_MAIN) break; 
        if((!bCtrlDown)&&(!bShiftDown)&&(g_nSelStart != g_nSelEnd)) 
        { 
          g_nInputMsgPos = g_nSelStart = g_nSelEnd; 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
          break; 
        } 
        if((!bCtrlDown)&&(g_nInputMsgPos >= g_szInputMsg.GetLength())) 
        { 
          g_nInputMsgPos = g_szInputMsg.GetLength(); 
          break; 
        } 
        if(bShiftDown) 
        { 
          if( g_nSelStart == g_nSelEnd ) 
            g_nSelStart = g_nInputMsgPos; 
          else if(g_nSelStart == g_nInputMsgPos) 
            g_nSelStart = 10000; 
          else if(g_nSelEnd == g_nInputMsgPos) 
            g_nSelEnd = 10000; 
          else 
            g_nSelStart = g_nInputMsgPos; 
        } 
        if(!bCtrlDown) // Right 
        { 
          g_nInputMsgPos++; 
          if(g_nInputMsgPos < g_szInputMsg.GetLength()) 
          { 
            if(g_nInputMsgPos&&IsDBCSLeadByte(g_szInputMsg.GetAt(g_nInputMsgPos-1))) 
            { 
              g_nInputMsgPos++; 
            } 
          } 
        } 
        else // Ctrl-Right 
        { 
          iPos--; 
          if(iPos<=0) iPos+=360; 
          SetCammerPos(iPos); 
/* 
          char ch; 
          ch = g_szInputMsg.GetAt(g_nInputMsgPos); 
          g_nInputMsgPos++; 
          if( g_nInputMsgPos >= g_szInputMsg.GetLength()) 
          { 
          } 
          else if(IsChar(ch)) 
          { 
            do  
            { 
              ch = g_szInputMsg.GetAt(g_nInputMsgPos); 
              g_nInputMsgPos++; 
              if( ! IsChar(ch)) 
              { 
                g_nInputMsgPos--; 
                break; 
              } 
            } while(g_nInputMsgPos < g_szInputMsg.GetLength()); 
          } 
          else if(IsDBCSLeadByte(ch)) 
          { 
            do  
            { 
              ch = g_szInputMsg.GetAt(g_nInputMsgPos); 
              g_nInputMsgPos++; 
              if( ! IsDBCSLeadByte(ch)) 
              { 
                g_nInputMsgPos--; 
                break; 
              } 
            } while(g_nInputMsgPos < g_szInputMsg.GetLength()); 
          } 
*/ 
        } 
        if(bShiftDown) 
        { 
          if( g_nSelStart == 10000 ) 
            g_nSelStart = g_nInputMsgPos; 
          else 
            g_nSelEnd = g_nInputMsgPos; 
          if(g_nSelStart > g_nSelEnd) 
          { 
            int nSwap; 
            nSwap = g_nSelStart; 
            g_nSelStart = g_nSelEnd; 
            g_nSelEnd = nSwap; 
          } 
        } 
        if(!bCtrlDown) 
        { 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
        } 
        break; 
      case VK_HOME: 
        if(g_nGameState != GAME_MAIN) break; 
        if((!bCtrlDown)&&(!bShiftDown)&&(!bTabDown))//Home 
        { 
          g_nInputMsgPos = 0; 
          g_nSelStart = 0; 
          g_nSelEnd = 0; 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
        } 
        else if((!bCtrlDown)&&(bShiftDown)&&(!bTabDown))//Shift + Home 
        { 
          if( g_nSelStart == g_nSelEnd )//如果沒有選擇字串 
          { 
            g_nSelEnd = g_nInputMsgPos; 
          } 
          g_nSelStart = g_nInputMsgPos = 0; 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
        } 
        else if((bCtrlDown)&&(!bShiftDown)&&(!bTabDown))//Ctrl + Home 
        { 
          if((nNowInWhere) > 0) 
          { 
            if(nNowInWhere < g_szInputMsgList.GetCount()) 
            { 
              nInputPos[nNowInWhere] = g_nInputMsgPos; 
              g_szInputMsgList.GetAt(g_szInputMsgList.FindIndex(nNowInWhere)) = g_szInputMsg; 
            } 
            else 
            { 
              szLastMsg = g_szInputMsg; 
            } 
            nNowInWhere = 0; 
            g_szInputMsg = g_szInputMsgList.GetAt(g_szInputMsgList.FindIndex(nNowInWhere)); 
            g_nInputMsgPos = nInputPos[nNowInWhere]; 
            g_nSelStart = 0; 
            g_nSelEnd = g_szInputMsg.GetLength(); 
            bMsgChanged = FALSE; 
            m_MainScreen.bChangeInputMsg[0] = TRUE; 
            m_MainScreen.bChangeInputMsg[1] = TRUE; 
          } 
        } 
//        else if((!bCtrlDown)&&(!bShiftDown)&&(bTabDown))//Tab + Home 
//        { 
//          if (g_fCamfov < 0.3f) break; 
//          g_fCamfov -= 0.1f; 
//          myglobs.view->SetField( g_fCamfov ); 
//        } 
        break; 
      case VK_END: 
        if(g_nGameState != GAME_MAIN) break; 
        if((!bCtrlDown)&&(!bShiftDown)&&(!bTabDown))//End 
        { 
          g_nSelStart = 0; 
          g_nSelEnd = 0; 
          g_nInputMsgPos = g_szInputMsg.GetLength(); 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
        } 
        else if((!bCtrlDown)&&(bShiftDown)&&(!bTabDown))//Shift + End 
        { 
          if( g_nSelStart == g_nSelEnd )//如果沒有選擇字串 
          { 
            g_nSelStart = g_nInputMsgPos; 
          } 
          g_nSelEnd = g_nInputMsgPos = g_szInputMsg.GetLength(); 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
        } 
        else if((bCtrlDown)&&(!bShiftDown)&&(!bTabDown))//Ctrl + End 
        { 
          if((nNowInWhere+1) < g_szInputMsgList.GetCount()) 
          { 
            nInputPos[nNowInWhere] = g_nInputMsgPos; 
            g_szInputMsgList.GetAt(g_szInputMsgList.FindIndex(nNowInWhere)) = g_szInputMsg; 
            nNowInWhere = g_szInputMsgList.GetCount()-1; 
            g_szInputMsg = g_szInputMsgList.GetAt(g_szInputMsgList.FindIndex(nNowInWhere)); 
            g_nInputMsgPos = nInputPos[nNowInWhere]; 
            g_nSelStart = 0; 
            g_nSelEnd = g_szInputMsg.GetLength(); 
            bMsgChanged = FALSE; 
            m_MainScreen.bChangeInputMsg[0] = TRUE; 
            m_MainScreen.bChangeInputMsg[1] = TRUE; 
          } 
        } 
//        else if((!bCtrlDown)&&(!bShiftDown)&&(bTabDown))//Tab + End 
//        { 
//          if (g_fCamfov > 0.3f) break; 
//          g_fCamfov += 0.1f; 
//          myglobs.view->SetField( g_fCamfov ); 
//        } 
        break; 
      case VK_NEXT: 
        if(g_nGameState != GAME_MAIN) break; 
        myglobs.camera->GetPosition(myglobs.scene, ¤tpos); 
        myglobs.camera->SetPosition(myglobs.scene, currentpos.x, currentpos.y+1.0f, currentpos.z); 
        myglobs.camera->LookAt( g_lpplayer, myglobs.scene, D3DRMCONSTRAIN_Z); 
        myglobs.camera->GetPosition(myglobs.scene,&g_CameraPosition); 
//        if(bTabDown) 
//        { 
//          iPos--; 
//          if(iPos<=0) iPos+=360; 
//          SetCammerPos(iPos); 
//        } 
        break; 
      case VK_DELETE: 
        if(g_nGameState != GAME_MAIN) break; 
        if((!bTabDown)&&(!bCtrlDown))//Delete 
        { 
          szLastMsg = g_szInputMsg; 
          if( g_nSelStart == g_nSelEnd ) 
          { 
            CString StrLeft, StrRight; 
            StrLeft = g_szInputMsg.Left(g_nInputMsgPos); 
            StrRight = g_szInputMsg.Right(g_szInputMsg.GetLength() - g_nInputMsgPos); 
            //光標右邊有字元 
            if(! StrRight.IsEmpty()) 
            { 
              //如果輸入的也是中文,則一個中文替掉一個中文 
              if(!IsDBCSLeadByte(StrRight.GetAt(0))) 
              { 
                if(StrRight.GetLength() > 1) 
                  StrRight = StrRight.Right(StrRight.GetLength() - 1); 
                else 
                  StrRight.Empty(); 
              } 
              else 
              { 
                if(StrRight.GetLength() > 2) 
                  StrRight = StrRight.Right(StrRight.GetLength() - 2); 
                else 
                  StrRight.Empty(); 
              } 
            } 
            g_szInputMsg = StrLeft + StrRight; 
            m_MainScreen.bChangeInputMsg[0] = TRUE; 
            m_MainScreen.bChangeInputMsg[1] = TRUE; 
          } 
          else//如果選擇的有東西 
          { 
            CString StrLeft,StrSel,StrRight; 
            StrLeft = g_szInputMsg.Left(g_nSelStart); 
            StrSel = g_szInputMsg.Mid(g_nSelStart, g_nSelEnd-g_nSelStart); 
            StrRight = g_szInputMsg.Right(g_szInputMsg.GetLength() - g_nSelEnd); 
            g_nSelEnd = g_nSelStart; 
            g_nInputMsgPos = g_nSelStart; 
            m_MainScreen.bChangeInputMsg[0] = TRUE; 
            m_MainScreen.bChangeInputMsg[1] = TRUE; 
            bMsgChanged = TRUE; 
            g_szInputMsg = StrLeft + StrRight; 
          } 
        } 
//        else if((bTabDown)&&(!bCtrlDown))//Tab + Delete 
//        { 
//          iPos++; 
//          if(iPos>=360) iPos-=360; 
//          SetCammerPos(iPos); 
//        } 
        break; 
      case VK_PRIOR://下視角 
        if(g_nGameState != GAME_MAIN) break; 
        myglobs.camera->GetPosition(myglobs.scene, ¤tpos); 
        if(currentpos.y <= 1.0f)break; 
        myglobs.camera->SetPosition(myglobs.scene, currentpos.x, currentpos.y-1.0f, currentpos.z); 
        myglobs.camera->LookAt(g_lpplayer, myglobs.scene, D3DRMCONSTRAIN_Z); 
        myglobs.camera->GetPosition(myglobs.scene,&g_CameraPosition); 
//        if(bTabDown) 
//        { 
//          myglobs.camera->GetPosition(myglobs.scene, ¤tpos); 
//          if(currentpos.y <= 1.0f)break; 
//          myglobs.camera->SetPosition( myglobs.scene, currentpos.x, currentpos.y-1.0f, currentpos.z); 
//          myglobs.camera->LookAt( g_lpplayer, myglobs.scene, D3DRMCONSTRAIN_Z); 
//        } 
        break; 
      case VK_INSERT://抬高視角 
        if(g_nGameState != GAME_MAIN) break; 
        if(!bTabDown)//Insert 
        { 
          bInsertState = !bInsertState; 
          m_MainScreen.bChangeInputMsg[0] = TRUE; 
          m_MainScreen.bChangeInputMsg[1] = TRUE; 
        } 
//        else//Tab + Insert  
//        {	 
//          myglobs.camera->GetPosition(myglobs.scene, ¤tpos); 
//          myglobs.camera->SetPosition( myglobs.scene, currentpos.x, currentpos.y+1.0f, currentpos.z); 
//          myglobs.camera->LookAt( g_lpplayer, myglobs.scene, D3DRMCONSTRAIN_Z); 
//        } 
        break; 
      } 
    } 
    break; 
  case WM_INPUTLANGCHANGE: 
    HandleLangChange(m_hWnd,wParam,lParam); 
    break; 
  case WM_IME_STARTCOMPOSITION: 
    return HandleStartComposition(m_hWnd,wParam,lParam); 
  case WM_IME_ENDCOMPOSITION: 
    return HandleEndComposition(m_hWnd,wParam,lParam); 
  case WM_IME_COMPOSITION: 
    return HandleComposition(m_hWnd,wParam,lParam); 
  case WM_IME_NOTIFY: 
    switch(wParam) 
    { 
    case IMN_OPENSTATUSWINDOW: 
    case IMN_CLOSESTATUSWINDOW: 
      return 1L; 
    case IMN_GUIDELINE: 
      HandleGuideLine(m_hWnd,wParam,lParam); 
      break; 
    case IMN_SETCONVERSIONMODE: 
      HandleSetConversionMode(m_hWnd,wParam,lParam); 
      break; 
    case IMN_OPENCANDIDATE: 
      if(lParam==0x01) return HandleOpenCandidate(m_hWnd,wParam,lParam); 
      break; 
    case IMN_CHANGECANDIDATE: 
      if(lParam==0x01) return HandleChangeCandidate(m_hWnd,wParam,lParam); 
      break; 
    case IMN_CLOSECANDIDATE: 
      if(lParam==0x01) return HandleCloseCandidate(m_hWnd,wParam,lParam); 
      break; 
    case IMN_PRIVATE: 
      return 1L; 
    } 
    break; 
/*cary 
  case UM_SERVERMSG: 
    { 
      if(gSendToSvrThread)//如果發送到服務器線程是開啟的,則結束它 
      { 
        WaitForSingleObject(gSendToSvrThread, INFINITE); 
        CloseHandle(gSendToSvrThread); 
        gSendToSvrThread = NULL; 
      } 
      ExplainSvrMsg();//解釋發送請求並收回的服務器數據 
    } 
    break; 
  case UM_SERVERACTIVEMSG://服務器主動發來的信息 
    { 
      SrvSendMsg();//解釋發送請求並收回的服務器數據 
    } 
    break; 
  case UM_SERBREAK: 
    { 
      Msg("與伺服器失去聯繫"); 
      QuitDirectMusic(); 
      QuitResolution(); 
      QuitIME(m_hWnd); 
      exit(1); 
      // 
      //[???] 
      // 
    } 
    break; 
  case UM_CHANGEMAP: 
    { 
      //顯示信息,在信息條中增加 
      //暫停染色,遊戲進入waitting狀態 
      g_nGameState = GAME_WAIT;//不鼠標或者其他接受消息 
      g_nReceiveMsgState = SVRMSG_CHANGEMAP; 
      nSpareTime = MAXLOADMAPTIME; 
      nRecTimes = 0; 
      //AppPause(TRUE); 
      //發送並開始接受服務器消息 
      DWORD dwSendSvr; 
      gSendToSvrThread = CreateThread(NULL, 0, ( LPTHREAD_START_ROUTINE )SendToServer, 0, 0, &dwSendSvr); 
      if(!gSendToSvrThread) 
      { 
        Msg("Sorry Create SendToServer Thread!"); 
        return FALSE; 
      } 
      //重新建立3D場景,並進入GAME_MAIN狀態 
    } 
end*/ 
//  case UM_MSG_ABORT: 
//    if(gInputMesThread) 
//    { 
//      WaitForSingleObject(gInputMesThread, INFINITE); 
//      CloseHandle(gInputMesThread); 
//      gInputMesThread = NULL; 
//      return 1; 
//    } 
  case MM_MCINOTIFY: 
    { 
      if (wParam == MCI_NOTIFY_SUCCESSFUL) 
      { 
        char cPlayMidiFile[256]; 
        sprintf(cPlayMidiFile,"%s\\midi\\midi%02d.mid",g_tszPathName,(rand()%4)+1); 
        PlayMidi(cPlayMidiFile); 
      } 
    } 
    break; 
  case WM_DESTROY: 
    KillTimer(TIMER_CURSOR); 
    QuitDirectMusic(); 
    QuitResolution(); 
    QuitIME(m_hWnd); 
    ShowCursor(TRUE); 
    break; 
  default: 
    break; 
  } 
  if ((LOWORD(wParam) > IDR_MAINFRAME) 
    && (LOWORD(wParam) < (IDR_MAINFRAME+100))) 
  { 
    m_MainScreen.ShowQuickMsg(LOWORD(wParam) - IDR_MAINFRAME - 1); 
  } 
  return CWnd::WindowProc(message, wParam, lParam); 
} 
 
void CMainWnd::OnDestroy()  
{ 
  CWnd::OnDestroy(); 
} 
 
void CMainWnd::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
  switch(g_nGameState) 
  { 
  case GAME_SETUP: 
    m_StartGameMenu.GameSetupOnLButtonDown(point); 
    break; 
  case GAME_LOADPLAYER: 
    m_MenuLoadOldPlay.LoadPlayerOnLButtonDown(point); 
    break; 
  case GAME_CREATEPLAYER: 
    m_MenuCreateNew.CreateNewOnLButtonDown(point); 
    break; 
  case GAME_MAIN: 
    m_MainScreen.GameMainOnLButtonDown(point); 
    break; 
  case GAME_SERVER: 
	wgs.LButtonDown(point.x,point.y); 
	break; 
  default: 
    break; 
  } 
  CWnd::OnLButtonDown(nFlags, point); 
} 
 
void CMainWnd::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
  switch(g_nGameState) 
  { 
  case GAME_SETUP: 
    m_StartGameMenu.GameSetupOnLButtonUp(point); 
    break; 
  case GAME_LOADPLAYER: 
    m_MenuLoadOldPlay.LoadPlayerOnLButtonUp(point); 
    break; 
  case GAME_CREATEPLAYER: 
    m_MenuCreateNew.CreateNewOnLButtonUp(point); 
    break; 
  case GAME_MAIN: 
    m_MainScreen.GameMainOnLButtonUp(point); 
    break; 
  case GAME_SERVER: 
	int iReturn; 
	if(ERR_NO==(iReturn=wgs.LButtonUp(point.x,point.y))) 
		break; 
	else if(ERR_EXIT==iReturn){ 
		g_nGameState=GAME_SETUP; 
	}else if(ERR_LINK==iReturn){ 
		TCHAR	szTemp[50]; 
		wsprintf(szTemp,"%c12m無法執行連線作業,請檢查網路設定!%c10m",27,27); 
		wgs.AddMessage(szTemp); 
	} 
	break; 
  default: 
    break; 
  } 
  CWnd::OnLButtonUp(nFlags, point); 
} 
 
void CMainWnd::OnLButtonDblClk(UINT nFlags, CPoint point)  
{ 
  switch(g_nGameState) 
  { 
  case GAME_MAIN: 
    m_MainScreen.GameMainOnLButtonDblClk(point); 
    break; 
  default: 
    break; 
  } 
  CWnd::OnLButtonDblClk(nFlags, point); 
} 
 
void CMainWnd::OnMouseMove(UINT nFlags, CPoint point)  
{ 
  switch(g_nGameState) 
  { 
  case GAME_SETUP: 
    m_StartGameMenu.GameSetupOnMouseMove(point); 
    break; 
  case GAME_LOADPLAYER: 
    m_MenuLoadOldPlay.LoadPlayerOnMouseMove(point); 
    break; 
  case GAME_CREATEPLAYER: 
    m_MenuCreateNew.CreateNewOnMouseMove(point); 
    break; 
  case GAME_MAIN: 
    m_MainScreen.GameMainOnMouseMove(point); 
    break; 
  case GAME_SERVER: 
	break; 
  default: 
    break; 
  } 
  CWnd::OnMouseMove(nFlags, point); 
} 
 
void CMainWnd::OnRButtonDown(UINT nFlags, CPoint point)  
{ 
  switch(g_nGameState) 
  { 
  case GAME_SETUP: 
    m_StartGameMenu.GameSetupOnRButtonDown(point); 
    break; 
  case GAME_LOADPLAYER: 
    m_MenuLoadOldPlay.LoadPlayerOnRButtonDown(point); 
    break; 
  case GAME_CREATEPLAYER: 
    m_MenuCreateNew.CreateNewOnRButtonDown(point); 
    break; 
  case GAME_MAIN: 
    m_MainScreen.GameMainOnRButtonDown(point); 
    break; 
  case GAME_FIGHTREADY: 
    { 
      //停止轉動 
      myglobs.camera->DeleteMoveCallback(MoveCameraCallback,&info); 
      g_nGameState = GAME_MAIN; 
    } 
    break; 
  case GAME_SERVER: 
	break; 
  default: 
    break; 
  } 
  CWnd::OnRButtonDown(nFlags, point); 
} 
 
void CMainWnd::OnRButtonUp(UINT nFlags, CPoint point)  
{ 
  switch(g_nGameState) 
  { 
  case GAME_MAIN: 
    m_MainScreen.GameMainOnRButtonUp(point); 
    break; 
  default: 
    break; 
  } 
  CWnd::OnRButtonUp(nFlags, point); 
} 
 
void CMainWnd::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
 
	if(g_nGameState==GAME_SERVER){ 
		wgs.PutCharAllEdit(nChar,nRepCnt); 
		CWnd::OnChar(nChar, nRepCnt, nFlags); 
	} 
  FeedKeyinCode(nChar,NULL); 
 
  static UINT nlastChar; 
  if((nChar == 38)||(nChar == 39))       return; 
  if((nChar !=  8)&&(nChar < ' '))       return; 
  if((nChar ==  8)&&g_nInputMsgPos == 0) return; 
 
  // 檢查是否為中文 
  if(nlastChar) { 
    if(!IsTraditionalChinese(nlastChar,nChar)) nlastChar = 0; 
  } 
  else if(IsDBCSLeadByte(nChar)) 
  { 
    nlastChar = nChar; 
    return; 
  } 
/* 
  if(nlastChar) 
  { 
    if(nChar < 64) nlastChar = 0; 
  } 
  else if(nChar > 160) 
  { 
    nlastChar = nChar; 
    return; 
  } 
*/   
  CString StrLeft, StrRight, StrSel; 
  CString szAdd; 
   
  szLastMsg = g_szInputMsg; 
  if( nlastChar ) 
  { 
    szAdd  = (BYTE)nlastChar; 
    szAdd += (BYTE)nChar; 
    nlastChar = 0; 
  } 
  else 
  { 
    szAdd = (BYTE)nChar; 
  } 
  /* 
  //讓自動輸入的命令生效  
  if(( g_szInputMsg.Find(' ') == -1 )&&	//還沒有輸入空格 
  ( nChar == ' ' ))&&					//現在是在輸入空格 
  ( g_szInputMsg.GetLength() == g_nSelEnd )&& 
  ( g_nSelStart == g_nInputMsgPos ))			//使用了塊,塊頭在光標處,塊尾在結尾 
  */ 
  if((nChar == ' ')&&(g_nSelEnd != g_nSelStart))//空格相當于確認 
  { 
    g_nInputMsgPos = g_nSelEnd; 
    g_nSelEnd = g_nSelStart; 
  } 
  //如果全選則清空,為命令自動輸入做準備 
  if(( g_nSelStart == 0 )&&( g_nSelEnd == g_szInputMsg.GetLength() )) 
  { 
    g_nInputMsgPos = g_nSelEnd = g_nSelStart = 0; 
    g_szInputMsg.Empty(); 
  } 
  //命令自動輸入 
  //如果在輸入命令 
  if(( g_szInputMsg.Find(' ') == -1 )&&	//還沒有輸入空格 
	   ( nChar != ' ' )&&					//現在也不是在輸入空格 
     ((( g_szInputMsg.GetLength() == g_nInputMsgPos )&& 
     ( g_nSelStart == g_nSelEnd ))||				//沒有使用塊,並且光標在結尾 
     (( g_szInputMsg.GetLength() == g_nSelEnd )&& 
     ( g_nSelStart == g_nInputMsgPos ))))			//或者使用了塊,塊頭在光標處,塊尾在結尾 
  { 
    //確認是emote 
    if( g_szInputMsg.GetLength() > 0 && g_szInputMsg[0] == ':' ) 
    { 
      // emote指令自動補全 
      if(!IsDBCSLeadByte(nChar)) 
      { 
        g_szInputMsg = g_szInputMsg.Left(g_nInputMsgPos); 
        // 為BackSpace鍵嗎? 
        if(nChar == 8) 
        { 
          if(g_szInputMsg.GetLength() <= 2) 
          { 
            if(g_szInputMsg.GetLength() == 1) 
              g_szInputMsg = ""; 
            else 
              g_szInputMsg = ':'; 
            g_nInputMsgPos = g_szInputMsg.GetLength(); 
            g_nSelStart = g_nSelEnd = 0; 
            m_MainScreen.bChangeInputMsg[0] = TRUE; 
            m_MainScreen.bChangeInputMsg[1] = TRUE; 
            bMsgChanged = TRUE; 
            return; 
          } 
          else 
          { 
            g_szInputMsg = g_szInputMsg.Left(g_szInputMsg.GetLength()-1); 
          } 
        } 
        else 
        { 
          g_szInputMsg += nChar; 
        } 
        StrLeft = g_szInputMsg.Right(g_szInputMsg.GetLength()-1); 
        g_nSelEnd = g_nSelStart = g_nInputMsgPos = g_szInputMsg.GetLength(); 
         
        POSITION pos; 
        int nLen = StrLeft.GetLength(); 
        CMainScreen::TEmote * lpEmote; 
        pos = m_MainScreen.listAllEmote.GetHeadPosition(); 
        while (pos != NULL) 
        { 
          lpEmote = m_MainScreen.listAllEmote.GetNext(pos); 
          if(!stricmp(lpEmote->szEmote.Left(nLen),StrLeft)) 
          { 
            pos = m_MainScreen.listAllEmote.GetHeadPosition(); 
            break; 
          } 
        } 
        if(pos != NULL) 
        { 
          StrRight = lpEmote->szEmote.Right(lpEmote->szEmote.GetLength() - nLen); 
          g_nSelEnd = g_nSelStart + StrRight.GetLength(); 
        } 
        m_MainScreen.bChangeInputMsg[0] = TRUE; 
        m_MainScreen.bChangeInputMsg[1] = TRUE; 
        bMsgChanged = TRUE; 
        g_szInputMsg = CString(":") + StrLeft + StrRight; 
      } 
    } 
    else 
    { 
      //系統命令自動補全 
      if(!IsDBCSLeadByte(nChar)) 
      { 
        g_szInputMsg = g_szInputMsg.Left(g_nInputMsgPos); 
        if(nChar == 8) 
        { 
          if(g_szInputMsg.GetLength() <= 1) 
          { 
            g_szInputMsg = ""; 
            g_nInputMsgPos = g_nSelStart = g_nSelEnd = 0; 
            m_MainScreen.bChangeInputMsg[0] = TRUE; 
            m_MainScreen.bChangeInputMsg[1] = TRUE; 
            bMsgChanged = TRUE; 
            return; 
          } 
          else 
          { 
            g_szInputMsg = g_szInputMsg.Left(g_szInputMsg.GetLength()-1); 
          } 
        } 
        else 
        { 
          g_szInputMsg += nChar; 
        } 
        StrLeft = g_szInputMsg; 
        g_nSelEnd = g_nSelStart = g_nInputMsgPos = g_szInputMsg.GetLength(); 
        POSITION pos; 
        int nLen = StrLeft.GetLength(); 
        pos = ListCom.GetHeadPosition(); 
        while (pos != NULL) 
        { 
          StrRight = ListCom.GetNext(pos); 
          if(!stricmp(StrRight.Left(nLen),StrLeft)) 
          { 
            pos = ListCom.GetHeadPosition(); 
            break; 
          } 
        } 
        if(pos != NULL) 
        { 
          StrRight = StrRight.Right(StrRight.GetLength() - nLen); 
          g_nSelEnd = g_nSelStart + StrRight.GetLength(); 
        } 
        else 
        { 
          StrRight.Empty(); 
        } 
        m_MainScreen.bChangeInputMsg[0] = TRUE; 
        m_MainScreen.bChangeInputMsg[1] = TRUE; 
        bMsgChanged = TRUE; 
        g_szInputMsg = StrLeft + StrRight;		 
      } 
    } 
  } 
  else if ( g_nSelStart >= g_nSelEnd )//如果沒有選中東西 
  { 
    StrLeft = g_szInputMsg.Left(g_nInputMsgPos); 
    StrRight = g_szInputMsg.Right(g_szInputMsg.GetLength() - g_nInputMsgPos); 
    g_nSelStart = g_nSelEnd; 
    // 是BackSpace鍵嗎? 
    if( nChar == 8 ) 
    { 
      if((StrLeft.Find(' ') == -1)||(StrLeft.Find(' ') == StrLeft.GetLength()-1)) 
      { 
        StrLeft = ""; 
      } 
      else if((!stricmp(StrLeft.Left(5), "tell "))&&((StrLeft.Find(' ',5) == -1)||(StrLeft.Find(' ',5) == StrLeft.GetLength()-1))) 
      { 
        StrLeft = StrLeft.Left(5); 
      } 
      //檢查是否是中文 
      else if(!IsStringChinese(StrLeft,g_nInputMsgPos)) 
      { 
        StrLeft = StrLeft.Left(g_nInputMsgPos-1); 
      } 
      else 
      { 
        StrLeft = StrLeft.Left(g_nInputMsgPos-2); 
      } 
      g_nInputMsgPos = StrLeft.GetLength(); 
    } 
    else 
    { 
      StrSel = g_szInputMsg; 
      StrSel += szAdd; 
      if(GetStrWidth(StrSel, TRUE) > MSG_WIDTH_LEN) return; 
      StrLeft += szAdd; 
      g_nInputMsgPos += szAdd.GetLength(); 
      //如果是覆蓋狀態,光標右邊有字元 
      if(( ! bInsertState )&&( ! StrRight.IsEmpty())) 
      { 
        if(!IsDBCSLeadByte(StrRight.GetAt(0))) 
        { 
          StrRight = StrRight.Right(StrRight.GetLength() - 1); 
        } 
        else 
        { 
          if(StrRight.GetLength() > 2) 
          { 
            StrRight = StrRight.Right(StrRight.GetLength() - 2); 
          } 
          else 
          { 
            StrRight.Empty(); 
          } 
        } 
      } 
      if(( nChar == ' ' )&&( StrRight.IsEmpty() )) 
      { 
        if((StrLeft[0] == ':')&&(StrLeft.Find(' ') == StrLeft.GetLength()-1)) 
          StrRight = m_OldMsg.szEmote; 
        else if(!stricmp(StrLeft,"tell ")) 
          StrRight = m_OldMsg.szTell; 
        else if(!stricmp(StrLeft,"DaZuo ")) 
          StrRight = m_OldMsg.szDaZuo; 
        else if(!stricmp(StrLeft,"TuNa ")) 
          StrRight = m_OldMsg.szTuNa; 
        else if(!stricmp(StrLeft,"Learn ")) 
          StrRight = m_OldMsg.szLearn; 
        else if(!stricmp(StrLeft,"YunGong ")) 
          StrRight = m_OldMsg.szYunGong; 
		else if(!stricmp(StrLeft,"Use ")) 
			StrRight = m_OldMsg.szUse; 
//        else if(!stricmp(StrLeft,"Eat ")) 
//          StrRight = m_OldMsg.szEat; 
//        else if(!stricmp(StrLeft,"Drink ")) 
//          StrRight = m_OldMsg.szDrink; 
        else if(!stricmp(StrLeft,"Give ")) 
          StrRight = m_OldMsg.szGive; 
		    else if(!stricmp(StrLeft,"Drop ")) 
          StrRight = m_OldMsg.szDrop; 
        else if(!stricmp(StrLeft,"Get ")) 
          StrRight = m_OldMsg.szGet; 
        else if(!stricmp(StrLeft,"Mapping ")) 
          StrRight = m_OldMsg.szMapping + " " + m_OldMsg.szMapping2; 
        else if(!stricmp(StrLeft,"Ask ")) 
          StrRight = m_OldMsg.szAsk; 
        if(!StrRight.IsEmpty()) 
        { 
          g_nSelStart = g_nInputMsgPos; 
          g_nSelEnd = g_nSelStart + StrRight.GetLength(); 
        } 
      } 
    } 
    m_MainScreen.bChangeInputMsg[0] = TRUE; 
    m_MainScreen.bChangeInputMsg[1] = TRUE; 
    bMsgChanged = TRUE; 
    g_szInputMsg = StrLeft + StrRight; 
  } 
  else//用戶選擇的有東西 
  { 
    StrLeft = g_szInputMsg.Left(g_nSelStart); 
    StrRight = g_szInputMsg.Right(g_szInputMsg.GetLength() - g_nSelEnd); 
    // 是BackSpace鍵嗎? 
    if( nChar == 8 ) 
    { 
      szAdd.Empty(); 
      g_nInputMsgPos = g_nSelStart; 
    } 
    else 
    { 
      StrSel = StrLeft + StrRight; 
      StrSel += szAdd; 
      if(GetStrWidth(StrSel, TRUE) > MSG_WIDTH_LEN) return; 
      g_nInputMsgPos = g_nSelStart + szAdd.GetLength(); 
    } 
    g_nSelEnd = g_nSelStart = 0; 
    m_MainScreen.bChangeInputMsg[0] = TRUE; 
    m_MainScreen.bChangeInputMsg[1] = TRUE; 
    bMsgChanged = TRUE; 
    if(szAdd.IsEmpty()) 
    { 
      g_szInputMsg = StrLeft + StrRight; 
    } 
    else 
    { 
      g_szInputMsg = StrLeft + szAdd + StrRight; 
    } 
  } 
  CWnd::OnChar(nChar, nRepCnt, nFlags); 
} 
BOOL bShowCaret; 
void CMainWnd::OnTimer(UINT nIDEvent)  
{ 
  CTimeAction m_TimeAction; 
  if(g_nGameState == GAME_MAIN || g_nGameState == GAME_FIGHTREADY){ 
    switch(nIDEvent){ 
    case 1: 
      { 
        m_TimeAction.DoTimeChange();//修改玩家的精和氣 
      } 
      break; 
    case 2: 
      break; 
    case 3: 
      { 
        PlayRandomWave(); 
      } 
      break; 
    case TIMER_CURSOR://每400毫秒畫光標一次 
      { 
       m_MainScreen.DrawCursor(); 
      } 
    default: 
      break; 
    } 
  }else if(g_nGameState==GAME_SERVER && nIDEvent==TIMER_CURSOR){ 
 		if(bShowCaret) 
			bShowCaret=FALSE; 
		else 
			bShowCaret=TRUE; 
  } 
  CWnd::OnTimer(nIDEvent); 
}