www.pudn.com > gamedata.rar > servergame.c


// servergame.cpp : Defines the entry point for the application. 
// 
 
#include "stdafx.h" 
#include "common.h" 
#include "resource.h" 
 
#define MAX_LOADSTRING 100 
#define MAX_CHAR      1024 
 
// 用 key 追踪 每一个单独的文件句柄 
// 的I/O 端口的状态. 
 
#define MAX_LOADSTRING 100 
 
// Global Variables: 
 
TCHAR szTitle[MAX_LOADSTRING];								// The title bar text 
TCHAR szWindowClass[MAX_LOADSTRING];								// The title bar text 
HANDLE ghCompletionPort; 
 
char szLoginInfo[2048]; 
struct GAMESERVERINFO pServerInfo[64]; 
struct optiondata option; 
 
// Global Variables: 
HINSTANCE hInst; 
TCHAR szTitle[MAX_LOADSTRING]; 
TCHAR szWindowClass[MAX_LOADSTRING]; 
 
TBBUTTON tbButtons[] =  
{ 
	{ 0, IDM_STARTSERVICE,	TBSTATE_ENABLED,	TBSTYLE_BUTTON, 0L, 0}, 
	{ 1, IDM_STOPSERVICE,	TBSTATE_ENABLED,	TBSTYLE_BUTTON, 0L, 0},	 
	{ 2, IDM_FONTCOLOR,		TBSTATE_ENABLED,	TBSTYLE_BUTTON, 0L, 0}, 
	{ 3, IDM_BACKCOLOR,		TBSTATE_ENABLED,	TBSTYLE_BUTTON, 0L, 0}, 
}; 
// Foward declarations of functions included in this code module: 
ATOM				MyRegisterClass(HINSTANCE hInstance); 
BOOL				InitInstance(HINSTANCE, int); 
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM); 
 
void ReadPack(struct logindata *login) 
{ 
    int     i = 0; 
    BOOL    bResult; 
    int     err; 
    DWORD   numRead; 
 
    while (++i) 
    { 
        // 读取一个单字符 
        bResult = ReadFile( 
                    (HANDLE)login->sock, 
                    login->InBuffer, 
                    1, 
                    &numRead, 
                    &login->ovIn); 
 
        // 这里,等待一个信息包. 
       if (bResult) return; 
 
        err = GetLastError(); 
 
        // 获取状态,这里并不代表错误 
        if (err == ERROR_IO_PENDING) 
            return; 
 
        if ( err == ERROR_INVALID_USER_BUFFER || 
             err == ERROR_NOT_ENOUGH_QUOTA || 
             err == ERROR_NOT_ENOUGH_MEMORY ) 
        { 
            if (i == 5)  
            { 
                Sleep(50);  // 等待并重试 
                continue; 
            } 
        } 
	 
        break; 
  
    }	 
} 
 
// 
// 确保我们运行在正确的版本下 Windows 2003 Server (sp1, or later) 
// 
BOOL CheckOsVersion() 
{ 
    OSVERSIONINFO   ver; 
    BOOL            bResult; 
 
    ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 
 
    bResult = GetVersionEx((LPOSVERSIONINFO) &ver); 
 
    if ((!bResult) || 
         (ver.dwPlatformId != VER_PLATFORM_WIN32_NT)) 
    { 
        MessageBox(NULL, "You Must Have Windows 2003 Server Sp1 or Later\n", "信息", 0); 
 
		return FALSE; 
    } 
	return TRUE; 
} 
 
DWORD WINAPI ThreadFunc(LPVOID pVoid) 
{ 
 
    BOOL    bResult; 
    DWORD   dwNumRead; 
    struct logindata *pCntx; 
    LPOVERLAPPED lpOverlapped; 
	char tmp[50]; 
 
    UNREFERENCED_PARAMETER(pVoid); 
 
    // 无限循环从 I/O completion port 获取信息. 
    for (;;) 
    { 
        bResult = GetQueuedCompletionStatus( 
               ghCompletionPort, 
               &dwNumRead, 
               &(DWORD)pCntx, 
               &lpOverlapped, 
               INFINITE 
            ); 
 
        if (bResult == FALSE 
            && lpOverlapped == NULL) 
        { 
//            FatalError( 
  //              "ThreadFunc - GetQueuedCompletionStatus()错误.\n"); 
        } 
        else if (bResult == FALSE 
            && lpOverlapped != NULL) 
        { 
          //  sprintf(tmp, "bResult == FALSE  lpOverlapped != NULL %d\n", pCntx->sock); 
          //  SaveLog(tmp); 
            if (closeusersocket(pCntx->sock) == -1) 
                CloseHandle(pCntx->ovOut.hEvent); 
        } 
        else if (dwNumRead == 0) 
        { 
         //   sprintf(tmp, "dwNumRead == 0 %d\n", pCntx->sock); 
         //   SaveLog(tmp); 
            if (closeusersocket(pCntx->sock) == -1) 
                CloseHandle(pCntx->ovOut.hEvent); 
        } 
        else 
        { 
			pCntx->OutBuffer[pCntx->nOutBufIndex++] = pCntx->InBuffer[0]; 
 
			if ((((BYTE)pCntx->OutBuffer[0] != 0xAA ) || ((BYTE)pCntx->OutBuffer[1] != 0x55)) && (pCntx->nOutBufIndex == 2)) 
			{ 
				memset(pCntx->OutBuffer, 0x00, sizeof(pCntx->OutBuffer)); 
				pCntx->nOutBufIndex = 0; 
			} 
			 
			if ((((BYTE)pCntx->OutBuffer[0] != 0xAA ) || ((BYTE)pCntx->OutBuffer[1] != 0x55) || (((BYTE)pCntx->OutBuffer[4] != 0xD5) && ((BYTE)pCntx->OutBuffer[4] != 0xF9))) && (pCntx->nOutBufIndex==5)) 
			{ 
				memset(pCntx->OutBuffer, 0x00, sizeof(pCntx->OutBuffer)); 
				pCntx->nOutBufIndex = 0;	 
			} 
 
			if(((BYTE)pCntx->OutBuffer[0] == 0xAA) && ((BYTE)pCntx->OutBuffer[1] == 0x55) &&  
				((int)(BYTE)pCntx->OutBuffer[2] + (int)(BYTE)pCntx->OutBuffer[3] * 256 + 6 == pCntx->nOutBufIndex) && (pCntx->nOutBufIndex==8)) 
			{ 
				if ((BYTE)pCntx->OutBuffer[4] == 0xD5) 
				{		    
					memset(tmp, 0x00, sizeof(tmp)); 
	     
					tmp[0] = (char)0xAA;	 
			    	tmp[1] = (char)0x55;		     
					tmp[2] = (char)0x0A;			     
					tmp[3] = (char)0x00;	    	 
					tmp[4] = (char)0xD6;    	 
					tmp[5] = (char)0x10;		     
					tmp[6] = (char)0x10;	     
					tmp[7] = (char)0x10;	     
					tmp[8] = (char)0x10;		      
					tmp[9] = (char)0x10;		     
					tmp[10] = (char)0x10;		     
					tmp[11] = (char)0x10;			 
					tmp[12] = (char)0x10;	    	 
					tmp[13] = (char)0x01;	     
					tmp[14] = (char)0x55;	     
					tmp[15] = (char)0xAA; 
 
					send(pCntx->sock, tmp, 16, 0); 
 
					memset(pCntx->OutBuffer, 0x00, sizeof(pCntx->OutBuffer)); 
					pCntx->nOutBufIndex = 0; 
				} 
			} 
			else if(((BYTE)pCntx->OutBuffer[0] == 0xAA) && ((BYTE)pCntx->OutBuffer[1] == 0x55) &&  
				((BYTE)pCntx->OutBuffer[2] + (BYTE)pCntx->OutBuffer[3] * 256 + 6 == pCntx->nOutBufIndex) && (pCntx->nOutBufIndex>=12)) 
			{ 
				analysedata(pCntx, pCntx->OutBuffer, pCntx->nOutBufIndex); 
 
				memset(pCntx->OutBuffer, 0x00, sizeof(pCntx->OutBuffer)); 
				pCntx->nOutBufIndex = 0; 
			} 
            // 开始读取 
            ReadPack(pCntx); 
        } 
    } 
 
    return 0; 
} 
 
 
void CreateWorkerThreads() 
{ 
    SYSTEM_INFO  sysinfo; 
#ifdef _CLIBTHREAD 
	UINT         dwThreadId; 
#else 
    DWORD        dwThreadId; 
#endif 
    DWORD        dwThreads; 
    DWORD        i; 
 
    GetSystemInfo(&sysinfo); 
    dwThreads = sysinfo.dwNumberOfProcessors * option.thread + 2; 
 
    for (i=0; isock = newsocket; 
        pKey->ovOut.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//为写信息包过程设置(事件对象) event . 
        pKey->ovOut.hEvent = (HANDLE)((DWORD)pKey->ovOut.hEvent | 0x1);  
     
         
        CreateIoCompletionPort(                                   //为请求绑定端口 
                (HANDLE)newsocket, 
                ghCompletionPort, 
                (DWORD)pKey,    
                0); 
 
        ReadPack(pKey);                                          // 完成第一次读操作 
 
		sprintf(tmp, "%d.%d.%d.%d 连接", clientAddress.sin_addr.S_un.S_un_b.s_b1,  
					clientAddress.sin_addr.S_un.S_un_b.s_b2, 
					clientAddress.sin_addr.S_un.S_un_b.s_b3, 
					clientAddress.sin_addr.S_un.S_un_b.s_b4); 
 
		InsertLogMsg(tmp); 
    } 
//	uninstallsqldata(); 
	return 0; 
} 
 
int APIENTRY WinMain(HINSTANCE hInstance, 
                     HINSTANCE hPrevInstance, 
                     LPSTR     lpCmdLine, 
                     int       nCmdShow) 
{ 
	MSG msg; 
//	HACCEL hAccelTable; 
 
	char szfilepath[256]; 
	char szfilename[256]; 
	char tmp[100]; 
	// Initialize global strings 
	GetExeDir(szfilepath); 
 
	sprintf(szfilename, "%sservergame.ini", szfilepath); 
 
	GetPrivateProfileString("SERVER", "PORT",             "", tmp,                   24, szfilename); 
	option.port = atoi(tmp); 
	GetPrivateProfileString("ODBC",   "ACCOUNT_DSN",      "", option.accountdsn,     24, szfilename); 
	GetPrivateProfileString("ODBC",   "ACCOUNT_UID",      "", option.accountuid,     24, szfilename); 
	GetPrivateProfileString("ODBC",   "ACCOUNT_PWD",      "", option.accountpwd,     24, szfilename); 
	GetPrivateProfileString("ODBC",   "CHAR_DSN",         "", option.chardsn,        24, szfilename); 
	GetPrivateProfileString("ODBC",   "CHAR_UID",         "", option.charuid,        24, szfilename); 
	GetPrivateProfileString("ODBC",   "CHAR_PWD",         "", option.charpwd,        24, szfilename); 
	GetPrivateProfileString("ODBC",   "DOOR_DSN",         "", option.doordsn,        24, szfilename); 
	GetPrivateProfileString("ODBC",   "DOOR_UID",         "", option.dooruid,        24, szfilename); 
	GetPrivateProfileString("ODBC",   "DOOR_PWD",         "", option.doorpwd,        24, szfilename); 
	GetPrivateProfileString("ODBC",   "WAREHOUSE_DSN",    "", option.warehousedsn,   24, szfilename); 
	GetPrivateProfileString("ODBC",   "WAREHOUSE_UID",    "", option.warehouseuid,   24, szfilename); 
	GetPrivateProfileString("ODBC",   "WAREHOUSE_PWD",    "", option.warehousepwd,   24, szfilename); 
	GetPrivateProfileString("ODBC",   "INFO_DSN",         "", option.infodsn,        24, szfilename); 
	GetPrivateProfileString("ODBC",   "INFO_UID",         "", option.infouid,        24, szfilename); 
	GetPrivateProfileString("ODBC",   "INFO_PWD",         "", option.infopwd,        24, szfilename); 
	GetPrivateProfileString("ODBC",   "LUMP_DSN",         "", option.lumpdsn,        24, szfilename); 
	GetPrivateProfileString("ODBC",   "LUMP_UID",         "", option.lumpuid,        24, szfilename); 
	GetPrivateProfileString("ODBC",   "LUMP_PWD",         "", option.lumppwd,        24, szfilename); 
	GetPrivateProfileString("ODBC",   "LOG_DSN",          "", option.logdsn,         24, szfilename); 
	GetPrivateProfileString("ODBC",   "LOG_UID",          "", option.loguid,         24, szfilename); 
	GetPrivateProfileString("ODBC",   "LOG_PWD",          "", option.logpwd,         24, szfilename); 
	GetPrivateProfileString("SYSTEM", "CPUTHREAD",        "", tmp,                   24, szfilename); 
	option.thread = atoi(tmp); 
	GetPrivateProfileString("GAME",   "MAXONLINE",        "", tmp,                   24, szfilename); 
	option.max_online = atoi(tmp); 
	GetPrivateProfileString("GAME",   "GAMESPEED",        "", tmp,                   24, szfilename); 
	option.speed_number = atoi(tmp); 
	GetPrivateProfileString("GAME",   "WELCOMEINFO",      "", tmp,                   100,szfilename); 
	strcpy(option.welcomeinfo, tmp); 
 
	GetPrivateProfileString("TEST",   "NOW",        "", tmp,                   24, szfilename); 
	option.testnow = atoi(tmp); 
	GetPrivateProfileString("TEST",   "ME1",        "", tmp,                   24, szfilename); 
	option.menow1 = atoi(tmp); 
	GetPrivateProfileString("TEST",   "ME2",        "", tmp,                   24, szfilename); 
	option.menow2 = atoi(tmp); 
	GetPrivateProfileString("TEST",   "X",          "", tmp,                   24, szfilename); 
	option.now_x = atoi(tmp); 
	GetPrivateProfileString("TEST",   "Y",          "", tmp,                   24, szfilename); 
	option.now_y = atoi(tmp); 
 
	if (!CheckOsVersion()) 
		return 0; 
 
	MyRegisterClass(hInstance); 
 
	// Perform application initialization: 
	if (!InitInstance (hInstance, nCmdShow))  
	{ 
		return FALSE; 
	} 
 
//	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SERVERGAME); 
 
	// Main message loop: 
	while (GetMessage(&msg, NULL, 0, 0))  
	{ 
		TranslateMessage(&msg); 
		DispatchMessage(&msg); 
	} 
 
	return msg.wParam; 
} 
 
ATOM MyRegisterClass(HINSTANCE hInstance) 
{ 
    WNDCLASS  wc; 
 
    wc.style            = CS_GLOBALCLASS|CS_HREDRAW|CS_VREDRAW; 
    wc.lpfnWndProc      = (WNDPROC)WndProc; 
    wc.cbClsExtra       = 0; 
    wc.cbWndExtra       = 0; 
    wc.hIcon            = LoadIcon((HINSTANCE)hInstance, MAKEINTRESOURCE(IDI_SERVERGAME)); 
    wc.hInstance        = (HINSTANCE)hInstance; 
    wc.hCursor          = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW + 1); 
    wc.lpszMenuName     = MAKEINTRESOURCE(IDR_MAINMENU); 
    wc.lpszClassName    = _GAME_SERVER_CLASS; 
 
	return RegisterClass(&wc); 
} 
 
// 
//   FUNCTION: InitInstance(HANDLE, int) 
// 
//   PURPOSE: Saves instance handle and creates main window 
// 
//   COMMENTS: 
// 
//        In this function, we save the instance handle in a global variable and 
//        create and display the main program window. 
// 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 
{ 
	DWORD dwStyle; 
	int i; 
  	int	nStatusPartsWidths[_NUMOFMAX_STATUS_PARTS]; 
	int nCnt; 
	RECT rcMainWnd, rcToolBar, rcStatusBar; 
	LV_COLUMN	lvc; 
	char		szText[64]; 
	INITCOMMONCONTROLSEX icex; 
 
	hInst = hInstance; 
	dwStyle = WS_THICKFRAME | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; 
 
	//OleInitialize(NULL); 
 
	icex.dwSize = sizeof(INITCOMMONCONTROLSEX); 
	icex.dwICC = ICC_LISTVIEW_CLASSES | ICC_BAR_CLASSES | ICC_INTERNET_CLASSES | ICC_TAB_CLASSES; 
 
	InitCommonControlsEx(&icex); 
 
    option.hMainWnd = CreateWindowEx(0, _GAME_SERVER_CLASS, _GAME_SERVER_TITLE,  
							dwStyle | WS_VISIBLE, 
							CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,                  
							NULL, NULL, (HINSTANCE)hInstance, NULL); 
 
	option.hToolBar = CreateToolbarEx(option.hMainWnd, WS_CHILD|CCS_TOP|WS_VISIBLE|SBS_SIZEGRIP, 
									_IDW_TOOLBAR, sizeof(tbButtons) / sizeof(TBBUTTON), (HINSTANCE)hInstance, IDB_TOOLBAR, 
									(LPCTBBUTTON)&tbButtons, sizeof(tbButtons) / sizeof(TBBUTTON), 
									_BMP_CX, _BMP_CY, _BMP_CX, _BMP_CY, sizeof(TBBUTTON)); 
 
	GetClientRect(option.hMainWnd, &rcMainWnd); 
	GetWindowRect(option.hToolBar, &rcToolBar); 
 
	option.hStatusBar = CreateWindowEx(0L, STATUSCLASSNAME, _T(""), WS_CHILD|WS_VISIBLE|SBS_SIZEGRIP, 
									0, rcMainWnd.bottom - _STATUS_HEIGHT, (rcMainWnd.right - rcMainWnd.left), _STATUS_HEIGHT, option.hMainWnd, (HMENU)_IDW_STATUSBAR, hInst, NULL); 
	nCnt = 0; 
	 
	for (i = _NUMOFMAX_STATUS_PARTS - 1; i >= 0; i--) 
		nStatusPartsWidths[nCnt++] = (rcMainWnd.right - rcMainWnd.left) - (90 * i); 
 
	SendMessage(option.hStatusBar, SB_SETPARTS, _NUMOFMAX_STATUS_PARTS, (LPARAM)nStatusPartsWidths); 
	SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(0, 0), (LPARAM)_TEXT("服务器关闭")); 
	SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(1, 0), (LPARAM)_TEXT("在线 0 人")); 
	SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(2, 0), (LPARAM)_TEXT("怪物 0 个")); 
	SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(3, 0), (LPARAM)_TEXT("矿石 0 个")); 
 
	GetWindowRect(option.hStatusBar, &rcStatusBar); 
 
    option.hLogMsgWnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, _TEXT(""),  
							WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_REPORT|LVS_EDITLABELS, 
							0, (rcToolBar.bottom - rcToolBar.top) - 2, (rcMainWnd.right - rcMainWnd.left),  
							(rcMainWnd.bottom - rcMainWnd.top) - (rcToolBar.bottom - rcToolBar.top) + 2 
							- (rcStatusBar.bottom - rcStatusBar.top), 
							option.hMainWnd, NULL, (HINSTANCE)hInstance, NULL); 
 
	ListView_SetExtendedListViewStyleEx(option.hLogMsgWnd, 0, LVS_EX_FULLROWSELECT); 
 
	lvc.mask	= LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; 
	lvc.fmt		= LVCFMT_LEFT; 
	lvc.cx		= 100; 
	lvc.pszText	= szText; 
 
	for (i = 0; i < 3; i++) 
	{ 
		lvc.iSubItem = i; 
		LoadString((HINSTANCE)hInstance, IDS_LVS_LABEL1 + i, szText, sizeof(szText)); 
		 
		ListView_InsertColumn(option.hLogMsgWnd, i, &lvc); 
	} 
	 
	ListView_SetColumnWidth(option.hLogMsgWnd, 2, 220 ); 
 
	SendMessage(option.hToolBar, TB_SETSTATE, (WPARAM)IDM_STOPSERVICE, (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0)); 
 
	ShowWindow(option.hMainWnd, SW_SHOW); 
	UpdateWindow(option.hMainWnd); 
 
	InvalidateRect(option.hMainWnd, NULL, TRUE ); 
 
	return TRUE; 
} 
 
// 
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG) 
// 
//  PURPOSE:  Processes messages for the main window. 
// 
//  WM_COMMAND	- process the application menu 
//  WM_PAINT	- Paint the main window 
//  WM_DESTROY	- post a quit message and return 
// 
// 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{				 
	RECT rcToolBar, rcMain, rcStatusBar; 
	int	nStatusPartsWidths[_NUMOFMAX_STATUS_PARTS]; 
	int i, nCnt; 
	TCHAR	szMsg[128]; 
	TCHAR	szTitle[128]; 
 
	switch (message) 
	{ 
 
		case WM_INITDIALOG: 
			return TRUE; 
		case WM_COMMAND: 
			OnCommand(wParam, lParam); 
			return TRUE; 
/*		case WM_ERASEBKGND: 
			return TRUE; 
		case WM_PAINT: 
			return TRUE; 
			*/ 
		case WM_SIZE: 
		{ 
			if (option.hToolBar && option.hMainWnd && option.hStatusBar)  
			{ 
				GetWindowRect(option.hToolBar, &rcToolBar); 
				GetClientRect(option.hMainWnd, &rcMain); 
				GetWindowRect(option.hStatusBar, &rcStatusBar); 
 
				MoveWindow(option.hToolBar, 0, 0, LOWORD(lParam), (rcToolBar.bottom - rcToolBar.top), TRUE); 
				MoveWindow(option.hStatusBar, 0, rcMain.bottom - (rcStatusBar.bottom - rcStatusBar.top),  
								LOWORD(lParam), (rcStatusBar.bottom - rcStatusBar.top), TRUE); 
				MoveWindow(option.hLogMsgWnd, 0, (rcToolBar.bottom - rcToolBar.top) - 2, (rcMain.right - rcMain.left),  
								(rcMain.bottom - rcMain.top) - (rcToolBar.bottom - rcToolBar.top) - (rcStatusBar.bottom - rcStatusBar.top) + 2,  
								TRUE); 
				nCnt = 0; 
 
				for (i = _NUMOFMAX_STATUS_PARTS - 1; i >= 0 ; i--) 
					nStatusPartsWidths[nCnt++] = (rcStatusBar.right - rcStatusBar.left) - (90 * i); 
 
				SendMessage(option.hStatusBar, SB_SETPARTS, _NUMOFMAX_STATUS_PARTS, (LPARAM)nStatusPartsWidths); 
 
			//	InvalidateRect(option.hStatusBar, NULL, TRUE ); 
 
			//	ShowWindow(option.hStatusBar, SW_SHOW); 
			} 
 
			break; 
		} 
		 
		case WM_CLOSE: 
		{ 
 
			LoadString(hInst, IDS_PROGRAM_QUIT, szMsg, sizeof(szMsg)); 
			LoadString(hInst, IDS_PROGRAM_TITLE, szTitle, sizeof(szTitle)); 
 
			if (MessageBox(option.hMainWnd, szMsg, szTitle, MB_ICONINFORMATION|MB_YESNO) == IDYES) 
			{			 
//				ClearServerSocket(); 
//				DisconnectFromServer(); 
 
//				savelumpinfo(Lump_info); 
				 
				saveserveruser(); 
 
				OnCommand(IDM_STOPSERVICE, 0L); 
 
 
 
			//	save_map_image(); 
 
//				CoUninitialize(); 
 
				WSACleanup(); 
 
				PostQuitMessage(0); 
			} 
 
			return 0L; 
		} 
	} 
 
	return (DefWindowProc(hWnd, message, wParam, lParam)); 
} 
 
// Mesage handler for about box. 
LRESULT CALLBACK AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	switch (message) 
	{ 
		case WM_INITDIALOG: 
				return TRUE; 
 
		case WM_COMMAND: 
			if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)  
			{ 
				EndDialog(hDlg, LOWORD(wParam)); 
			} 
			return TRUE; 
	} 
    return FALSE; 
} 
 
LRESULT CALLBACK InfoProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	char tmp[255]; 
	 
	switch (message) 
	{ 
		case WM_INITDIALOG: 
			SetDlgItemText(hDlg, IDC_EDIT, "服务器10分钟后重新启动, 请下线."); 
			return TRUE; 
 
		case WM_COMMAND: 
			if (LOWORD(wParam) == IDC_SEND)  
			{ 
				GetDlgItemText(hDlg, IDC_EDIT, tmp, 255); 
 
				speakalluser(tmp); 
			} 
			return TRUE; 
		case WM_CLOSE: 
			EndDialog(hDlg, FALSE); 
			return TRUE; 
	} 
    return FALSE; 
}