📄 winmain.c
字号:
/* * Copyright (C) 2001 Erik Latoshek [forester] (laterk@inbox.lv) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#ifdef WIN32_GUI#pragma warning(disable : 4047)#include "common/setup_before.h"#include <stdio.h>#include <windows.h>#include <windowsx.h>#include <winuser.h>#include <process.h>#include <richedit.h>#include <string.h>#include <commctrl.h>#include <time.h>#include "bnetd/connection.h"#include "bnetd/account.h"#include "bnetd/account_wrap.h"#include "bnetd/ipban.h"#include "bnetd/message.h"#include "bnetd/server.h"#include "common/addr.h"#include "common/eventlog.h"#include "common/list.h"#include "common/version.h"#include "resource.h"#include "winmain.h"#include "common/setup_after.h"#define WM_SHELLNOTIFY (WM_USER+1)extern int server_main(int, char*[]);static void guiThread(void*);static void guiAddText(const char *, COLORREF);static void guiAddText_user(const char *, COLORREF);static void guiDEAD(char*);static void guiMoveWindow(HWND, RECT*);static void guiClearLogWindow(void);static void guiKillTrayIcon(void);long PASCAL guiWndProc(HWND, UINT, WPARAM, LPARAM);static void guiOnCommand(HWND, int, HWND, UINT);static void guiOnMenuSelect(HWND, HMENU, int, HMENU, UINT);static int guiOnShellNotify(int, int);static BOOL guiOnCreate(HWND, LPCREATESTRUCT);static void guiOnClose(HWND);static void guiOnSize(HWND, UINT, int, int);static void guiOnPaint(HWND);static void guiOnCaptureChanged(HWND);static BOOL guiOnSetCursor(HWND, HWND, UINT, UINT);static void guiOnMouseMove(HWND, int, int, UINT);static void guiOnLButtonDown(HWND, BOOL, int, int, UINT);static void guiOnLButtonUp(HWND, int, int, UINT);static void guiOnServerConfig (void);static void guiOnAbout (HWND);static void guiOnUpdates (void);static void guiOnAnnounce (HWND);static void guiOnUserStatusChange (HWND);BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);BOOL CALLBACK AnnDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);BOOL CALLBACK KickDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);#define MODE_HDIVIDE 1#define MODE_VDIVIDE 1struct gui_struc { HWND hwnd; HMENU hmenuTray; HWND hwndConsole; HWND hwndUsers; HWND hwndUserCount; HWND hwndUserEditButton; HWND hwndTree; int y_ratio; int x_ratio; HANDLE event_ready; BOOL main_finished; int mode; char szDefaultStatus[128]; RECT rectHDivider, rectVDivider, rectConsole, rectUsers, rectConsoleEdge, rectUsersEdge; WPARAM wParam; LPARAM lParam;};static struct gui_struc gui;char selected_item[255];int fprintf(FILE *stream, const char *format, ...){ va_list args; va_start(args, format); if(stream == stderr || stream == stdout) return gui_lvprintf(eventlog_level_error, format, args); else return vfprintf(stream, format, args);}int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE reserved, LPSTR lpCmdLine, int nCmdShow){ int result; gui.main_finished = FALSE; gui.event_ready = CreateEvent(NULL, FALSE, FALSE, NULL); _beginthread( guiThread, 0, (void*)hInstance); WaitForSingleObject(gui.event_ready, INFINITE); result = server_main(__argc ,__argv); gui.main_finished = TRUE; eventlog(eventlog_level_debug,__FUNCTION__,"server exited ( return : %i )", result); WaitForSingleObject(gui.event_ready, INFINITE); return 0;}static void guiThread(void *param){ WNDCLASSEX wc; MSG msg; LoadLibrary("RichEd20.dll"); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW|CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)guiWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = (HINSTANCE)param; wc.hIcon = LoadIcon(wc.hInstance, MAKEINTRESOURCE(IDI_ICON1)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = 0; wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); wc.lpszClassName = "BnetdWndClass"; wc.hIconSm = NULL; if(!RegisterClassEx( &wc )) guiDEAD("cant register WNDCLASS"); gui.hwnd = CreateWindowEx( 0, wc.lpszClassName, "The Player -vs- Player Gaming Network Server", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, (HINSTANCE)param, NULL); if(!gui.hwnd) guiDEAD("cant create window"); ShowWindow(gui.hwnd, SW_SHOW); SetEvent(gui.event_ready); while( GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); }}long PASCAL guiWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ gui.wParam = wParam; gui.lParam = lParam; switch(message) { HANDLE_MSG(hwnd, WM_CREATE, guiOnCreate); HANDLE_MSG(hwnd, WM_COMMAND, guiOnCommand); HANDLE_MSG(hwnd, WM_MENUSELECT, guiOnMenuSelect); HANDLE_MSG(hwnd, WM_SIZE, guiOnSize); HANDLE_MSG(hwnd, WM_CLOSE, guiOnClose); HANDLE_MSG(hwnd, WM_PAINT, guiOnPaint); HANDLE_MSG(hwnd, WM_SETCURSOR, guiOnSetCursor); HANDLE_MSG(hwnd, WM_LBUTTONDOWN, guiOnLButtonDown); HANDLE_MSG(hwnd, WM_LBUTTONUP, guiOnLButtonUp); HANDLE_MSG(hwnd, WM_MOUSEMOVE, guiOnMouseMove); case WM_CAPTURECHANGED: guiOnCaptureChanged((HWND)lParam); return 0; case WM_SHELLNOTIFY: return guiOnShellNotify(wParam, lParam); } return DefWindowProc(hwnd, message, wParam, lParam);}static BOOL guiOnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct){ gui.hwndConsole = CreateWindowEx( 0, RICHEDIT_CLASS, NULL, WS_CHILD|WS_VISIBLE|ES_READONLY|ES_MULTILINE|WS_VSCROLL|WS_HSCROLL|ES_NOHIDESEL, 0, 0, 0, 0, hwnd, 0, 0, NULL); if(!gui.hwndConsole) return FALSE; gui.hwndUsers = CreateWindowEx( WS_EX_CLIENTEDGE, "LISTBOX", NULL, WS_CHILD|WS_VISIBLE|LBS_STANDARD|LBS_NOINTEGRALHEIGHT, 0, 0, 0, 0, hwnd, 0, 0, NULL); if(!gui.hwndUsers) return FALSE; //amadeo: temp. button for useredit until rightcklick is working.... gui.hwndUserEditButton = CreateWindow( "button", "Edit User Status", WS_CHILD | WS_VISIBLE | ES_LEFT, 0, 0, 0, 0, hwnd, (HMENU) 881, 0, NULL) ; if(!gui.hwndUserEditButton) return FALSE; gui.hwndUserCount = CreateWindowEx( WS_EX_CLIENTEDGE, "edit", " 0 user(s) online:", WS_CHILD|WS_VISIBLE|ES_CENTER|ES_READONLY, 0, 0, 0, 0, hwnd, 0, 0, NULL); if(!gui.hwndUserCount) return FALSE; SendMessage(gui.hwndUserCount, WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),0); SendMessage(gui.hwndUsers, WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),0); SendMessage(gui.hwndUserEditButton, WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),0); BringWindowToTop(gui.hwndUsers); strcpy( gui.szDefaultStatus, "Void" ); gui.y_ratio = (100<<10)/100; gui.x_ratio = (0<<10)/100; return TRUE;}static void guiOnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify){ if( id == IDM_EXIT ) guiOnClose(hwnd); else if( id == IDM_SAVE ) server_save_wraper(); else if( id == IDM_RESTART ) server_restart_wraper(); else if( id == IDM_SHUTDOWN ) server_quit_wraper(); else if( id == IDM_CLEAR ) guiClearLogWindow(); else if( id == IDM_RESTORE ) guiOnShellNotify(IDI_TRAY, WM_LBUTTONDBLCLK); else if(id == IDM_USERLIST) guiOnUpdateUserList(); else if(id == IDM_SERVERCONFIG) guiOnServerConfig (); else if(id == IDM_ABOUT) guiOnAbout (hwnd); else if(id == ID_HELP_CHECKFORUPDATES) guiOnUpdates (); else if(id == IDM_ANN) guiOnAnnounce (hwnd); else if(id == ID_USERACTIONS_KICKUSER) guiOnUserStatusChange(hwnd); else if(id == 881) guiOnUserStatusChange(hwnd);}static void guiOnMenuSelect(HWND hwnd, HMENU hmenu, int item, HMENU hmenuPopup, UINT flags){ // char str[256]; //by greini /*if( item == 0 || flags == -1) SetWindowText( gui.hwndStatus, gui.szDefaultStatus ); else { LoadString( GetWindowInstance(hwnd), item, str, sizeof(str) ); if( str[0] ) SetWindowText( gui.hwndStatus, str ); }*/}static int guiOnShellNotify(int uID, int uMessage){ if(uID == IDI_TRAY) { if(uMessage == WM_LBUTTONDBLCLK) { if( !IsWindowVisible(gui.hwnd) ) ShowWindow(gui.hwnd, SW_RESTORE); SetForegroundWindow(gui.hwnd); } else if(uMessage == WM_RBUTTONDOWN) { POINT cp; GetCursorPos(&cp); SetForegroundWindow(gui.hwnd); TrackPopupMenu(gui.hmenuTray, TPM_LEFTALIGN|TPM_LEFTBUTTON, cp.x, cp.y, 0, gui.hwnd, NULL); } } return 0;}static void guiOnPaint(HWND hwnd){ PAINTSTRUCT ps; HDC dc; dc = BeginPaint(hwnd, &ps); DrawEdge(dc, &gui.rectHDivider, BDR_SUNKEN, BF_MIDDLE); DrawEdge(dc, &gui.rectConsoleEdge, BDR_SUNKEN, BF_RECT); DrawEdge(dc, &gui.rectUsersEdge, BDR_SUNKEN, BF_RECT); EndPaint(hwnd, &ps); UpdateWindow(gui.hwndConsole); UpdateWindow(gui.hwndUsers); UpdateWindow(gui.hwndUserCount); UpdateWindow(gui.hwndUserEditButton);}static void guiOnClose(HWND hwnd){ guiKillTrayIcon(); if( !gui.main_finished ) { eventlog(eventlog_level_debug,__FUNCTION__,"GUI wants server dead..."); exit(0); } else { eventlog(eventlog_level_debug,__FUNCTION__,"GUI wants to exit..."); SetEvent(gui.event_ready); }}static void guiOnSize(HWND hwnd, UINT state, int cx, int cy){ int cy_console, cy_edge, cx_edge, cy_frame, cy_status; if( state == SIZE_MINIMIZED ) { NOTIFYICONDATA dta; dta.cbSize = sizeof(NOTIFYICONDATA); dta.hWnd = hwnd; dta.uID = IDI_TRAY; dta.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; dta.uCallbackMessage = WM_SHELLNOTIFY; dta.hIcon = LoadIcon(GetWindowInstance(hwnd), MAKEINTRESOURCE(IDI_ICON1)); strcpy(dta.szTip, "PvPGN"); strcat(dta.szTip, " "); strcat(dta.szTip, PVPGN_VERSION); Shell_NotifyIcon(NIM_ADD, &dta); ShowWindow(hwnd, SW_HIDE); return; } if (state == SIZE_RESTORED) { NOTIFYICONDATA dta; dta.hWnd = hwnd; dta.uID = IDI_TRAY; Shell_NotifyIcon(NIM_DELETE,&dta); } cy_status = 0; cy_edge = GetSystemMetrics(SM_CYEDGE); cx_edge = GetSystemMetrics(SM_CXEDGE); cy_frame = (cy_edge<<1) + GetSystemMetrics(SM_CYBORDER) + 1; cy_console = ((cy-cy_status-cy_frame-cy_edge*2)*gui.y_ratio)>>10; gui.rectConsoleEdge.left = 0; gui.rectConsoleEdge.right = cx -140; gui.rectConsoleEdge.top = 0; gui.rectConsoleEdge.bottom = cy - cy_status; gui.rectConsole.left = cx_edge; gui.rectConsole.right = cx - 140 -cx_edge; gui.rectConsole.top = cy_edge; gui.rectConsole.bottom = cy - cy_status; gui.rectUsersEdge.left = cx - 140; gui.rectUsersEdge.top = 18; gui.rectUsersEdge.right = cx; gui.rectUsersEdge.bottom = cy - cy_status - 10; gui.rectUsers.left = cx -138; gui.rectUsers.right = cx ; gui.rectUsers.top = 18 + cy_edge; gui.rectUsers.bottom = cy - cy_status -20 ; guiMoveWindow(gui.hwndConsole, &gui.rectConsole); guiMoveWindow(gui.hwndUsers, &gui.rectUsers); MoveWindow(gui.hwndUserCount, cx - 140, 0, 140, 18, TRUE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -