Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
BIN
Server/ManageTool/ChatParser/ChatParser.aps
Normal file
BIN
Server/ManageTool/ChatParser/ChatParser.aps
Normal file
Binary file not shown.
76
Server/ManageTool/ChatParser/ChatParser.cpp
Normal file
76
Server/ManageTool/ChatParser/ChatParser.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
// ChatParser.cpp : 응용 프로그램에 대한 클래스 동작을 정의합니다.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ChatParser.h"
|
||||
#include "ChatParserDlg.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
||||
|
||||
// CChatParserApp
|
||||
|
||||
BEGIN_MESSAGE_MAP(CChatParserApp, CWinApp)
|
||||
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
// CChatParserApp 생성
|
||||
|
||||
CChatParserApp::CChatParserApp()
|
||||
{
|
||||
// TODO: 여기에 생성 코드를 추가합니다.
|
||||
// InitInstance에 모든 중요한 초기화 작업을 배치합니다.
|
||||
}
|
||||
|
||||
|
||||
// 유일한 CChatParserApp 개체입니다.
|
||||
|
||||
CChatParserApp theApp;
|
||||
|
||||
|
||||
// CChatParserApp 초기화
|
||||
|
||||
BOOL CChatParserApp::InitInstance()
|
||||
{
|
||||
// 응용 프로그램 매니페스트가 ComCtl32.dll 버전 6 이상을 사용하여 비주얼 스타일을
|
||||
// 사용하도록 지정하는 경우, Windows XP 상에서 반드시 InitCommonControlsEx()가 필요합니다.
|
||||
// InitCommonControlsEx()를 사용하지 않으면 창을 만들 수 없습니다.
|
||||
INITCOMMONCONTROLSEX InitCtrls;
|
||||
InitCtrls.dwSize = sizeof(InitCtrls);
|
||||
// 응용 프로그램에서 사용할 모든 공용 컨트롤 클래스를 포함하도록
|
||||
// 이 항목을 설정하십시오.
|
||||
InitCtrls.dwICC = ICC_WIN95_CLASSES;
|
||||
InitCommonControlsEx(&InitCtrls);
|
||||
|
||||
CWinApp::InitInstance();
|
||||
|
||||
// 표준 초기화
|
||||
// 이들 기능을 사용하지 않고 최종 실행 파일의 크기를 줄이려면
|
||||
// 아래에서 필요 없는 특정 초기화
|
||||
// 루틴을 제거해야 합니다.
|
||||
// 해당 설정이 저장된 레지스트리 키를 변경하십시오.
|
||||
// TODO: 이 문자열을 회사 또는 조직의 이름과 같은
|
||||
// 적절한 내용으로 수정해야 합니다.
|
||||
SetRegistryKey(_T("로컬 응용 프로그램 마법사에서 생성된 응용 프로그램"));
|
||||
|
||||
CChatParserDlg dlg;
|
||||
m_pMainWnd = &dlg;
|
||||
INT_PTR nResponse = dlg.DoModal();
|
||||
if (nResponse == IDOK)
|
||||
{
|
||||
// TODO: 여기에 [확인]을 클릭하여 대화 상자가 없어질 때 처리할
|
||||
// 코드를 배치합니다.
|
||||
}
|
||||
else if (nResponse == IDCANCEL)
|
||||
{
|
||||
// TODO: 여기에 [취소]를 클릭하여 대화 상자가 없어질 때 처리할
|
||||
// 코드를 배치합니다.
|
||||
}
|
||||
|
||||
// 대화 상자가 닫혔으므로 응용 프로그램의 메시지 펌프를 시작하지 않고 응용 프로그램을 끝낼 수 있도록 FALSE를
|
||||
// 반환합니다.
|
||||
return FALSE;
|
||||
}
|
||||
31
Server/ManageTool/ChatParser/ChatParser.h
Normal file
31
Server/ManageTool/ChatParser/ChatParser.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// ChatParser.h : PROJECT_NAME 응용 프로그램에 대한 주 헤더 파일입니다.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __AFXWIN_H__
|
||||
#error "PCH에 대해 이 파일을 포함하기 전에 'stdafx.h'를 포함합니다."
|
||||
#endif
|
||||
|
||||
#include "resource.h" // 주 기호입니다.
|
||||
|
||||
|
||||
// CChatParserApp:
|
||||
// 이 클래스의 구현에 대해서는 ChatParser.cpp을 참조하십시오.
|
||||
//
|
||||
|
||||
class CChatParserApp : public CWinApp
|
||||
{
|
||||
public:
|
||||
CChatParserApp();
|
||||
|
||||
// 재정의입니다.
|
||||
public:
|
||||
virtual BOOL InitInstance();
|
||||
|
||||
// 구현입니다.
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
extern CChatParserApp theApp;
|
||||
204
Server/ManageTool/ChatParser/ChatParser.rc
Normal file
204
Server/ManageTool/ChatParser/ChatParser.rc
Normal file
@@ -0,0 +1,204 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 한국어 resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_KOR)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
|
||||
#pragma code_page(949)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
|
||||
"#define _AFX_NO_OLE_RESOURCES\r\n"
|
||||
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
|
||||
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
|
||||
"\r\n"
|
||||
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_KOR)\r\n"
|
||||
"LANGUAGE 18, 1\r\n"
|
||||
"#pragma code_page(949)\r\n"
|
||||
"#include ""res\\ChatParser.rc2"" // Microsoft Visual C++ 이외의 다른 도구에서 편집한 리소스입니다.\r\n"
|
||||
"#include ""afxres.rc"" // 표준 구성 요소입니다.\r\n"
|
||||
"#endif\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDR_MAINFRAME ICON "res\\ChatParser.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_ABOUTBOX DIALOGEX 0, 0, 235, 55
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "ChatParser 정보"
|
||||
FONT 9, "MS 셸 대화 상자", 0, 0, 0x1
|
||||
BEGIN
|
||||
ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
|
||||
LTEXT "ChatParser 버전 1.0",IDC_STATIC,40,10,119,8,SS_NOPREFIX
|
||||
LTEXT "Copyright (C) 2008",IDC_STATIC,40,25,119,8
|
||||
DEFPUSHBUTTON "확인",IDOK,178,7,50,16,WS_GROUP
|
||||
END
|
||||
|
||||
IDD_CHATPARSER_DIALOG DIALOGEX 0, 0, 499, 399
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "ChatParser"
|
||||
FONT 9, "굴림", 400, 0, 0x81
|
||||
BEGIN
|
||||
PUSHBUTTON "Open",IDC_OPENFILE,433,7,59,14
|
||||
CONTROL "Oldversion",IDC_OLDVERSION,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,443,25,49,10
|
||||
LISTBOX IDC_CHATLIST,7,40,485,352,LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP
|
||||
EDITTEXT IDC_OPEN_FILENAME,7,7,423,14,ES_AUTOHSCROLL | ES_READONLY
|
||||
COMBOBOX IDC_SERVERID,7,24,52,102,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_ZONEID,61,24,48,124,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "find",IDC_FINDLIST,359,23,59,14
|
||||
COMBOBOX IDC_CHATTYPE,111,24,103,124,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
EDITTEXT IDC_FINDNAME,216,24,86,13,ES_AUTOHSCROLL
|
||||
CONTROL "FindName",IDC_FINDNAMECHK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,304,26,55,10
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,1
|
||||
PRODUCTVERSION 1,0,0,1
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "041203b5"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "TODO: <회사 이름>"
|
||||
VALUE "FileDescription", "TODO: <파일 설명>"
|
||||
VALUE "FileVersion", "1.0.0.1"
|
||||
VALUE "InternalName", "ChatParser.exe"
|
||||
VALUE "LegalCopyright", "TODO: (c) <회사 이름>. All rights reserved."
|
||||
VALUE "OriginalFilename", "ChatParser.exe"
|
||||
VALUE "ProductName", "TODO: <제품 이름>"
|
||||
VALUE "ProductVersion", "1.0.0.1"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x412, 949
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_ABOUTBOX, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 228
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 48
|
||||
END
|
||||
|
||||
IDD_CHATPARSER_DIALOG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 492
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 392
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_ABOUTBOX "ChatParser 정보(&A)..."
|
||||
END
|
||||
|
||||
#endif // 한국어 resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
#define _AFX_NO_SPLITTER_RESOURCES
|
||||
#define _AFX_NO_OLE_RESOURCES
|
||||
#define _AFX_NO_TRACKER_RESOURCES
|
||||
#define _AFX_NO_PROPERTY_RESOURCES
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_KOR)
|
||||
LANGUAGE 18, 1
|
||||
#pragma code_page(949)
|
||||
#include "res\ChatParser.rc2" // Microsoft Visual C++ 이외의 다른 도구에서 편집한 리소스입니다.
|
||||
#include "afxres.rc" // 표준 구성 요소입니다.
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
20
Server/ManageTool/ChatParser/ChatParser.sln
Normal file
20
Server/ManageTool/ChatParser/ChatParser.sln
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChatParser", "ChatParser.vcproj", "{380483B5-D873-4836-9D31-99C0791A6F4F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{380483B5-D873-4836-9D31-99C0791A6F4F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{380483B5-D873-4836-9D31-99C0791A6F4F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{380483B5-D873-4836-9D31-99C0791A6F4F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{380483B5-D873-4836-9D31-99C0791A6F4F}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
BIN
Server/ManageTool/ChatParser/ChatParser.suo
Normal file
BIN
Server/ManageTool/ChatParser/ChatParser.suo
Normal file
Binary file not shown.
311
Server/ManageTool/ChatParser/ChatParser.vcproj
Normal file
311
Server/ManageTool/ChatParser/ChatParser.vcproj
Normal file
@@ -0,0 +1,311 @@
|
||||
<?xml version="1.0" encoding="ks_c_5601-1987"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="ChatParser"
|
||||
ProjectGUID="{380483B5-D873-4836-9D31-99C0791A6F4F}"
|
||||
RootNamespace="ChatParser"
|
||||
Keyword="MFCProj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="false"
|
||||
ValidateParameters="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1042"
|
||||
AdditionalIncludeDirectories="$(IntDir)"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="false"
|
||||
ValidateParameters="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
|
||||
MinimalRebuild="false"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1042"
|
||||
AdditionalIncludeDirectories="$(IntDir)"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="소스 파일"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\ChatParser.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChatParserDlg.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChatParserSetup.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Clipboard.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NFTokenizer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\RegFunctions.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XListBox.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="헤더 파일"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\ChatParser.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChatParserDlg.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChatParserSetup.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Clipboard.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NFTokenizer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\RegFunctions.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Resource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XListBox.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="리소스 파일"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\res\ChatParser.ico"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChatParser.rc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\res\ChatParser.rc2"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\ReadMe.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
<Global
|
||||
Name="RESOURCE_FILE"
|
||||
Value="ChatParser.rc"
|
||||
/>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
564
Server/ManageTool/ChatParser/ChatParserDlg.cpp
Normal file
564
Server/ManageTool/ChatParser/ChatParserDlg.cpp
Normal file
@@ -0,0 +1,564 @@
|
||||
// ChatParserDlg.cpp : 구현 파일
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ChatParser.h"
|
||||
#include "ChatParserDlg.h"
|
||||
#include "NFTokenizer.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
||||
|
||||
// 응용 프로그램 정보에 사용되는 CAboutDlg 대화 상자입니다.
|
||||
|
||||
class CAboutDlg : public CDialog
|
||||
{
|
||||
public:
|
||||
CAboutDlg();
|
||||
|
||||
// 대화 상자 데이터입니다.
|
||||
enum { IDD = IDD_ABOUTBOX };
|
||||
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
|
||||
|
||||
// 구현입니다.
|
||||
protected:
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
|
||||
{
|
||||
}
|
||||
|
||||
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
// CChatParserDlg 대화 상자
|
||||
|
||||
|
||||
|
||||
|
||||
CChatParserDlg::CChatParserDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CChatParserDlg::IDD, pParent)
|
||||
{
|
||||
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
||||
}
|
||||
|
||||
void CChatParserDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
DDX_Control(pDX, IDC_CHATLIST, m_ChatList);
|
||||
DDX_Control(pDX, IDC_OLDVERSION, m_OldVersion);
|
||||
DDX_Control(pDX, IDC_SERVERID, m_ServerGroup);
|
||||
DDX_Control(pDX, IDC_ZONEID, m_ServerZone);
|
||||
DDX_Control(pDX, IDC_CHATTYPE, m_ChatType);
|
||||
DDX_Control(pDX, IDC_FINDNAMECHK, m_FindNameChk);
|
||||
DDX_Control(pDX, IDC_FINDNAME, m_FindName);
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CChatParserDlg, CDialog)
|
||||
ON_WM_SYSCOMMAND()
|
||||
ON_WM_PAINT()
|
||||
ON_WM_QUERYDRAGICON()
|
||||
//}}AFX_MSG_MAP
|
||||
ON_BN_CLICKED(IDC_OPENFILE, &CChatParserDlg::OnBnClickedOpenfile)
|
||||
ON_BN_CLICKED(IDC_FINDLIST, &CChatParserDlg::OnBnClickedFindlist)
|
||||
ON_BN_CLICKED(IDC_FINDNAMECHK, &CChatParserDlg::OnBnClickedFindnamechk)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
// CChatParserDlg 메시지 처리기
|
||||
|
||||
BOOL CChatParserDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// 시스템 메뉴에 "정보..." 메뉴 항목을 추가합니다.
|
||||
|
||||
// IDM_ABOUTBOX는 시스템 명령 범위에 있어야 합니다.
|
||||
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
|
||||
ASSERT(IDM_ABOUTBOX < 0xF000);
|
||||
|
||||
CMenu* pSysMenu = GetSystemMenu(FALSE);
|
||||
if (pSysMenu != NULL)
|
||||
{
|
||||
CString strAboutMenu;
|
||||
strAboutMenu.LoadString(IDS_ABOUTBOX);
|
||||
if (!strAboutMenu.IsEmpty())
|
||||
{
|
||||
pSysMenu->AppendMenu(MF_SEPARATOR);
|
||||
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
|
||||
}
|
||||
}
|
||||
|
||||
// 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는
|
||||
// 프레임워크가 이 작업을 자동으로 수행합니다.
|
||||
SetIcon(m_hIcon, TRUE); // 큰 아이콘을 설정합니다.
|
||||
SetIcon(m_hIcon, FALSE); // 작은 아이콘을 설정합니다.
|
||||
|
||||
// TODO: 여기에 추가 초기화 작업을 추가합니다.
|
||||
SetDlgItemText(IDC_OPENFILE, GetMyINIString("LOCAL_STRING", "STRING_01"));
|
||||
SetDlgItemText(IDC_OLDVERSION, GetMyINIString("LOCAL_STRING", "STRING_02"));
|
||||
|
||||
SetDlgItemText(IDC_FINDLIST, GetMyINIString("LOCAL_STRING", "STRING_04"));
|
||||
|
||||
SetDlgItemText(IDC_FINDNAMECHK, GetMyINIString("LOCAL_STRING", "STRING_05"));
|
||||
m_FindName.EnableWindow(FALSE);
|
||||
|
||||
int iCount = atoi(GetMyINIString("SERVER_GROUP", "SERVER_GROUP_CNT"));
|
||||
|
||||
char strID[32];
|
||||
char strName[32];
|
||||
|
||||
m_ServerGroup.AddString("All");
|
||||
for(int i = 0; i < iCount; ++i)
|
||||
{
|
||||
wsprintf(strID, "SERVER_GROUP%d", i+1);
|
||||
m_ServerGroup.AddString(GetMyINIString("SERVER_GROUP", strID));
|
||||
}
|
||||
m_ServerGroup.SetCurSel(0);
|
||||
|
||||
|
||||
iCount = atoi(GetMyINIString("SERVER_ZONE", "SERVER_ZONE_CNT"));
|
||||
|
||||
m_ServerZone.AddString("All");
|
||||
for(int i = 0; i < iCount; ++i)
|
||||
{
|
||||
wsprintf(strID, "SERVER_ZONE%d", i+1);
|
||||
wsprintf(strName, "ZONE%s", GetMyINIString("SERVER_ZONE", strID));
|
||||
|
||||
m_ServerZone.AddString(strName);
|
||||
}
|
||||
m_ServerZone.SetCurSel(0);
|
||||
|
||||
|
||||
iCount = atoi(GetMyINIString("CHAT_TYPE", "CHAT_TYPE_CNT"));
|
||||
|
||||
m_ChatType.AddString("All");
|
||||
for(int i = 0; i < iCount; ++i)
|
||||
{
|
||||
wsprintf(strID, "CHAT_TYPE%d", i+1);
|
||||
m_ChatType.AddString(GetMyINIString("CHAT_TYPE", strID));
|
||||
}
|
||||
m_ChatType.SetCurSel(0);
|
||||
|
||||
|
||||
memset(&m_OpenFile, 0, sizeof(OPENFILENAME));
|
||||
|
||||
m_OpenFile.lStructSize = sizeof(OPENFILENAME);
|
||||
m_OpenFile.hwndOwner = m_hWnd;
|
||||
m_OpenFile.lpstrFilter = "Chat Log files\0*.log\0All files\0*.*";
|
||||
m_OpenFile.nMaxFile = MAX_PATH * MAX_PATH;
|
||||
m_OpenFile.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_EXPLORER;
|
||||
m_OpenFile.lpstrFile = m_szFileName;
|
||||
|
||||
return TRUE; // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
|
||||
}
|
||||
|
||||
void CChatParserDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
||||
{
|
||||
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
|
||||
{
|
||||
CAboutDlg dlgAbout;
|
||||
dlgAbout.DoModal();
|
||||
}
|
||||
else
|
||||
{
|
||||
CDialog::OnSysCommand(nID, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
// 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면
|
||||
// 아래 코드가 필요합니다. 문서/뷰 모델을 사용하는 MFC 응용 프로그램의 경우에는
|
||||
// 프레임워크에서 이 작업을 자동으로 수행합니다.
|
||||
|
||||
void CChatParserDlg::OnPaint()
|
||||
{
|
||||
if (IsIconic())
|
||||
{
|
||||
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트
|
||||
|
||||
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
|
||||
|
||||
// 클라이언트 사각형에서 아이콘을 가운데에 맞춥니다.
|
||||
int cxIcon = GetSystemMetrics(SM_CXICON);
|
||||
int cyIcon = GetSystemMetrics(SM_CYICON);
|
||||
CRect rect;
|
||||
GetClientRect(&rect);
|
||||
int x = (rect.Width() - cxIcon + 1) / 2;
|
||||
int y = (rect.Height() - cyIcon + 1) / 2;
|
||||
|
||||
// 아이콘을 그립니다.
|
||||
dc.DrawIcon(x, y, m_hIcon);
|
||||
}
|
||||
else
|
||||
{
|
||||
CDialog::OnPaint();
|
||||
}
|
||||
}
|
||||
|
||||
// 사용자가 최소화된 창을 끄는 동안에 커서가 표시되도록 시스템에서
|
||||
// 이 함수를 호출합니다.
|
||||
HCURSOR CChatParserDlg::OnQueryDragIcon()
|
||||
{
|
||||
return static_cast<HCURSOR>(m_hIcon);
|
||||
}
|
||||
|
||||
// 추가
|
||||
void CChatParserDlg::AddLineToChatList(unsigned char cChatType, char* szMsg)
|
||||
{
|
||||
CXListBox::Color cBackColor = CXListBox::BackColor;
|
||||
CXListBox::Color cMessageColor = CXListBox::ChatNormal;
|
||||
|
||||
switch(cChatType)
|
||||
{
|
||||
case NORMAL:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatNormal;
|
||||
break;
|
||||
case PARTY:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatParty;
|
||||
break;
|
||||
case FRIEND:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatFriend;
|
||||
break;
|
||||
case GUILD:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatGuild;
|
||||
break;
|
||||
case CLIENT_LOG:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatNormal;
|
||||
break;
|
||||
case STALL:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatStall;
|
||||
break;
|
||||
case SHOUT:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatShout;
|
||||
break;
|
||||
case ADMIN_NORMAL_CHAT:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatAdminNormal;
|
||||
break;
|
||||
case ADMIN_SHOUT:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatAdminShout;
|
||||
break;
|
||||
case WHISPER:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatWhisper;
|
||||
break;
|
||||
case TRADE:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatTrade;
|
||||
break;
|
||||
case NOTICE:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatNotice;
|
||||
break;
|
||||
case DICE:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::ChatAdminShout;
|
||||
break;
|
||||
case GMREPORT:
|
||||
cBackColor = CXListBox::BackColor; cMessageColor = CXListBox::GMReport;
|
||||
break;
|
||||
}
|
||||
|
||||
m_ChatList.AddLine(cMessageColor, cBackColor, szMsg, FALSE);
|
||||
}
|
||||
|
||||
void CChatParserDlg::Cleanup()
|
||||
{
|
||||
m_ChatList.ResetContent();
|
||||
}
|
||||
|
||||
void CChatParserDlg::OnBnClickedOpenfile()
|
||||
{
|
||||
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
|
||||
ZeroMemory(m_szFileName, MAX_PATH);
|
||||
|
||||
if(GetOpenFileName(&m_OpenFile))
|
||||
{
|
||||
// 파서하기
|
||||
LoadFile();
|
||||
|
||||
SetDlgItemText(IDC_OPEN_FILENAME, m_szFileName);
|
||||
}
|
||||
}
|
||||
|
||||
void CChatParserDlg::LoadFile()
|
||||
{
|
||||
FILE* fp = fopen(m_szFileName, "rt");
|
||||
if(fp == NULL)
|
||||
return;
|
||||
|
||||
Cleanup();
|
||||
m_ChatData.clear();
|
||||
|
||||
int iCount = 0;
|
||||
|
||||
BOOL bOldVersion = FALSE;
|
||||
|
||||
if(m_OldVersion.GetCheck())
|
||||
bOldVersion = TRUE;
|
||||
|
||||
char strData[2048];
|
||||
int Len = 0;
|
||||
|
||||
CHATLIST st;
|
||||
|
||||
while(!feof(fp))
|
||||
{
|
||||
fgets(strData, 2048, fp);
|
||||
|
||||
if(strncmp(strData, "[Ty-NOR]", 8) == 0)
|
||||
break;
|
||||
else
|
||||
{
|
||||
std::string str = strData;
|
||||
std::string temp, temp2;
|
||||
Nave::NFTokenizerA token(str, "[");
|
||||
int iToken = token.CountTokens();
|
||||
DWORD dwServerID = 0;
|
||||
int Temp = 0;
|
||||
|
||||
for(int i = 0; i < iToken; ++i)
|
||||
{
|
||||
temp = token.NextToken();
|
||||
|
||||
if(i == 0) // 시간
|
||||
{
|
||||
sscanf(temp.c_str(), "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
&st.sysTime.wYear, &st.sysTime.wMonth, &st.sysTime.wDay,
|
||||
&st.sysTime.wHour, &st.sysTime.wMinute, &st.sysTime.wSecond);
|
||||
}
|
||||
else if(i == 1)
|
||||
{
|
||||
sscanf(temp.c_str(), "ServerID:0x%08x", &dwServerID);
|
||||
}
|
||||
else if(i == 2)
|
||||
{
|
||||
temp2 = &temp[6];
|
||||
temp2.erase(temp2.end()-1);
|
||||
int n = temp2.find_first_of(" ");
|
||||
strcpy(st.strServerName, temp2.c_str());
|
||||
st.strServerName[n] = 0;
|
||||
}
|
||||
else if(i == 3)
|
||||
{
|
||||
sscanf(temp.c_str(), "Zone:%2d", &st.iZone);
|
||||
}
|
||||
else if(i == 4)
|
||||
{
|
||||
sscanf(temp.c_str(), "CH:%2d", &st.iChannel);
|
||||
}
|
||||
else if(i == 5)
|
||||
{
|
||||
sscanf(temp.c_str(), "X:%4d", &Temp);
|
||||
}
|
||||
else if(i == 6)
|
||||
{
|
||||
sscanf(temp.c_str(), "Z:%4d", &Temp);
|
||||
}
|
||||
else if(i == 7)
|
||||
{
|
||||
sscanf(temp.c_str(), "UID:%10d", &st.dwUID);
|
||||
}
|
||||
else if(i == 8)
|
||||
{
|
||||
sscanf(temp.c_str(), "CID:%10d", &st.dwCID);
|
||||
}
|
||||
else if(i == 9)
|
||||
{
|
||||
sscanf(temp.c_str(), "Type:%2d", &st.iChatType);
|
||||
}
|
||||
else if(i == 10)
|
||||
{
|
||||
temp2 = &temp[2];
|
||||
temp2.erase(temp2.end()-1);
|
||||
int n = temp2.find_last_not_of(" ");
|
||||
strcpy(st.strSenderName, temp2.c_str());
|
||||
st.strSenderName[n+1] = 0;
|
||||
}
|
||||
else if(i == 11)
|
||||
{
|
||||
temp2 = &temp[2];
|
||||
temp2.erase(temp2.end()-1);
|
||||
int n = temp2.find_last_not_of(" ");
|
||||
strcpy(st.strTargetName, temp2.c_str());
|
||||
st.strTargetName[n+1] = 0;
|
||||
}
|
||||
else if(i == 12)
|
||||
{
|
||||
strncpy(st.strMessage, temp.c_str(), temp.size()-2);
|
||||
st.strMessage[temp.size()-2] = 0;
|
||||
}
|
||||
}
|
||||
m_ChatData[iCount++] = st;
|
||||
|
||||
}
|
||||
/*
|
||||
if(strncmp(strData, "[Ty-NOR]", 8) == 0)
|
||||
break;
|
||||
else
|
||||
{
|
||||
// 시간 읽기
|
||||
sscanf(strData, "[%04d-%02d-%02d %02d:%02d:%02d]",
|
||||
&st.sysTime.wYear, &st.sysTime.wMonth, &st.sysTime.wDay,
|
||||
&st.sysTime.wHour, &st.sysTime.wMinute, &st.sysTime.wSecond);
|
||||
|
||||
// 그룹
|
||||
sscanf(&strData[21], "[Group:%s]", st.strServerName);
|
||||
|
||||
// 아이디들
|
||||
sscanf(&strData[44], "[Zone:%2d][CH:%2d][UID:%10d][CID:%10d][Type:%2d]", &st.iZone, &st.iChannel, &st.dwUID, &st.dwCID, &st.iChatType);
|
||||
|
||||
if(strncmp(&strData[101], "[S:", 3) == 0)
|
||||
{
|
||||
// Sender
|
||||
sscanf(&strData[101], "[S:%s]", st.strSenderName);
|
||||
|
||||
// Target
|
||||
sscanfe(&strData[120], "[T:%s]", st.strTargetName);
|
||||
if(st.strTargetName[0] == ']')
|
||||
ZeroMemory(st.strTargetName, 32);
|
||||
|
||||
// Msg
|
||||
strcpy(st.strMessage, &strData[140]);
|
||||
Len = (int)strlen(st.strMessage);
|
||||
if(st.strMessage[Len-2] == ']')
|
||||
st.strMessage[Len-2] = 0;
|
||||
else
|
||||
st.strMessage[Len-1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Msg
|
||||
strcpy(st.strMessage, &strData[102]);
|
||||
Len = (int)strlen(st.strMessage);
|
||||
if(st.strMessage[Len-2] == ']')
|
||||
st.strMessage[Len-2] = 0;
|
||||
else
|
||||
st.strMessage[Len-1] = 0;
|
||||
}
|
||||
m_ChatData[iCount++] = st;
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
m_ChatList.AddString(GetMyINIString("LOCAL_STRING", "STRING_03"));
|
||||
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void CChatParserDlg::OnBnClickedFindlist()
|
||||
{
|
||||
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
|
||||
Cleanup();
|
||||
|
||||
char strData[2048];
|
||||
int Len = 0;
|
||||
|
||||
char strTemp[32];
|
||||
char strServerGroup[32];
|
||||
|
||||
int iGroupID = m_ServerGroup.GetCurSel();
|
||||
if(iGroupID != 0)
|
||||
{
|
||||
m_ServerGroup.GetWindowText(strServerGroup, 32);
|
||||
}
|
||||
|
||||
int iZoneID = m_ServerZone.GetCurSel();
|
||||
if(iZoneID != 0)
|
||||
{
|
||||
iZoneID = 0;
|
||||
m_ServerZone.GetWindowText(strTemp, 32);
|
||||
sscanf(strTemp, "ZONE%d", &iZoneID);
|
||||
}
|
||||
|
||||
int iChatType = m_ChatType.GetCurSel();
|
||||
if(iChatType != 0)
|
||||
{
|
||||
m_ChatType.GetWindowText(strTemp, 32);
|
||||
iChatType = GetChatType(strTemp);
|
||||
}
|
||||
|
||||
char strName[64];
|
||||
BOOL bFindName = FALSE;
|
||||
if(m_FindNameChk.GetCheck())
|
||||
{
|
||||
bFindName = TRUE;
|
||||
|
||||
m_FindName.GetWindowText(strName, 64);
|
||||
}
|
||||
else
|
||||
{
|
||||
ZeroMemory(strName, 64);
|
||||
}
|
||||
|
||||
// 출력
|
||||
std::map<int, CHATLIST>::iterator obj = m_ChatData.begin();
|
||||
std::map<int, CHATLIST>::iterator end = m_ChatData.end();
|
||||
|
||||
BOOL bAddItem;
|
||||
|
||||
while(obj != end)
|
||||
{
|
||||
CHATLIST& st = obj->second;
|
||||
bAddItem = TRUE;
|
||||
|
||||
if(iGroupID != 0 && strcmp(strServerGroup, st.strServerName) != 0)
|
||||
{
|
||||
bAddItem = FALSE;
|
||||
}
|
||||
|
||||
if(iZoneID != 0 && st.iZone != iZoneID)
|
||||
{
|
||||
bAddItem = FALSE;
|
||||
}
|
||||
|
||||
if(iChatType != 0 && st.iChatType != iChatType)
|
||||
{
|
||||
bAddItem = FALSE;
|
||||
}
|
||||
|
||||
if(bFindName)
|
||||
{
|
||||
if(strcmp(strName, st.strSenderName) != 0 && strcmp(strName, st.strTargetName) != 0)
|
||||
bAddItem = FALSE;
|
||||
}
|
||||
|
||||
if(bAddItem)
|
||||
{
|
||||
if(st.iChatType-1 == WHISPER)
|
||||
{
|
||||
if(strlen(st.strTargetName) == 0)
|
||||
wsprintf(strData, "%-15s[Z:%02d/C:%d][%02d:%02d] %s", st.strServerName, st.iZone, st.iChannel, st.sysTime.wHour, st.sysTime.wMinute, st.strMessage);
|
||||
else
|
||||
wsprintf(strData, "%-15s[Z:%02d/C:%d][%02d:%02d] %s (To: %s)", st.strServerName, st.iZone, st.iChannel, st.sysTime.wHour, st.sysTime.wMinute, st.strMessage, st.strTargetName);
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf(strData, "%-15s[Z:%02d/C:%d][%02d:%02d] %s", st.strServerName, st.iZone, st.iChannel, st.sysTime.wHour, st.sysTime.wMinute, st.strMessage);
|
||||
}
|
||||
|
||||
if(iChatType == 0)
|
||||
AddLineToChatList(st.iChatType-1, strData);
|
||||
else
|
||||
AddLineToChatList(iChatType-1, strData);
|
||||
}
|
||||
|
||||
++obj;
|
||||
}
|
||||
|
||||
UpdateData(false);
|
||||
|
||||
}
|
||||
|
||||
void CChatParserDlg::OnBnClickedFindnamechk()
|
||||
{
|
||||
m_FindName.EnableWindow(m_FindNameChk.GetCheck());
|
||||
}
|
||||
92
Server/ManageTool/ChatParser/ChatParserDlg.h
Normal file
92
Server/ManageTool/ChatParser/ChatParserDlg.h
Normal file
@@ -0,0 +1,92 @@
|
||||
// ChatParserDlg.h : 헤더 파일
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "afxwin.h"
|
||||
#include "XListBox.h"
|
||||
#include <map>
|
||||
|
||||
typedef struct CHATLIST
|
||||
{
|
||||
SYSTEMTIME sysTime;
|
||||
|
||||
char strServerName[32];
|
||||
|
||||
int iZone;
|
||||
int iChannel;
|
||||
unsigned long dwUID;
|
||||
unsigned long dwCID;
|
||||
int iChatType;
|
||||
|
||||
char strSenderName[32];
|
||||
char strTargetName[32];
|
||||
char strMessage[512];
|
||||
|
||||
CHATLIST()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
ZeroMemory(&sysTime, sizeof(sysTime));
|
||||
iZone=0;
|
||||
iChannel=0;
|
||||
dwUID=0;
|
||||
dwCID=0;
|
||||
iChatType=0;
|
||||
ZeroMemory(strServerName, 32);
|
||||
ZeroMemory(strSenderName, 32);
|
||||
ZeroMemory(strTargetName, 32);
|
||||
ZeroMemory(strMessage, 512);
|
||||
}
|
||||
}CHATLIST;
|
||||
|
||||
// CChatParserDlg 대화 상자
|
||||
class CChatParserDlg : public CDialog
|
||||
{
|
||||
// 생성입니다.
|
||||
public:
|
||||
CChatParserDlg(CWnd* pParent = NULL); // 표준 생성자입니다.
|
||||
|
||||
// 대화 상자 데이터입니다.
|
||||
enum { IDD = IDD_CHATPARSER_DIALOG };
|
||||
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
|
||||
|
||||
void AddLineToChatList(unsigned char cChatType, char* szMsg);
|
||||
void Cleanup();
|
||||
void LoadFile();
|
||||
|
||||
|
||||
// 구현입니다.
|
||||
protected:
|
||||
HICON m_hIcon;
|
||||
|
||||
// 생성된 메시지 맵 함수
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
|
||||
afx_msg void OnPaint();
|
||||
afx_msg HCURSOR OnQueryDragIcon();
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
OPENFILENAME m_OpenFile;
|
||||
char m_szFileName[MAX_PATH * MAX_PATH];
|
||||
|
||||
std::map<int, CHATLIST> m_ChatData;
|
||||
|
||||
CXListBox m_ChatList;
|
||||
CButton m_OldVersion;
|
||||
CComboBox m_ServerGroup;
|
||||
CComboBox m_ServerZone;
|
||||
CComboBox m_ChatType;
|
||||
CButton m_FindNameChk;
|
||||
CEdit m_FindName;
|
||||
|
||||
public:
|
||||
afx_msg void OnBnClickedOpenfile();
|
||||
afx_msg void OnBnClickedFindlist();
|
||||
afx_msg void OnBnClickedFindnamechk();
|
||||
};
|
||||
15
Server/ManageTool/ChatParser/ChatParserSetup.cpp
Normal file
15
Server/ManageTool/ChatParser/ChatParserSetup.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "stdafx.h"
|
||||
#include "ChatParserSetup.h"
|
||||
|
||||
|
||||
CChatParserSetup::CChatParserSetup(const char* szFileName)
|
||||
: Registry::CSetupFile(szFileName)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CChatParserSetup& CChatParserSetup::GetInstance()
|
||||
{
|
||||
static CChatParserSetup setup("./ChatParserSetup.ini");
|
||||
return setup;
|
||||
}
|
||||
17
Server/ManageTool/ChatParser/ChatParserSetup.h
Normal file
17
Server/ManageTool/ChatParser/ChatParserSetup.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _GAMA_NETWORK_CHAT_SETUP_H_
|
||||
#define _GAMA_NETWORK_CHAT_SETUP_H_
|
||||
|
||||
#include "RegFunctions.h"
|
||||
|
||||
/** \class CChatParserSetup
|
||||
모니터링 툴 셋업 클래스*/
|
||||
class CChatParserSetup : public Registry::CSetupFile
|
||||
{
|
||||
public:
|
||||
|
||||
CChatParserSetup(const char* szFileName);
|
||||
static CChatParserSetup& GetInstance();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
42
Server/ManageTool/ChatParser/ChatParserSetup.ini
Normal file
42
Server/ManageTool/ChatParser/ChatParserSetup.ini
Normal file
@@ -0,0 +1,42 @@
|
||||
[SERVER_GROUP]
|
||||
SERVER_GROUP_CNT = 1
|
||||
SERVER_GROUP1 = Ichman
|
||||
|
||||
[SERVER_ZONE]
|
||||
SERVER_ZONE_CNT = 9
|
||||
SERVER_ZONE1 = 1
|
||||
SERVER_ZONE2 = 2
|
||||
SERVER_ZONE3 = 4
|
||||
SERVER_ZONE4 = 5
|
||||
SERVER_ZONE5 = 8
|
||||
SERVER_ZONE6 = 12
|
||||
SERVER_ZONE7 = 16
|
||||
SERVER_ZONE8 = 17
|
||||
SERVER_ZONE9 = 18
|
||||
|
||||
[CHAT_TYPE]
|
||||
CHAT_TYPE_CNT = 17
|
||||
CHAT_TYPE1 = NORMAL
|
||||
CHAT_TYPE2 = PARTY
|
||||
CHAT_TYPE3 = FRIEND
|
||||
CHAT_TYPE4 = GUILD
|
||||
CHAT_TYPE5 = CLIENT_LOG
|
||||
CHAT_TYPE6 = STALL
|
||||
CHAT_TYPE7 = SHOUT
|
||||
CHAT_TYPE8 = ADMIN_NORMAL_CHAT
|
||||
CHAT_TYPE9 = ADMIN_SHOUT
|
||||
CHAT_TYPE10 = WHISPER
|
||||
CHAT_TYPE11 = TRADE
|
||||
CHAT_TYPE12 = CAMP_SHOP
|
||||
CHAT_TYPE13 = NOTIFY_CHAR_INFO
|
||||
CHAT_TYPE14 = FIND_PARTY
|
||||
CHAT_TYPE15 = ENEMY_CHECK
|
||||
CHAT_TYPE16 = DICE
|
||||
CHAT_TYPE17 = NOTICE
|
||||
|
||||
[LOCAL_STRING]
|
||||
STRING_01 = 열기
|
||||
STRING_02 = 구버젼 로그
|
||||
STRING_03 = 로딩 완료.
|
||||
STRING_04 = 검색
|
||||
STRING_05 = 이름검색
|
||||
253
Server/ManageTool/ChatParser/Clipboard.cpp
Normal file
253
Server/ManageTool/ChatParser/Clipboard.cpp
Normal file
@@ -0,0 +1,253 @@
|
||||
// CClipboard Class
|
||||
// ----------------
|
||||
// Written by David Terracino <davet@lycosemail.com>
|
||||
//
|
||||
// This code is released into the public domain, because
|
||||
// it's silly easy. If you want to use and expand it, go
|
||||
// ahead; fine by me. If you do expand this class's
|
||||
// functionality, please consider sending it back up to
|
||||
// the MFC Programmer's Sourcebook at www.codeguru.com.
|
||||
//
|
||||
// And as always, please give credit where credit is
|
||||
// due. Don't remove my name from the source.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Modified by Hans Dietrich hdietrich2@hotmail.com
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Clipboard.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// GetText - Retrieves text from the clipboard
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// Return Values:
|
||||
// CString - not empty if text was successfully copied from clipboard
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CString CClipboard::GetText()
|
||||
{
|
||||
CString str;
|
||||
str = _T("");
|
||||
|
||||
// First, open the clipboard. OpenClipboard() takes one
|
||||
// parameter, the handle of the window that will temporarily
|
||||
// be it's owner. If NULL is passed, the current process
|
||||
// is assumed.
|
||||
if (::OpenClipboard(NULL))
|
||||
{
|
||||
// Request a pointer to the text on the clipboard.
|
||||
HGLOBAL hGlobal = ::GetClipboardData(CF_TEXT);
|
||||
|
||||
// If there was no text on the clipboard, we have
|
||||
// been returned a NULL handle.
|
||||
if (hGlobal)
|
||||
{
|
||||
// Now we have a global memory handle to the text
|
||||
// stored on the clipboard. We have to lock this global
|
||||
// handle so that we have access to it.
|
||||
LPSTR lpszData = (LPSTR) ::GlobalLock(hGlobal);
|
||||
|
||||
if (lpszData)
|
||||
{
|
||||
str = lpszData;
|
||||
|
||||
// Now, simply unlock the global memory pointer
|
||||
// and close the clipboard.
|
||||
::GlobalUnlock(hGlobal);
|
||||
}
|
||||
}
|
||||
::CloseClipboard();
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// GetText - Retrieves text from the clipboard
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parameters:
|
||||
// lpszBuffer - pointer to a string where the text is to be put
|
||||
// nBufSize - allocated length of lpszBuffer
|
||||
//
|
||||
// Return Values:
|
||||
// TRUE - Text was successfully retrieved
|
||||
// FALSE - No text returned
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL CClipboard::GetText(LPSTR lpszBuffer, int nBufSize)
|
||||
{
|
||||
ASSERT(lpszBuffer);
|
||||
if (lpszBuffer == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (nBufSize == 0)
|
||||
return FALSE;
|
||||
|
||||
lpszBuffer[0] = 0;
|
||||
|
||||
BOOL bSuccess = FALSE;
|
||||
|
||||
// First, open the clipboard. OpenClipboard() takes one
|
||||
// parameter, the handle of the window that will temporarily
|
||||
// be it's owner. If NULL is passed, the current process
|
||||
// is assumed.
|
||||
if (::OpenClipboard(NULL))
|
||||
{
|
||||
// Request a pointer to the text on the clipboard.
|
||||
HGLOBAL hGlobal = ::GetClipboardData(CF_TEXT);
|
||||
|
||||
// If there was no text on the clipboard, we have
|
||||
// been returned a NULL handle.
|
||||
if (hGlobal)
|
||||
{
|
||||
// Now we have a global memory handle to the text
|
||||
// stored on the clipboard. We have to lock this global
|
||||
// handle so that we have access to it.
|
||||
LPSTR lpszData = (LPSTR) ::GlobalLock(hGlobal);
|
||||
|
||||
if (lpszData)
|
||||
{
|
||||
// Now get the size of the text on the clipboard.
|
||||
DWORD nSize = (DWORD)::GlobalSize(hGlobal);
|
||||
|
||||
// Make sure the text on the clipboard is not longer
|
||||
// that the buffer that was allocated for it. If it was
|
||||
// snip the text on the clipboard so that it fits.
|
||||
if (nSize >= (UINT)nBufSize)
|
||||
nSize = nBufSize - 1;
|
||||
|
||||
// Now, copy the text into the return buffer. Note that
|
||||
// there will be at least one nul at the end
|
||||
ZeroMemory(lpszBuffer, nBufSize);
|
||||
CopyMemory(lpszBuffer, lpszData, nSize);
|
||||
|
||||
// Now, simply unlock the global memory pointer
|
||||
// and close the clipboard.
|
||||
::GlobalUnlock(hGlobal);
|
||||
bSuccess = TRUE;
|
||||
}
|
||||
}
|
||||
::CloseClipboard();
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// GetTextLength - Retrieves length of text on the clipboard
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// Return Values:
|
||||
// > 0 - Text length was successfully returned.
|
||||
// 0 - No text on the clipboard
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DWORD CClipboard::GetTextLength()
|
||||
{
|
||||
DWORD nSize = 0; // Size of clipboard data
|
||||
|
||||
// First, open the clipboard. OpenClipboard() takes one
|
||||
// parameter, the handle of the window that will temporarily
|
||||
// be it's owner. If NULL is passed, the current process
|
||||
// is assumed.
|
||||
if (::OpenClipboard(NULL))
|
||||
{
|
||||
// Request a pointer to the text on the clipboard.
|
||||
HGLOBAL hGlobal = ::GetClipboardData(CF_TEXT);
|
||||
|
||||
// If there was no text on the clipboard, we have
|
||||
// been returned a NULL handle.
|
||||
if (hGlobal)
|
||||
{
|
||||
// Now we have a global memory handle to the text
|
||||
// stored on the clipboard. We have to lock this global
|
||||
// handle so that we have access to it.
|
||||
LPSTR lpszData = (LPSTR) ::GlobalLock(hGlobal);
|
||||
|
||||
if (lpszData)
|
||||
{
|
||||
// Now get the size of the text on the clipboard.
|
||||
nSize = (DWORD)::GlobalSize(hGlobal);
|
||||
|
||||
// Now, simply unlock the global memory pointer
|
||||
// and close the clipboard.
|
||||
::GlobalUnlock(hGlobal);
|
||||
}
|
||||
}
|
||||
::CloseClipboard();
|
||||
}
|
||||
|
||||
return nSize;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SetText - Places text on the clipboard
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parameters:
|
||||
// lpszBuffer - pointer to a string to put on the clipboard
|
||||
//
|
||||
// Return Values:
|
||||
// TRUE - Text was successfully copied onto clipboard
|
||||
// FALSE - Text not copied
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL CClipboard::SetText(LPCTSTR lpszBuffer)
|
||||
{
|
||||
BOOL bSuccess = FALSE;
|
||||
|
||||
// First, open the clipboard. OpenClipboard() takes one
|
||||
// parameter, the handle of the window that will temporarily
|
||||
// be it's owner. If NULL is passed, the current process
|
||||
// is assumed. After opening, empty the clipboard so we
|
||||
// can put our text on it.
|
||||
if (::OpenClipboard(NULL))
|
||||
{
|
||||
::EmptyClipboard();
|
||||
|
||||
// Get the size of the string in the buffer that was
|
||||
// passed into the function, so we know how much global
|
||||
// memory to allocate for the string.
|
||||
int nSize = (int)_tcslen(lpszBuffer);
|
||||
|
||||
// Allocate the memory for the string.
|
||||
HGLOBAL hGlobal = ::GlobalAlloc(GMEM_ZEROINIT, nSize+1);
|
||||
|
||||
// If we got any error during the memory allocation,
|
||||
// we have been returned a NULL handle.
|
||||
if (hGlobal)
|
||||
{
|
||||
// Now we have a global memory handle to the text
|
||||
// stored on the clipboard. We have to lock this global
|
||||
// handle so that we have access to it.
|
||||
LPTSTR lpszData = (LPTSTR) ::GlobalLock(hGlobal);
|
||||
|
||||
if (lpszData)
|
||||
{
|
||||
// Now, copy the text from the buffer into the allocated
|
||||
// global memory pointer
|
||||
_tcscpy(lpszData, lpszBuffer);
|
||||
|
||||
// Now, simply unlock the global memory pointer,
|
||||
// set the clipboard data type and pointer,
|
||||
// and close the clipboard.
|
||||
::GlobalUnlock(hGlobal);
|
||||
::SetClipboardData(CF_TEXT, hGlobal);
|
||||
bSuccess = TRUE;
|
||||
}
|
||||
}
|
||||
::CloseClipboard();
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
29
Server/ManageTool/ChatParser/Clipboard.h
Normal file
29
Server/ManageTool/ChatParser/Clipboard.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// CClipboard Class
|
||||
// ----------------
|
||||
// Written by David Terracino <davet@lycosemail.com>
|
||||
//
|
||||
// This code is released into the public domain, because
|
||||
// it's silly easy. If you want to use and expand it, go
|
||||
// ahead; fine by me. If you do expand this class's
|
||||
// functionality, please consider sending it back up to
|
||||
// the MFC Programmer's Sourcebook at www.codeguru.com.
|
||||
//
|
||||
// And as always, please give credit where credit is
|
||||
// due. Don't remove my name from the source.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Modified by Hans Dietrich hdietrich2@hotmail.com
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef CCLIPBOARD_H
|
||||
#define CCLIPBOARD_H
|
||||
|
||||
class CClipboard
|
||||
{
|
||||
public:
|
||||
static CString GetText();
|
||||
static BOOL GetText(LPSTR lpszBuffer, int nBufSize);
|
||||
static DWORD GetTextLength();
|
||||
static BOOL SetText(LPCTSTR lpszBuffer);
|
||||
};
|
||||
|
||||
#endif
|
||||
85
Server/ManageTool/ChatParser/ReadMe.txt
Normal file
85
Server/ManageTool/ChatParser/ReadMe.txt
Normal file
@@ -0,0 +1,85 @@
|
||||
================================================================================
|
||||
MFC 라이브러리 : ChatParser 프로젝트 개요
|
||||
===============================================================================
|
||||
|
||||
응용 프로그램 마법사에서 이 ChatParser 응용 프로그램을
|
||||
만들었습니다. 이 응용 프로그램은 MFC의 기본 사용법을 보여 줄 뿐만 아니라 응용 프로그램
|
||||
작성을 위한 기본 구조를 제공합니다.
|
||||
|
||||
이 파일에는 ChatParser 응용 프로그램을 구성하는 각 파일에 대한
|
||||
요약 설명이 포함되어 있습니다.
|
||||
|
||||
ChatParser.vcproj
|
||||
응용 프로그램 마법사를 사용하여 생성된 VC++ 프로젝트의 주 프로젝트 파일입니다.
|
||||
파일을 생성한 Visual C++ 버전에 대한 정보와 응용 프로그램 마법사를 사용하여 선택한
|
||||
플랫폼, 구성 및 프로젝트 기능에 대한 정보가 들어 있습니다.
|
||||
|
||||
ChatParser.h
|
||||
응용 프로그램의 기본 헤더 파일입니다. 여기에는 다른 프로젝트 관련
|
||||
헤더(Resource.h 포함)가 들어 있고 CChatParserApp 응용 프로그램
|
||||
클래스를 선언합니다.
|
||||
|
||||
ChatParser.cpp
|
||||
응용 프로그램 클래스 CChatParserApp이(가) 들어 있는 기본 응용 프로그램
|
||||
소스 파일입니다.
|
||||
|
||||
ChatParser.rc
|
||||
프로그램에서 사용하는 모든 Microsoft Windows 리소스의 목록입니다.
|
||||
여기에는 RES 하위 디렉터리에 저장된 아이콘, 비트맵 및 커서가
|
||||
포함됩니다. 이 파일은 Microsoft Visual C++에서 직접
|
||||
편집할 수 있습니다. 프로젝트 리소스는 1042에 있습니다.
|
||||
|
||||
res\ChatParser.ico
|
||||
응용 프로그램의 아이콘으로 사용되는 아이콘 파일입니다. 이 아이콘은
|
||||
주 리소스 파일인 ChatParser.rc에 의해 포함됩니다.
|
||||
|
||||
res\ChatParser.rc2
|
||||
이 파일에는 Microsoft Visual C++ 이외의 다른 도구에서 편집한 리소스가
|
||||
들어 있습니다. 리소스 편집기로 편집할 수 없는 모든 리소스는
|
||||
이 파일에 넣어야 합니다.
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
응용 프로그램 마법사에서 하나의 대화 상자 클래스가 만들어집니다.
|
||||
|
||||
ChatParserDlg.h, ChatParserDlg.cpp ? 대화 상자
|
||||
이 파일에는 CChatParserDlg 클래스가 들어 있습니다. 이 클래스는
|
||||
응용 프로그램의 주 대화 상자 동작을 정의합니다. 대화 상자의 템플릿은
|
||||
Microsoft Visual C++에서 편집할 수 있는 ChatParser.rc에 있습니다.
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
기타 표준 파일:
|
||||
|
||||
StdAfx.h, StdAfx.cpp
|
||||
이 파일은 미리 컴파일된 헤더 파일(PCH)인 ChatParser.pch와
|
||||
미리 컴파일된 형식 파일인 StdAfx.obj를 빌드하는 데 사용됩니다.
|
||||
|
||||
Resource.h
|
||||
새 리소스 ID를 정의하는 표준 헤더 파일입니다.
|
||||
Microsoft Visual C++에서 이 파일을 읽고 업데이트합니다.
|
||||
|
||||
ChatParser.manifest
|
||||
응용 프로그램 매니페스트 파일은 Windows XP에서 특정 버전의 Side-by-Side
|
||||
어셈블리에 대한 응용 프로그램 종속성을 설명하는 데 사용됩니다. 로더는 이 정보를
|
||||
사용하여 어셈블리 캐시에서 적절한 어셈블리를 로드하거나 응용 프로그램에서 전용
|
||||
어셈블리를 로드합니다. 응용 프로그램 매니페스트는 응용 프로그램 실행 파일과 같은
|
||||
폴더에 설치된 외부 .manifest 파일로 재배포를 위해 포함되거나 리소스의 형태로
|
||||
실행 파일에 포함될 수 있습니다.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
기타 참고:
|
||||
|
||||
응용 프로그램 마법사는 "TODO:"를 사용하여 추가하거나 사용자 지정해야 하는
|
||||
소스 코드 부분을 나타냅니다.
|
||||
|
||||
응용 프로그램이 공유 DLL에서 MFC를 사용하는 경우 해당 MFC DLL을
|
||||
재배포해야 합니다. 그리고 응용 프로그램이 운영 체제의 로캘과
|
||||
다른 언어를 사용하는 경우 해당 지역화된 리소스인 MFC80XXX.DLL을
|
||||
재배포해야 합니다. 이 두가지 항목에 대한 자세한 내용은
|
||||
MSDN 설명서의 Visual C++ 응용 프로그램 재배포 항목을
|
||||
참조하십시오.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
187
Server/ManageTool/ChatParser/RegFunctions.cpp
Normal file
187
Server/ManageTool/ChatParser/RegFunctions.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include "RegFunctions.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
bool Registry::WriteString(const char *FileName_In, const char *Section_In,
|
||||
const char *KeyName_In, const char *Value_In)
|
||||
{
|
||||
return 0 != WritePrivateProfileString(Section_In, KeyName_In, Value_In, FileName_In);
|
||||
}
|
||||
|
||||
unsigned long Registry::ReadInt(const char *FileName_In, const char *Section_In, const char *KeyName_In)
|
||||
{
|
||||
return static_cast<unsigned long>(GetPrivateProfileInt(Section_In, KeyName_In, 0, FileName_In));
|
||||
}
|
||||
|
||||
bool Registry::ReadString(const char *FileName_In, const char *Section_In,
|
||||
const char *KeyName_In, char *Buffer_Out, int nBufferSize)
|
||||
{
|
||||
return 0 != GetPrivateProfileString(Section_In, KeyName_In,
|
||||
NULL, Buffer_Out, nBufferSize, FileName_In);
|
||||
}
|
||||
|
||||
bool Registry::WriteStruct(const char *FileName_In, const char *Section_In,
|
||||
const char *KeyName_In, void *Value_In, const int Size_in)
|
||||
{
|
||||
return 0 != WritePrivateProfileStruct(Section_In, KeyName_In, Value_In, Size_in, FileName_In);
|
||||
}
|
||||
|
||||
bool Registry::ReadStruct(const char *FileName_In, const char *Section_In,
|
||||
const char *KeyName_In, void *Value_Out, const int Size_in)
|
||||
{
|
||||
return 0 != GetPrivateProfileStruct(Section_In, KeyName_In, Value_Out, Size_in, FileName_In);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Registry::CSetupFile::CSetupFile()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
Registry::CSetupFile::CSetupFile(const char* szFileName)
|
||||
{
|
||||
Open(szFileName);
|
||||
}
|
||||
|
||||
Registry::CSetupFile::~CSetupFile()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
inline unsigned long sdbmHash(const unsigned char *str)
|
||||
{
|
||||
unsigned long hash = 0;
|
||||
int c;
|
||||
|
||||
while (c = *str++) { hash = c + (hash << 6) + (hash << 16) - hash; }
|
||||
return hash;
|
||||
}
|
||||
|
||||
bool Registry::CSetupFile::Open(const char* szFileName)
|
||||
{
|
||||
std::string fileLine;
|
||||
std::string szSection;
|
||||
std::string szKey;
|
||||
std::string szValue;
|
||||
|
||||
fileLine.reserve(4096);
|
||||
szSection.reserve(1024);
|
||||
szKey.reserve(1024);
|
||||
szValue.reserve(4096);
|
||||
|
||||
std::fstream file(szFileName, std::ios_base::in);
|
||||
|
||||
std::string::size_type nPosition = std::string::npos;
|
||||
std::string::size_type nEndPosition = std::string::npos;
|
||||
std::string::size_type nDataPosition = std::string::npos;
|
||||
std::string::size_type nDataEndPosition = std::string::npos;
|
||||
|
||||
unsigned long dwSectionValue = 0;
|
||||
|
||||
if(file.is_open())
|
||||
{
|
||||
while(std::getline(file, fileLine))
|
||||
{
|
||||
nPosition = fileLine.find_first_not_of(" \r\n\t");
|
||||
|
||||
if(std::string::npos != nPosition)
|
||||
{
|
||||
if('[' == fileLine[nPosition])
|
||||
{
|
||||
// 섹션명임
|
||||
nEndPosition = fileLine.find_first_of(']', nPosition);
|
||||
if(std::string::npos != nEndPosition)
|
||||
{
|
||||
szSection.assign(fileLine.begin() + nPosition + 1,
|
||||
fileLine.begin() + nEndPosition);
|
||||
|
||||
dwSectionValue = sdbmHash(reinterpret_cast<const unsigned char*>(szSection.c_str()));
|
||||
}
|
||||
}
|
||||
else if(0 != fileLine.compare(nPosition, sizeof(char) * 2, "//"))
|
||||
{
|
||||
// 주석 아님
|
||||
nEndPosition = fileLine.find_first_of('=', nPosition);
|
||||
|
||||
if(std::string::npos != nEndPosition)
|
||||
{
|
||||
// nEndPosition 좌우로 Key - Value Pair임.
|
||||
nDataEndPosition = fileLine.find_last_not_of("= \t", nEndPosition);
|
||||
|
||||
if(std::string::npos != nDataEndPosition)
|
||||
{
|
||||
// 키 읽어옴.
|
||||
szKey.assign(fileLine.begin() + nPosition,
|
||||
fileLine.begin() + nDataEndPosition + 1);
|
||||
|
||||
nDataPosition = fileLine.find_first_not_of("= \t", nEndPosition);
|
||||
|
||||
if(std::string::npos != nDataPosition)
|
||||
{
|
||||
nDataEndPosition = fileLine.find_last_not_of(" \r\n\t");
|
||||
|
||||
if(std::string::npos != nDataEndPosition)
|
||||
{
|
||||
// 값 읽어옴
|
||||
m_SetupMap.insert(SetupMap::value_type(
|
||||
sdbmHash(reinterpret_cast<const unsigned char*>(szKey.c_str())) + dwSectionValue,
|
||||
Data(szSection, szKey,
|
||||
std::string(fileLine.begin() + nDataPosition, fileLine.begin() + nDataEndPosition + 1))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Registry::CSetupFile::Clear()
|
||||
{
|
||||
m_SetupMap.clear();
|
||||
}
|
||||
|
||||
const char* Registry::CSetupFile::GetString(const char* szSection, const char* szKey,
|
||||
const char* szDefaultValue)
|
||||
{
|
||||
DWORD dwHashValue = sdbmHash(reinterpret_cast<const unsigned char*>(szSection))
|
||||
+ sdbmHash(reinterpret_cast<const unsigned char*>(szKey));
|
||||
|
||||
std::pair<SetupMap::iterator, SetupMap::iterator> pos_pair = m_SetupMap.equal_range(dwHashValue);
|
||||
|
||||
for(; pos_pair.first != pos_pair.second; ++pos_pair.first)
|
||||
{
|
||||
Data& data = pos_pair.first->second;
|
||||
|
||||
if(0 == data.m_szSection.compare(szSection) &&
|
||||
0 == data.m_szKey.compare(szKey))
|
||||
{
|
||||
return data.m_szValue.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
return szDefaultValue;
|
||||
}
|
||||
|
||||
unsigned int Registry::CSetupFile::GetInt(const char* szSection, const char* szKey,
|
||||
unsigned int nDefaultValue)
|
||||
{
|
||||
const char* szStr = GetString(szSection, szKey);
|
||||
|
||||
if(0 != szStr)
|
||||
{
|
||||
return atoi(szStr);
|
||||
}
|
||||
|
||||
return nDefaultValue;
|
||||
}
|
||||
|
||||
59
Server/ManageTool/ChatParser/RegFunctions.h
Normal file
59
Server/ManageTool/ChatParser/RegFunctions.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef _REGISTRY_FUNCTIONS_H_
|
||||
#define _REGISTRY_FUNCTIONS_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace Registry
|
||||
{
|
||||
bool WriteString(const char *FileName_In, const char *Section_In,
|
||||
const char *KeyName_In, const char *Value_In);
|
||||
|
||||
unsigned long ReadInt(const char *FileName_In,
|
||||
const char *Section_In, const char *KeyName_In);
|
||||
|
||||
bool ReadString(const char *FileName_In, const char *Section_In,
|
||||
const char *KeyName_In, char *Buffer_Out, int nBufferSize);
|
||||
|
||||
bool WriteStruct(const char *FileName_In, const char *Section_In,
|
||||
const char *KeyName_In, void *Value_In, const int Size_in);
|
||||
|
||||
bool ReadStruct(const char *FileName_In, const char *Section_In,
|
||||
const char *KeyName_In, void *Value_Out, const int Size_in);
|
||||
|
||||
class CSetupFile
|
||||
{
|
||||
public:
|
||||
|
||||
CSetupFile();
|
||||
CSetupFile(const char* szFileName);
|
||||
~CSetupFile();
|
||||
|
||||
bool Open(const char* szFileName);
|
||||
void Clear();
|
||||
|
||||
const char* GetString(const char* szSection, const char* szKey, const char* szDefaultValue = 0);
|
||||
unsigned int GetInt(const char* szSection, const char* szKey, unsigned int nDefaultValue = 0);
|
||||
|
||||
private:
|
||||
|
||||
struct Data
|
||||
{
|
||||
std::string m_szSection;
|
||||
std::string m_szKey;
|
||||
std::string m_szValue;
|
||||
|
||||
Data(const std::string& szSection, const std::string& szKey, const std::string& szValue)
|
||||
: m_szSection(szSection), m_szKey(szKey), m_szValue(szValue)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::multimap<unsigned long, Data> SetupMap;
|
||||
|
||||
SetupMap m_SetupMap;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
702
Server/ManageTool/ChatParser/XListBox.cpp
Normal file
702
Server/ManageTool/ChatParser/XListBox.cpp
Normal file
@@ -0,0 +1,702 @@
|
||||
// XListBox.cpp
|
||||
//
|
||||
// Author: Hans Dietrich
|
||||
// hdietrich2@hotmail.com
|
||||
//
|
||||
// This software is released into the public domain.
|
||||
// You are free to use it in any way you like.
|
||||
//
|
||||
// This software is provided "as is" with no expressed
|
||||
// or implied warranty. I accept no liability for any
|
||||
// damage or loss of business that this software may cause.
|
||||
//
|
||||
// Notes on use: To use in an MFC project, first create
|
||||
// a listbox using the standard dialog editor.
|
||||
// Be sure to mark the listbox as OWNERDRAW
|
||||
// FIXED, and check the HAS STRINGS box.
|
||||
// Using Class Wizard, create a variable for
|
||||
// the listbox. Finally, manually edit the
|
||||
// dialog's .h file and replace CListBox with
|
||||
// CXListBox, and #include XListBox.h.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XListBox.h"
|
||||
#include "Clipboard.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char BASED_CODE THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
// NOTE - following table must be kept in sync with ColorPickerCB.cpp
|
||||
|
||||
static COLORREF ColorTable[16] = { RGB( 0, 0, 0), // Black
|
||||
RGB(255, 255, 255), // White
|
||||
RGB(255, 255, 255), // ChatNormal
|
||||
RGB(141, 180, 244), // ChatParty
|
||||
RGB(255, 255, 255), // ChatFriend
|
||||
RGB(255, 229, 57), // ChatGuild
|
||||
RGB(255, 255, 255), // ChatStall
|
||||
RGB( 53, 218, 193), // ChatShout
|
||||
RGB(220, 220, 220), // ChatAdminNormal
|
||||
RGB(255, 128, 64), // ChatAdminShout
|
||||
RGB(255, 128, 239), // ChatWhisper
|
||||
RGB(255, 0, 255), // ChatNotice
|
||||
RGB(204, 128, 255), // ChatTrade
|
||||
RGB( 38, 255, 38), // Call : 운영자를 부르는 유저의 목소리-_ -a
|
||||
RGB(255, 0, 255), // GMReport
|
||||
RGB( 0, 0, 0) }; // BackColor
|
||||
|
||||
BEGIN_MESSAGE_MAP(CXListBox, CListBox)
|
||||
//{{AFX_MSG_MAP(CXListBox)
|
||||
ON_WM_LBUTTONDBLCLK()
|
||||
ON_WM_CONTEXTMENU()
|
||||
ON_COMMAND(ID_EDIT_SELECT_ALL, OnEditSelectAll)
|
||||
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
|
||||
ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
|
||||
ON_WM_ERASEBKGND()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
#define new DEBUG_NEW
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CXListBox
|
||||
|
||||
CXListBox::CXListBox()
|
||||
{
|
||||
m_ColorWindow = ::GetSysColor(COLOR_WINDOW);
|
||||
m_ColorHighlight = ::GetSysColor(COLOR_HIGHLIGHT);
|
||||
m_ColorWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
|
||||
m_ColorHighlightText = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
|
||||
m_bColor = TRUE;
|
||||
m_cxExtent = 0;
|
||||
m_nTabPosition = 8; // tab stops every 8 columns
|
||||
m_nSpaceWidth = 7;
|
||||
m_nContextMenuId = (UINT)-1;
|
||||
for (int i = 0; i < MAXTABSTOPS; i++)
|
||||
m_nTabStopPositions[i] = (i+1) * m_nTabPosition * m_nSpaceWidth;
|
||||
}
|
||||
|
||||
CXListBox::~CXListBox()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// MeasureItem
|
||||
void CXListBox::MeasureItem(LPMEASUREITEMSTRUCT)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CompareItem
|
||||
int CXListBox::CompareItem(LPCOMPAREITEMSTRUCT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// DrawItem
|
||||
void CXListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
|
||||
{
|
||||
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
|
||||
|
||||
COLORREF oldtextcolor, oldbackgroundcolor;
|
||||
|
||||
pDC->GetCharWidth((UINT) ' ', (UINT) ' ', &m_nSpaceWidth);
|
||||
pDC->GetCharWidth((UINT) 'c', (UINT) 'c', &m_nAveCharWidth);
|
||||
|
||||
for (int i = 0; i < MAXTABSTOPS; i++)
|
||||
m_nTabStopPositions[i] = (i+1) * m_nAveCharWidth * m_nTabPosition;
|
||||
|
||||
// draw focus rectangle when no items in listbox
|
||||
if (lpDIS->itemID == (UINT)-1)
|
||||
{
|
||||
if (lpDIS->itemAction & ODA_FOCUS)
|
||||
pDC->DrawFocusRect(&lpDIS->rcItem);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
int selChange = lpDIS->itemAction & ODA_SELECT;
|
||||
int focusChange = lpDIS->itemAction & ODA_FOCUS;
|
||||
int drawEntire = lpDIS->itemAction & ODA_DRAWENTIRE;
|
||||
|
||||
if (selChange || drawEntire)
|
||||
{
|
||||
BOOL sel = lpDIS->itemState & ODS_SELECTED;
|
||||
|
||||
int nLen = CListBox::GetTextLen(lpDIS->itemID);
|
||||
if (nLen != LB_ERR)
|
||||
{
|
||||
char *buf = new char [nLen + 10];
|
||||
ASSERT(buf);
|
||||
if (buf && (GetTextWithColor(lpDIS->itemID, (LPSTR)buf) != LB_ERR))
|
||||
{
|
||||
// set text color from first character in string -
|
||||
// NOTE: 1 was added to color index to avoid asserts by CString
|
||||
int itext = int (buf[0] - 1);
|
||||
|
||||
// set background color from second character in string -
|
||||
// NOTE: 1 was added to color index to avoid asserts by CString
|
||||
int iback = int (buf[1] - 1);
|
||||
buf[0] = ' ';
|
||||
buf[1] = ' ';
|
||||
COLORREF textcolor = sel ? m_ColorHighlightText : ColorTable[itext];
|
||||
oldtextcolor = pDC->SetTextColor(textcolor);
|
||||
COLORREF backgroundcolor = sel ? m_ColorHighlight : ColorTable[iback];
|
||||
oldbackgroundcolor = pDC->SetBkColor(backgroundcolor);
|
||||
|
||||
// fill the rectangle with the background color the fast way
|
||||
pDC->ExtTextOut(0, 0, ETO_OPAQUE, &lpDIS->rcItem, NULL, 0, NULL);
|
||||
|
||||
pDC->TabbedTextOut(lpDIS->rcItem.left, lpDIS->rcItem.top, &buf[2],
|
||||
(int)strlen(&buf[2]), MAXTABSTOPS, (LPINT)m_nTabStopPositions, 0);
|
||||
|
||||
CSize size;
|
||||
size = pDC->GetOutputTextExtent(&buf[2]);
|
||||
int nScrollBarWidth = ::GetSystemMetrics(SM_CXVSCROLL);
|
||||
size.cx += nScrollBarWidth; // in case of vertical scrollbar
|
||||
|
||||
int cxExtent = (size.cx > m_cxExtent) ? size.cx : m_cxExtent;
|
||||
|
||||
if (cxExtent > m_cxExtent)
|
||||
{
|
||||
m_cxExtent = cxExtent;
|
||||
SetHorizontalExtent(m_cxExtent+(m_cxExtent/32));
|
||||
}
|
||||
}
|
||||
if (buf)
|
||||
delete [] buf;
|
||||
}
|
||||
}
|
||||
|
||||
if (focusChange || (drawEntire && (lpDIS->itemState & ODS_FOCUS)))
|
||||
{
|
||||
pDC->DrawFocusRect(&lpDIS->rcItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// GetTextWithColor - get text string with color bytes
|
||||
int CXListBox::GetTextWithColor(int nIndex, LPTSTR lpszBuffer) const
|
||||
{
|
||||
if (!::IsWindow(m_hWnd))
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return LB_ERR;
|
||||
}
|
||||
|
||||
ASSERT(lpszBuffer);
|
||||
lpszBuffer[0] = 0;
|
||||
return CListBox::GetText(nIndex, lpszBuffer);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// GetTextWithColor - get text string with color bytes
|
||||
void CXListBox::GetTextWithColor(int nIndex, CString& rString) const
|
||||
{
|
||||
if (!::IsWindow(m_hWnd))
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
rString.Empty();
|
||||
CListBox::GetText(nIndex, rString);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// GetText - for compatibility with CListBox (no color bytes)
|
||||
int CXListBox::GetText(int nIndex, LPTSTR lpszBuffer) const
|
||||
{
|
||||
if (!::IsWindow(m_hWnd))
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return LB_ERR;
|
||||
}
|
||||
|
||||
ASSERT(lpszBuffer);
|
||||
|
||||
lpszBuffer[0] = 0;
|
||||
|
||||
int nRet = CListBox::GetText(nIndex, lpszBuffer);
|
||||
|
||||
int n = (int)strlen(lpszBuffer);
|
||||
if (n > 2)
|
||||
memcpy(&lpszBuffer[0], &lpszBuffer[2], n-1); // copy nul too
|
||||
|
||||
return nRet;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// GetText - for compatibility with CListBox (no color bytes)
|
||||
void CXListBox::GetText(int nIndex, CString& rString) const
|
||||
{
|
||||
if (!::IsWindow(m_hWnd))
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
CString str;
|
||||
str.Empty();
|
||||
CListBox::GetText(nIndex, str);
|
||||
if ((!str.IsEmpty()) && (str.GetLength() > 2))
|
||||
rString = str.Mid(2);
|
||||
else
|
||||
rString.Empty();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// GetTextLen - for compatibility with CListBox (no color bytes)
|
||||
int CXListBox::GetTextLen(int nIndex) const
|
||||
{
|
||||
if (!::IsWindow(m_hWnd))
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return LB_ERR;
|
||||
}
|
||||
|
||||
int n = CListBox::GetTextLen(nIndex);
|
||||
if (n != LB_ERR && n >= 2)
|
||||
n -= 2;
|
||||
return n;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// SearchString
|
||||
int CXListBox::SearchString(int nStartAfter, LPCTSTR lpszItem, BOOL bExact) const
|
||||
{
|
||||
if (!::IsWindow(m_hWnd))
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return LB_ERR;
|
||||
}
|
||||
|
||||
// start the search after specified index
|
||||
int nIndex = nStartAfter + 1;
|
||||
|
||||
int nCount = GetCount();
|
||||
if (nCount == LB_ERR)
|
||||
return LB_ERR;
|
||||
|
||||
// convert string to search for to lower case
|
||||
CString strItem;
|
||||
strItem = lpszItem;
|
||||
strItem.MakeLower();
|
||||
int nItemSize = strItem.GetLength();
|
||||
|
||||
CString strText;
|
||||
|
||||
// search until end
|
||||
for ( ; nIndex < nCount; nIndex++)
|
||||
{
|
||||
GetText(nIndex, strText);
|
||||
strText.MakeLower();
|
||||
if (!bExact)
|
||||
strText = strText.Left(nItemSize);
|
||||
if (strText == strItem)
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
// if we started at beginning there is no more to do, search failed
|
||||
if (nStartAfter == -1)
|
||||
return LB_ERR;
|
||||
|
||||
// search until we reach beginning index
|
||||
for (nIndex = 0; (nIndex <= nStartAfter) && (nIndex < nCount); nIndex++)
|
||||
{
|
||||
GetText(nIndex, strText);
|
||||
strText.MakeLower();
|
||||
if (!bExact)
|
||||
strText = strText.Left(nItemSize);
|
||||
if (strText == strItem)
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
return LB_ERR;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// FindString
|
||||
int CXListBox::FindString(int nStartAfter, LPCTSTR lpszItem) const
|
||||
{
|
||||
return SearchString(nStartAfter, lpszItem, FALSE);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// SelectString
|
||||
int CXListBox::SelectString(int nStartAfter, LPCTSTR lpszItem)
|
||||
{
|
||||
int rc = SearchString(nStartAfter, lpszItem, FALSE);
|
||||
if (rc != LB_ERR)
|
||||
SetCurSel(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// FindStringExact
|
||||
int CXListBox::FindStringExact(int nStartAfter, LPCTSTR lpszItem) const
|
||||
{
|
||||
return SearchString(nStartAfter, lpszItem, TRUE);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// InsertString - override to add text color
|
||||
int CXListBox::InsertString(int nIndex, LPCTSTR lpszItem)
|
||||
{
|
||||
if (!::IsWindow(m_hWnd))
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return LB_ERR;
|
||||
}
|
||||
|
||||
CString s;
|
||||
s.Empty();
|
||||
s = lpszItem;
|
||||
|
||||
Color tc = Black; // to force black-only text
|
||||
Color bc = White;
|
||||
|
||||
UINT nColor = (UINT) tc;
|
||||
ASSERT(nColor < 16);
|
||||
if (nColor >= 16)
|
||||
tc = Black;
|
||||
|
||||
// don't display \r or \n characters
|
||||
int i;
|
||||
while ((i = s.FindOneOf("\r\n")) != -1)
|
||||
s.SetAt(i, ' ');
|
||||
|
||||
// first character in string is color -- add 1 to color
|
||||
// to avoid asserts by CString class
|
||||
CString t;
|
||||
t .Empty();
|
||||
t += (char) (tc + 1);
|
||||
t += (char) (bc + 1);
|
||||
t += s;
|
||||
|
||||
// try to insert the string into the listbox
|
||||
i = CListBox::InsertString(nIndex, t);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// AddString - override to add text color
|
||||
void CXListBox::AddString(LPCTSTR lpszItem)
|
||||
{
|
||||
AddLine(CXListBox::Black, CXListBox::White, lpszItem, true);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// AddLine
|
||||
void CXListBox::AddLine(Color tc, Color bc, LPCTSTR lpszLine, BOOL bAutoScroll)
|
||||
{
|
||||
if (!::IsWindow(m_hWnd))
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
CString s;
|
||||
s.Empty();
|
||||
s = lpszLine;
|
||||
|
||||
if (!m_bColor)
|
||||
{
|
||||
tc = Black; // to force black-only text
|
||||
bc = White;
|
||||
}
|
||||
|
||||
UINT nColor = (UINT) tc;
|
||||
ASSERT(nColor < 16);
|
||||
if (nColor >= 16)
|
||||
tc = Black;
|
||||
|
||||
// don't display \r or \n characters
|
||||
int i;
|
||||
while ((i = s.FindOneOf("\r\n")) != -1)
|
||||
s.SetAt(i, ' ');
|
||||
|
||||
// first character in string is color -- add 1 to color
|
||||
// to avoid asserts by CString class
|
||||
CString t;
|
||||
t.Empty();
|
||||
t += (char) (tc + 1);
|
||||
t += (char) (bc + 1);
|
||||
t += s;
|
||||
|
||||
// try to add the string to the listbox
|
||||
i = CListBox::AddString(t);
|
||||
if (i == LB_ERRSPACE)
|
||||
{
|
||||
// will get LB_ERRSPACE if listbox is out of memory
|
||||
int n = GetCount();
|
||||
|
||||
if (n == LB_ERR)
|
||||
return;
|
||||
|
||||
if (n < 2)
|
||||
return;
|
||||
|
||||
// try to delete some strings to free up some room --
|
||||
// don't spend too much time deleting strings, since
|
||||
// we might be getting a burst of messages
|
||||
n = (n < 20) ? (n - 1) : 20;
|
||||
if (n <= 0)
|
||||
n = 1;
|
||||
|
||||
SetRedraw(FALSE);
|
||||
for (i = 0; i < n; i++)
|
||||
DeleteString(0);
|
||||
|
||||
i = CListBox::AddString(t);
|
||||
|
||||
SetRedraw(TRUE);
|
||||
}
|
||||
|
||||
if(bAutoScroll && (i >= 0))
|
||||
{
|
||||
SetTopIndex(i);
|
||||
}
|
||||
|
||||
SetCurSel(-1);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Printf
|
||||
void _cdecl CXListBox::Printf(Color tc, Color bc, UINT nID, LPCTSTR lpszFmt, ...)
|
||||
{
|
||||
char buf[1024], fmt[1024];
|
||||
va_list marker;
|
||||
|
||||
// load format string from string resource if
|
||||
// a resource ID was specified
|
||||
if (nID)
|
||||
{
|
||||
CString s;
|
||||
if (!s.LoadString(nID))
|
||||
{
|
||||
sprintf(s.GetBufferSetLength(80), "Failed to load string resource %u",
|
||||
nID);
|
||||
s.ReleaseBuffer(-1);
|
||||
}
|
||||
strncpy(fmt, s, sizeof(fmt)-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// format string was passed as parameter
|
||||
strncpy(fmt, lpszFmt, sizeof(fmt)-1);
|
||||
}
|
||||
fmt[sizeof(fmt)-1] = 0;
|
||||
|
||||
// combine output string and variables
|
||||
va_start(marker, lpszFmt);
|
||||
_vsnprintf(buf, sizeof(buf)-1, fmt, marker);
|
||||
va_end(marker);
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
|
||||
AddLine(tc, bc, buf, true);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// EnableColor
|
||||
void CXListBox::EnableColor (BOOL bEnable)
|
||||
{
|
||||
m_bColor = bEnable;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// SetTabPosition
|
||||
void CXListBox::SetTabPosition(int nSpacesPerTab)
|
||||
{
|
||||
ASSERT(nSpacesPerTab > 0 && nSpacesPerTab < 11);
|
||||
|
||||
m_nTabPosition = nSpacesPerTab;
|
||||
|
||||
CDC* pDC = GetDC();
|
||||
|
||||
if (pDC)
|
||||
{
|
||||
TEXTMETRIC tm;
|
||||
pDC->GetTextMetrics(&tm);
|
||||
|
||||
pDC->GetCharWidth((UINT) ' ', (UINT) ' ', &m_nSpaceWidth);
|
||||
pDC->GetCharWidth((UINT) '9', (UINT) '9', &m_nAveCharWidth);
|
||||
|
||||
for (int i = 0; i < MAXTABSTOPS; i++)
|
||||
m_nTabStopPositions[i] = (i+1) * m_nAveCharWidth * m_nTabPosition;
|
||||
|
||||
ReleaseDC(pDC);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// GetVisibleLines
|
||||
int CXListBox::GetVisibleLines()
|
||||
{
|
||||
int nCount = 0;
|
||||
|
||||
CDC* pDC = GetDC();
|
||||
|
||||
if (pDC)
|
||||
{
|
||||
TEXTMETRIC tm;
|
||||
pDC->GetTextMetrics(&tm);
|
||||
int h = tm.tmHeight + tm.tmInternalLeading;
|
||||
ReleaseDC(pDC);
|
||||
|
||||
CRect rect;
|
||||
GetClientRect(&rect);
|
||||
nCount = rect.Height() / h;
|
||||
}
|
||||
return nCount;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// ResetContent
|
||||
void CXListBox::ResetContent()
|
||||
{
|
||||
if (!::IsWindow(m_hWnd))
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
CListBox::ResetContent();
|
||||
|
||||
m_cxExtent = 0;
|
||||
|
||||
SetHorizontalExtent(m_cxExtent);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// SetFont
|
||||
void CXListBox::SetFont(CFont *pFont, BOOL bRedraw)
|
||||
{
|
||||
if (!::IsWindow(m_hWnd))
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
CListBox::SetFont(pFont, bRedraw);
|
||||
|
||||
CDC* pDC = GetDC();
|
||||
|
||||
if (pDC)
|
||||
{
|
||||
CFont *pOldFont = pDC->SelectObject(pFont);
|
||||
|
||||
TEXTMETRIC tm;
|
||||
pDC->GetTextMetrics(&tm);
|
||||
int h = tm.tmHeight;
|
||||
SetItemHeight(0, h);
|
||||
|
||||
pDC->SelectObject(pOldFont);
|
||||
|
||||
pDC->GetCharWidth((UINT) ' ', (UINT) ' ', &m_nSpaceWidth);
|
||||
pDC->GetCharWidth((UINT) '9', (UINT) '9', &m_nAveCharWidth);
|
||||
|
||||
for (int i = 0; i < MAXTABSTOPS; i++)
|
||||
m_nTabStopPositions[i] = (i+1) * m_nAveCharWidth * m_nTabPosition;
|
||||
|
||||
ReleaseDC(pDC);
|
||||
}
|
||||
|
||||
m_cxExtent = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// OnLButtonDblClk
|
||||
void CXListBox::OnLButtonDblClk(UINT nFlags, CPoint point)
|
||||
{
|
||||
CListBox::OnLButtonDblClk(nFlags, point);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// OnContextMenu
|
||||
void CXListBox::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
|
||||
{
|
||||
if (m_nContextMenuId == -1)
|
||||
{
|
||||
TRACE(" no context menu\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CMenu menu;
|
||||
if (!menu.LoadMenu(m_nContextMenuId))
|
||||
{
|
||||
TRACE(" ERROR failed to load %d\n", m_nContextMenuId);
|
||||
return;
|
||||
}
|
||||
|
||||
menu.GetSubMenu(0)->TrackPopupMenu(0,
|
||||
point.x, point.y, this, NULL);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// OnEditCopy
|
||||
void CXListBox::OnEditCopy()
|
||||
{
|
||||
CString str;
|
||||
str.Empty();
|
||||
|
||||
int nCount = GetCount();
|
||||
int nSel = 0;
|
||||
|
||||
for (int i = 0; i < nCount; i++)
|
||||
{
|
||||
if (GetSel(i) > 0)
|
||||
{
|
||||
CString s;
|
||||
s.Empty();
|
||||
GetText(i, s);
|
||||
if (!s.IsEmpty())
|
||||
{
|
||||
nSel++;
|
||||
s.TrimLeft("\r\n");
|
||||
s.TrimRight("\r\n");
|
||||
if (s.Find('\n') == -1)
|
||||
s += "\n";
|
||||
s.Replace("\t", " ");
|
||||
str += s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!str.IsEmpty())
|
||||
CClipboard::SetText(str);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// OnEditClear
|
||||
void CXListBox::OnEditClear()
|
||||
{
|
||||
ResetContent();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// OnEditSelectAll
|
||||
void CXListBox::OnEditSelectAll()
|
||||
{
|
||||
if (!::IsWindow(m_hWnd))
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
SelItemRange(TRUE, 0, GetCount()-1);
|
||||
}
|
||||
|
||||
// Add by zun!
|
||||
BOOL CXListBox::OnEraseBkgnd(CDC* pDC)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
93
Server/ManageTool/ChatParser/XListBox.h
Normal file
93
Server/ManageTool/ChatParser/XListBox.h
Normal file
@@ -0,0 +1,93 @@
|
||||
// XListBox.h
|
||||
//
|
||||
// Author: Hans Dietrich
|
||||
// hdietrich2@hotmail.com
|
||||
//
|
||||
// This software is released into the public domain.
|
||||
// You are free to use it in any way you like.
|
||||
//
|
||||
// This software is provided "as is" with no expressed
|
||||
// or implied warranty. I accept no liability for any
|
||||
// damage or loss of business that this software may cause.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef XLISTBOX_H
|
||||
#define XLISTBOX_H
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CXListBox class
|
||||
|
||||
class CXListBox : public CListBox
|
||||
{
|
||||
// Constructors
|
||||
public:
|
||||
CXListBox();
|
||||
~CXListBox();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
int m_cxExtent;
|
||||
int m_nTabPosition;
|
||||
BOOL m_bColor;
|
||||
COLORREF m_ColorWindow;
|
||||
COLORREF m_ColorHighlight;
|
||||
COLORREF m_ColorWindowText;
|
||||
COLORREF m_ColorHighlightText;
|
||||
|
||||
// NOTE - following list must be kept in sync with ColorPickerCB.cpp
|
||||
enum Color{ Black, White,
|
||||
ChatNormal, ChatParty, ChatFriend, ChatGuild, ChatStall, ChatShout,
|
||||
ChatAdminNormal, ChatAdminShout, ChatWhisper, ChatNotice, ChatTrade, Call, GMReport, BackColor
|
||||
};
|
||||
|
||||
void EnableColor(BOOL bEnable);
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void AddLine(Color tc, Color bc, LPCTSTR lpszLine, BOOL bAutoScroll = TRUE);
|
||||
void AddString(LPCTSTR lpszItem);
|
||||
int FindString(int nStartAfter, LPCTSTR lpszItem) const;
|
||||
int FindStringExact(int nStartAfter, LPCTSTR lpszItem) const;
|
||||
int GetText(int nIndex, LPTSTR lpszBuffer) const;
|
||||
void GetText(int nIndex, CString& rString) const;
|
||||
int GetTextLen(int nIndex) const;
|
||||
int GetTextWithColor(int nIndex, LPTSTR lpszBuffer) const;
|
||||
void GetTextWithColor(int nIndex, CString& rString) const;
|
||||
int GetVisibleLines();
|
||||
int InsertString(int nIndex, LPCTSTR lpszItem);
|
||||
void _cdecl Printf(Color tc, Color bc, UINT nID, LPCTSTR lpszFmt, ...);
|
||||
virtual void ResetContent();
|
||||
int SelectString(int nStartAfter, LPCTSTR lpszItem);
|
||||
void SetContextMenuId(UINT nId) { m_nContextMenuId = nId; }
|
||||
virtual void SetFont(CFont *pFont, BOOL bRedraw = TRUE);
|
||||
void SetTabPosition(int nSpacesPerTab);
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
int SearchString(int nStartAfter, LPCTSTR lpszItem, BOOL bExact) const;
|
||||
|
||||
#define MAXTABSTOPS 100
|
||||
int m_nTabStopPositions[MAXTABSTOPS];
|
||||
int m_nSpaceWidth;
|
||||
int m_nAveCharWidth;
|
||||
UINT m_nContextMenuId;
|
||||
|
||||
virtual int CompareItem (LPCOMPAREITEMSTRUCT lpCIS);
|
||||
virtual void DrawItem (LPDRAWITEMSTRUCT lpDIS);
|
||||
virtual void MeasureItem (LPMEASUREITEMSTRUCT lpMIS);
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CXListBox)
|
||||
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
|
||||
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
|
||||
afx_msg void OnEditCopy();
|
||||
afx_msg void OnEditClear();
|
||||
afx_msg void OnEditSelectAll();
|
||||
afx_msg BOOL OnEraseBkgnd(CDC* pDC); // Add by zun!
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
#endif
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BIN
Server/ManageTool/ChatParser/res/ChatParser.ico
Normal file
BIN
Server/ManageTool/ChatParser/res/ChatParser.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
13
Server/ManageTool/ChatParser/res/ChatParser.rc2
Normal file
13
Server/ManageTool/ChatParser/res/ChatParser.rc2
Normal file
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// ChatParser.RC2 - Microsoft Visual C++에서 직접 편집하지 않는 리소스
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#error 이 파일은 Microsoft Visual C++에서 편집할 수 없습니다.
|
||||
#endif //APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 여기에 수동으로 편집한 리소스를 추가합니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
31
Server/ManageTool/ChatParser/resource.h
Normal file
31
Server/ManageTool/ChatParser/resource.h
Normal file
@@ -0,0 +1,31 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by ChatParser.rc
|
||||
//
|
||||
#define IDM_ABOUTBOX 0x0010
|
||||
#define IDD_ABOUTBOX 100
|
||||
#define IDS_ABOUTBOX 101
|
||||
#define IDD_CHATPARSER_DIALOG 102
|
||||
#define IDR_MAINFRAME 128
|
||||
#define IDC_OPEN_FILENAME 1000
|
||||
#define IDC_OPENFILE 1001
|
||||
#define IDC_FINDLIST 1002
|
||||
#define IDC_CHATLIST 1003
|
||||
#define IDC_OLDVERSION 1004
|
||||
#define IDC_SERVERID 1005
|
||||
#define IDC_ZONEID 1006
|
||||
#define IDC_ZONEID2 1007
|
||||
#define IDC_CHATTYPE 1007
|
||||
#define IDC_FINDNAME 1008
|
||||
#define IDC_FINDNAMECHK 1009
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 129
|
||||
#define _APS_NEXT_COMMAND_VALUE 32771
|
||||
#define _APS_NEXT_CONTROL_VALUE 1009
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
76
Server/ManageTool/ChatParser/stdafx.cpp
Normal file
76
Server/ManageTool/ChatParser/stdafx.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
// stdafx.cpp : 표준 포함 파일만 들어 있는 소스 파일입니다.
|
||||
// ChatParser.pch는 미리 컴파일된 헤더가 됩니다.
|
||||
// stdafx.obj에는 미리 컴파일된 형식 정보가 포함됩니다.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ChatParserSetup.h"
|
||||
|
||||
/// \brief 섹션명과 키로 ini 셋업 파일에서 셋팅된 값 얻기
|
||||
/// \param szSection 얻고자하는 값이 속한 섹션명
|
||||
/// \param szKey 얻고자 하는 값에 매칭되는 키
|
||||
const char* GetMyINIString(const char* szSection, const char* szKey)
|
||||
{
|
||||
const char* szResult = CChatParserSetup::GetInstance().GetString(szSection, szKey, 0);
|
||||
|
||||
if(0 == szResult)
|
||||
{
|
||||
CString strErr;
|
||||
strErr.Format("Setup string load failed! - key: %s", szKey);
|
||||
AfxMessageBox(strErr, MB_ICONSTOP);
|
||||
return "???";
|
||||
}
|
||||
|
||||
return szResult;
|
||||
}
|
||||
|
||||
const int GetChatType(const char* szType)
|
||||
{
|
||||
int iCount = 17;
|
||||
char* strFind[] = {
|
||||
"NORMAL",
|
||||
"PARTY",
|
||||
"FRIEND",
|
||||
"GUILD",
|
||||
"CLIENT_LOG",
|
||||
"STALL",
|
||||
"SHOUT",
|
||||
"ADMIN_NORMAL_CHAT",
|
||||
"ADMIN_SHOUT",
|
||||
"WHISPER",
|
||||
"TRADE",
|
||||
"CAMP_SHOP",
|
||||
"NOTIFY_CHAR_INFO",
|
||||
"FIND_PARTY",
|
||||
"ENEMY_CHECK",
|
||||
"DICE",
|
||||
"NOTICE"
|
||||
};
|
||||
int FindID[] = {
|
||||
NORMAL,
|
||||
PARTY,
|
||||
FRIEND,
|
||||
GUILD,
|
||||
CLIENT_LOG,
|
||||
STALL,
|
||||
SHOUT,
|
||||
ADMIN_NORMAL_CHAT,
|
||||
ADMIN_SHOUT,
|
||||
WHISPER,
|
||||
TRADE,
|
||||
CAMP_SHOP,
|
||||
NOTIFY_CHAR_INFO,
|
||||
FIND_PARTY,
|
||||
ENEMY_CHECK,
|
||||
DICE,
|
||||
NOTICE
|
||||
};
|
||||
|
||||
|
||||
for(int i = 0; i < iCount; ++i)
|
||||
{
|
||||
if(strcmp(szType, strFind[i]) == 0)
|
||||
return FindID[i]+1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
111
Server/ManageTool/ChatParser/stdafx.h
Normal file
111
Server/ManageTool/ChatParser/stdafx.h
Normal file
@@ -0,0 +1,111 @@
|
||||
// stdafx.h : 자주 사용하지만 자주 변경되지는 않는
|
||||
// 표준 시스템 포함 파일 및 프로젝트 관련 포함 파일이
|
||||
// 들어 있는 포함 파일입니다.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _SECURE_ATL
|
||||
#define _SECURE_ATL 1
|
||||
#endif
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
#define VC_EXTRALEAN // 거의 사용되지 않는 내용은 Windows 헤더에서 제외합니다.
|
||||
#endif
|
||||
|
||||
// 아래 지정된 플랫폼에 우선하는 플랫폼을 대상으로 하는 경우 다음 정의를 수정하십시오.
|
||||
// 다른 플랫폼에 사용되는 해당 값의 최신 정보는 MSDN을 참조하십시오.
|
||||
#ifndef WINVER // Windows XP 이상에서만 기능을 사용할 수 있습니다.
|
||||
#define WINVER 0x0501 // 다른 버전의 Windows에 맞도록 적합한 값으로 변경해 주십시오.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINNT // Windows XP 이상에서만 기능을 사용할 수 있습니다.
|
||||
#define _WIN32_WINNT 0x0501 // 다른 버전의 Windows에 맞도록 적합한 값으로 변경해 주십시오.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINDOWS // Windows 98 이상에서만 기능을 사용할 수 있습니다.
|
||||
#define _WIN32_WINDOWS 0x0410 // Windows Me 이상에 맞도록 적합한 값으로 변경해 주십시오.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_IE // IE 6.0 이상에서만 기능을 사용할 수 있습니다.
|
||||
#define _WIN32_IE 0x0600 // 다른 버전의 IE에 맞도록 적합한 값으로 변경해 주십시오.
|
||||
#endif
|
||||
|
||||
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 일부 CString 생성자는 명시적으로 선언됩니다.
|
||||
|
||||
// MFC의 공통 부분과 무시 가능한 경고 메시지에 대한 숨기기를 해제합니다.
|
||||
#define _AFX_ALL_WARNINGS
|
||||
|
||||
#include <afxwin.h> // MFC 핵심 및 표준 구성 요소입니다.
|
||||
#include <afxext.h> // MFC 확장입니다.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef _AFX_NO_OLE_SUPPORT
|
||||
#include <afxdtctl.h> // Internet Explorer 4 공용 컨트롤에 대한 MFC 지원입니다.
|
||||
#endif
|
||||
#ifndef _AFX_NO_AFXCMN_SUPPORT
|
||||
#include <afxcmn.h> // Windows 공용 컨트롤에 대한 MFC 지원입니다.
|
||||
#endif // _AFX_NO_AFXCMN_SUPPORT
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef _UNICODE
|
||||
#if defined _M_IX86
|
||||
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
#elif defined _M_IA64
|
||||
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
#elif defined _M_X64
|
||||
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
#else
|
||||
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#pragma warning(disable : 4996) // vs2005에서 추가됨. 보안상의 이유로 더 이상 사용되지 않는 MFC나 ATL 함수를 사용하는 경우에도 C4996이 발생할 수 있습니다
|
||||
|
||||
enum ChatCmdType
|
||||
{
|
||||
NORMAL = 0, // 현재 캐릭터 좌표를 가지고 판단.
|
||||
PARTY = 1, // 파티 채팅
|
||||
FRIEND = 2, // 친구 채팅 (이름 char[16] * m_cNum - MAX 100개)
|
||||
GUILD = 3, // 길드 채팅
|
||||
|
||||
CLIENT_LOG = 5,
|
||||
STALL = 6, // 노점상 채팅 (이름 char[16] * m_cNum - MAX 10개)
|
||||
SHOUT = 7, // 외치기
|
||||
|
||||
ADMIN_NORMAL_CHAT = 8, // 운영자 통상 채팅 (Ack로만 사용)
|
||||
ADMIN_SHOUT = 9, // 운영자 외치기 (Ack로만 사용)
|
||||
|
||||
WHISPER = 10, // 이 번호는 쓰이지 않는다.Whisper는 별도의 패킷을 사용하기 때문이다. 단, 로그시에 쓰인다.
|
||||
TRADE = 11, // 외치기와 동일 (색 구분용으로 다른 커맨드로 만듬)
|
||||
|
||||
CAMP_SHOP = 12, // 길드 요새 상점 채팅 (이름 char[16] * m_cNum - MAX 10개)
|
||||
|
||||
NOTIFY_CHAR_INFO = 13, // 운영자 명령 hp
|
||||
|
||||
FIND_PARTY = 14, // 파티 찾기
|
||||
|
||||
ENEMY_CHECK = 15, // 적아군 식별.
|
||||
|
||||
DICE = 16, // 주사위 채팅 (파티채팅과 동일)
|
||||
|
||||
GMREPORT = 17, // 지엠 채팅
|
||||
|
||||
NOTICE = 255,
|
||||
|
||||
PktChatMaxSize = 180
|
||||
};
|
||||
|
||||
const char* GetMyINIString(const char* szSection, const char* szKey);
|
||||
const int GetChatType(const char* szType);
|
||||
|
||||
|
||||
61
Server/ManageTool/Executable/Executable.vcproj
Normal file
61
Server/ManageTool/Executable/Executable.vcproj
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="ks_c_5601-1987"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="Executable"
|
||||
ProjectGUID="{A4363ECD-EA34-4C86-A0B2-B2BB09F45AFC}"
|
||||
Keyword="MakeFileProj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="10">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="10">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Release"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\release\RylMonitoringToolSetup.ini">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\release\RylSetupManageTool.ini">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\release\RylSetupServerGroup.ini">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
BIN
Server/ManageTool/Executable/ManageServerDB.dat
Normal file
BIN
Server/ManageTool/Executable/ManageServerDB.dat
Normal file
Binary file not shown.
3
Server/ManageTool/Executable/ManageSetupClient.ini
Normal file
3
Server/ManageTool/Executable/ManageSetupClient.ini
Normal file
@@ -0,0 +1,3 @@
|
||||
[ManageClient]
|
||||
ManageServerIP=67.228.215.235
|
||||
ManageServerPort=12538
|
||||
138
Server/ManageTool/Executable/RylMonitoringToolSetup.ini
Normal file
138
Server/ManageTool/Executable/RylMonitoringToolSetup.ini
Normal file
@@ -0,0 +1,138 @@
|
||||
// 최종수정일: 2005-05-19
|
||||
|
||||
|
||||
[MANAGER_SERVER_CONNECTION]
|
||||
MANAGER_SERVER_IP = 122.49.75.3
|
||||
|
||||
|
||||
[CHAT_SERVER_CONNECTION]
|
||||
|
||||
CHAT_SERVER_NUM = 2
|
||||
|
||||
CHAT_SERVER_IP_00 = 0
|
||||
CHAT_SERVER_INDEX_00 = 0
|
||||
|
||||
CHAT_SERVER_IP_01 = 122.49.75.3
|
||||
CHAT_SERVER_INDEX_01 = 1
|
||||
|
||||
//CHAT_SERVER_IP_02 = 67.18.189.3
|
||||
//CHAT_SERVER_INDEX_02 = 2
|
||||
|
||||
|
||||
[SERVER_GROUP_INFO]
|
||||
SERVER_GROUP_NUM = 2
|
||||
|
||||
|
||||
SERVER_GROUP_NAME_00 = TEST
|
||||
SERVER_GROUP_INDEX_00 = 0
|
||||
|
||||
SERVER_GROUP_NAME_01 = Ichman
|
||||
SERVER_GROUP_INDEX_01 = 1
|
||||
|
||||
SERVER_GROUP_NAME_02 = IVERIA
|
||||
SERVER_GROUP_INDEX_02 = 2
|
||||
|
||||
|
||||
[ZONE_INFO]
|
||||
ZONE_NUM = 9
|
||||
|
||||
ZONE_INDEX_00 = 1
|
||||
ZONE_NAME_00 = Zone1
|
||||
|
||||
ZONE_INDEX_01 = 2
|
||||
ZONE_NAME_01 = Zone2
|
||||
|
||||
ZONE_INDEX_02 = 4
|
||||
ZONE_NAME_02 = Zone4
|
||||
|
||||
ZONE_INDEX_03 = 5
|
||||
ZONE_NAME_03 = Zone5
|
||||
|
||||
ZONE_INDEX_04 = 8
|
||||
ZONE_NAME_04 = Zone8
|
||||
|
||||
ZONE_INDEX_05 = 12
|
||||
ZONE_NAME_05 = Zone12
|
||||
|
||||
ZONE_INDEX_06 = 16
|
||||
ZONE_NAME_06 = Zone16
|
||||
|
||||
ZONE_INDEX_07 = 17
|
||||
ZONE_NAME_07 = Zone17
|
||||
|
||||
ZONE_INDEX_08 = 18
|
||||
ZONE_NAME_08 = Zone18
|
||||
|
||||
[CHAT_TYPE_INFO]
|
||||
CHAT_TYPE_NUM = 11
|
||||
|
||||
CHAT_TYPE_NAME_00 = NORMAL
|
||||
CHAT_TYPE_NAME_01 = PARTY
|
||||
CHAT_TYPE_NAME_02 = FRIEND
|
||||
CHAT_TYPE_NAME_03 = GUILD
|
||||
CHAT_TYPE_NAME_04 = STALL
|
||||
CHAT_TYPE_NAME_05 = SHOUT
|
||||
CHAT_TYPE_NAME_06 = ADMIN_NORMAL
|
||||
CHAT_TYPE_NAME_07 = ADMIN_SHOUT
|
||||
CHAT_TYPE_NAME_08 = WHISPER
|
||||
CHAT_TYPE_NAME_09 = NOTICE
|
||||
CHAT_TYPE_NAME_10 = TRADE
|
||||
|
||||
SEND_CHAT_TYPE_NUM = 2
|
||||
|
||||
SEND_CHAT_TYPE_NAME_00 = SHOUT
|
||||
SEND_CHAT_TYPE_NAME_01 = ADMIN_SHOUT
|
||||
|
||||
[CHANNEL_INFO]
|
||||
CHANNEL_NUM = 1
|
||||
|
||||
[LOCAL_STRING]
|
||||
|
||||
STRING_001 = 현재라인
|
||||
STRING_002 = 라인수 (최대 5000라인)
|
||||
STRING_003 = 자동스크롤
|
||||
STRING_004 = 채팅로그출력
|
||||
STRING_005 = 모니터링창 비우기
|
||||
STRING_006 = [필터 옵션]
|
||||
STRING_007 = 서버 그룹
|
||||
STRING_008 = 채팅 타입
|
||||
STRING_009 = [유저 동접 정보]
|
||||
STRING_010 = 관리서버 연결 상태:
|
||||
STRING_011 = 동접로그 출력
|
||||
STRING_012 = 총합:
|
||||
STRING_013 = 관리서버 인증
|
||||
STRING_014 = GM명
|
||||
STRING_015 = 대상 캐릭터 명
|
||||
STRING_016 = 메세지:
|
||||
STRING_017 = 보내기
|
||||
STRING_018 = 작업 결과:
|
||||
STRING_019 = 채팅 서버 인증
|
||||
STRING_020 = [창 전환]>>>>
|
||||
STRING_021 = 대화 상대:
|
||||
STRING_022 = 대상 계정 또는 UID
|
||||
STRING_023 = 계정으로 귓말 보내기
|
||||
STRING_024 = 귓속말 할 대상은 한명만 지정할 수 있습니다.
|
||||
STRING_025 = 전송 조건이 잘못되었습니다.
|
||||
STRING_026 = 메세지를 전송하는데 실패했습니다.
|
||||
STRING_027 = 연결됨
|
||||
STRING_028 = 연결 끊김
|
||||
STRING_029 = 1대1 대화를 사용할 수 없는 로우입니다.
|
||||
STRING_030 = 채팅 서버 연결 끊김 : 세션을 얻는데 실패했습니다.
|
||||
STRING_031 = 채팅 서버 연결 성공
|
||||
STRING_032 = 채팅 서버 연결 실패
|
||||
STRING_033 = 채팅 서버 연결 끊김
|
||||
STRING_034 = 인증 성공
|
||||
STRING_035 = 인증 실패
|
||||
STRING_036 = 값이 비어있습니다.
|
||||
STRING_037 = 관리 서버 연결 성공
|
||||
STRING_038 = 관리 서버 연결 실패
|
||||
STRING_039 = 관리 서버 연결 끊김
|
||||
STRING_040 = 관리 서버 인증 성공
|
||||
STRING_041 = 채팅 서버 인증
|
||||
STRING_042 = 관리 서버 인증
|
||||
STRING_043 = 해당 캐릭터가 존재하지 않습니다.
|
||||
STRING_044 = 로그인을 해야 사용 가능합니다.
|
||||
STRING_045 = 유저의 대화 요청!
|
||||
STRING_046 = 유저의 메세지 받기로 설정한 후 메세지를 보내십시요.
|
||||
STRING_047 = 현재 로그인 중인 계정
|
||||
STRING_048 = 유저의 메세지 받기
|
||||
BIN
Server/ManageTool/Executable/RylSetupBindServerID.ini
Normal file
BIN
Server/ManageTool/Executable/RylSetupBindServerID.ini
Normal file
Binary file not shown.
149
Server/ManageTool/Executable/RylSetupManageTool.ini
Normal file
149
Server/ManageTool/Executable/RylSetupManageTool.ini
Normal file
@@ -0,0 +1,149 @@
|
||||
// <Release Note>
|
||||
|
||||
// 2005-05-25 (ver: 1480.01)
|
||||
// 1. LOCAL_STRING 섹션에 MSG_063 항목 추가
|
||||
|
||||
|
||||
[CONNECTION]
|
||||
|
||||
ManageServerIP = 67.228.215.235
|
||||
ManageServerPort = 11124
|
||||
|
||||
[MISC]
|
||||
// 기본값: R: 212, G: 208, B: 200
|
||||
TOOL_BACK_CLR_R =212
|
||||
TOOL_BACK_CLR_G =208
|
||||
TOOL_BACK_CLR_B =200
|
||||
|
||||
[LOCAL_STRING]
|
||||
|
||||
TOTAL_USER_COUNT = 총 유저수:
|
||||
SHOW_USER_NUM = 유저수 표시
|
||||
HIDE_USER_NUM = 유저수 숨기기
|
||||
ALL_SERVER_NOTIFY = 전 서버 공지
|
||||
STATUS_COLOR = [서버 상태 색]
|
||||
NORMAL = 정상
|
||||
SERVER_DOWNED = 서버 다운
|
||||
DISCONNECTED = 연결 끊김
|
||||
BLOCKED = 블럭
|
||||
CLIENT_DOWNED = 관리 클라이언트 다운
|
||||
PATCH_ONLY = 패치만 가능
|
||||
LOGIN_CLOSED = 로그인 서버 닫힘
|
||||
GROUP_STATUS = [그룹 상태 색]
|
||||
NORMAL_AND_ALL_OPEN = 정상이며 완전 개방
|
||||
ERROR_OCCURED = 문제 발생
|
||||
ADMIN_OPEN = 운영자만 개방
|
||||
ALLOWED_OPEN = 허용된 유저만 개방
|
||||
CONNECTING_USER_LIST = [접속중인 관리자]
|
||||
WHO_AM_I = 내 계정:
|
||||
CURRENT_MANAGER = 관리 권한을 가진 계정:
|
||||
PROMOTE_ME = 관리 권한 요청
|
||||
LOGIN_UID_GROUP = [로그인 서버, UID 서버]
|
||||
SERVER_GROUP_LIST = [서버 그룹 목록]
|
||||
SELECTED_GROUP_STATUS = [선택된 그룹 상태]
|
||||
FUNCTION_SERVER = (기능 서버)
|
||||
SELECTED_SERVER_INFO = (선택된 그룹 정보)
|
||||
SERVER_GROUP = 서버 그룹:
|
||||
SERVER_ID = 서버 ID:
|
||||
HOSTNAME = 호스트 네임:
|
||||
GAME_ZONE_GROUP = (게임 서버)
|
||||
GROUP_USER_COUNT = 그룹 유저 수:
|
||||
REPORT = [리포트]
|
||||
DISABLE_SOUND_CAUTION = 경고음 사용 안함
|
||||
DISABLE_REPORT = 리포트 안함
|
||||
REPORT_LIST = >> 리포트 내용
|
||||
DELETE = 삭제
|
||||
ALL_DELETE = 모두 삭제
|
||||
OPERATION_REPORT = >> 수행 결과
|
||||
NOTIFY_CONTENTS = [공지 내용]
|
||||
NOTIFY_TARGET = [공지 대상]
|
||||
MESSAGE_DELAY = 1라인 공지당 시간 간격:
|
||||
SEC = 초
|
||||
TIME_INTERVAL = 회당 간격:
|
||||
MIN = 분
|
||||
TIMES = 회
|
||||
FREQUENCY = 횟수:
|
||||
NOTIFY = 공지
|
||||
ADMIN_INFO = 운영자 정보
|
||||
ADMIN_REG = 운영자 등록
|
||||
ADMIN_DEL = 운영자 삭제
|
||||
ADMIN_EDIT = 운영자 정보 수정
|
||||
ADMIN_MANAGEMENT = 운영자 관리창
|
||||
LOGIN_NAME_1 = 로우(통합)
|
||||
LOGIN_NAME_2 = 로우(신규)
|
||||
LOGIN_NAME_3 = 테스트
|
||||
STAT_SERVER_STATUS = [통계 서버 상태]
|
||||
STAT_1ST_STATUS = 1ST 연결
|
||||
STAT_2ND_STATUS = 2ND 연결
|
||||
|
||||
|
||||
|
||||
MSG_001 = 로우 서버 관리툴이 초기화 되었습니다!
|
||||
MSG_002 = 관리 권한을 가지고 있지 않기 때문에 메뉴를 사용할 수 없습니다.
|
||||
MSG_003 = 접속 오류 - 에러코드-%d
|
||||
MSG_004 = 서버 명령 실패 - NULL 세션 <※ 관리서버와의 연결상태를 확인하십시요.>
|
||||
MSG_005 = 잘못된 서버 타입이거나 실행 정보를 얻어오는데 실패했습니다.
|
||||
MSG_006 = %s 시작 실패 - NULL세션, 에러코드-%d
|
||||
MSG_007 = %s 시작 실패 - 잘못된 서버 타입이거나 실행 정보를 얻어오는데 실패했습니다, 에러코드-%d
|
||||
MSG_008 = %s 종료 실패 - NULL 세션, 에러코드-%d
|
||||
MSG_009 = %s 종료 실패 - 잘못된 서버 타입이거나 실행 정보를 얻어오는제 실패했습니다. 에러코드-%d
|
||||
MSG_010 = 정말로 강제 종료하시겠습니까?
|
||||
MSG_011 = %s 프로세스 강제 종료 실패 - NULL 세션, 에러코드-%d
|
||||
MSG_012 = %s 프로세스 강제 종료 실패 - 잘못된 서버 타입이거나 실행 정보를 얻어오는데 실패했습니다, 에러코드-%d
|
||||
MSG_013 = 프로세스 강제 종료 취소됨
|
||||
MSG_014 = 관리 클라이언트 다운
|
||||
MSG_015 = 서버 다운
|
||||
MSG_016 = 미디어웹 통합 과금 서버와 연결끊김
|
||||
MSG_017 = 중계 서버와 연결 끊김
|
||||
MSG_018 = 채팅 서버와 연결 끊김
|
||||
MSG_019 = 로그인 서버와 연결 끊김
|
||||
MSG_020 = UID서버와 연결 끊김
|
||||
MSG_021 = 서버 블럭
|
||||
MSG_022 = 관리 권한을 가지고 있지 않습니다.
|
||||
MSG_023 = 관리 권한이 요청되었습니다. 승인하시겠습니까? (요청자-ID: %s/ Name: %s/ IP: %s)
|
||||
MSG_024 = 관리 권한을 요청하시겠습니까?
|
||||
MSG_025 = RunID 맵 셋팅 실패 - RunID를 찾을 수 없습니다. (0x%08X (Group: %d))
|
||||
MSG_026 = 아직 접속되지 않았습니다. 잠시만 기다려 주세요.
|
||||
MSG_027 = 접속 성공 - %s:%d
|
||||
MSG_028 = 접속 실패 - 에러코드-%d
|
||||
MSG_029 = 세션 연결 끊김
|
||||
MSG_030 = 관리 서버와 연결이 끊겼습니다.
|
||||
MSG_031 = 잘못된 RunID 정보입니다. 서버 제어를 할 수 없습니다.
|
||||
MSG_032 = 인증 성공
|
||||
MSG_033 = 인증 실패 - 에러코드: %d
|
||||
MSG_034 = 관리 권한 얻기 성공
|
||||
MSG_035 = 관리 권한 요청 실패 - 에러코드-%d
|
||||
MSG_036 = 잘못된 패킷 사이즈 - SS:0x%p/Cmd:0x%p/Size:%d
|
||||
MSG_037 = 유저 추가 실패 - SS: 0x%p, Cmd:0x%p, Err:%d
|
||||
MSG_038 = 유저 리스트 얻기 실패 - SS:0x%p, Cmd:0x%p, Err:%d
|
||||
MSG_039 = 유저 로그인 패킷 얻기 실패 - SS:0x%p, Cmd:0x%p, Err:%d
|
||||
MSG_040 = 유저 로그아웃 패킷 얻기 실패 - SS:0x%p, Cmd:0x%p, Err:%d
|
||||
MSG_041 = RunID 정보 얻기 성공. 서버 제어가 가능합니다.
|
||||
MSG_042 = 프로세스 상태 패킷 얻기 실패 - SS:0x%p, Cmd:0x%p, Err:%d
|
||||
MSG_043 = 유저리액션 요청 실패 - SS:0x%p, Cmd:0x%p, Err:%d
|
||||
MSG_044 = 관리자 정보 얻기 실패 - SS:0x%p, Cmd:0x%p, Err:%d
|
||||
MSG_045 = 등록 할 유저 정보 보내기 실패. 유저 등록 실패.
|
||||
MSG_046 = 연결이 끊겨 있어서 유저를 등록할 수 없습니다.
|
||||
MSG_047 = 수정 할 유저 정보 보내기 실패. 유저 정보를 수정 할 수 없습니다.
|
||||
MSG_048 = 연결이 끊겨 있어서 유저 정보를 수정할 수 없습니다.
|
||||
MSG_049 = 삭제할 유저 정보 보내기 실패. 유저 삭제 실패.
|
||||
MSG_050 = 연결이 끊겨 있어서 유저를 삭제할 수 없습니다.
|
||||
MSG_051 = 운영자 등록창
|
||||
MSG_052 = 새 운영자 정보
|
||||
MSG_053 = 운영자 수정창
|
||||
MSG_054 = 수정 정보
|
||||
MSG_056 = 공지 성공: %s
|
||||
MSG_057 = 공지 완료
|
||||
MSG_058 = 공지 시작
|
||||
MSG_059 = 메모리 할당 실패로 인해 공지를 보내는데 실패했습니다.
|
||||
MSG_060 = 공지 메시지 추가 실패: 공지를 보내는데 실패했습니다.
|
||||
MSG_061 = 공지가 완료되기 전에 창을 닫으면 보내고 있던 공지가 취소됩니다. 그래도 닫으시겠습니까?
|
||||
MSG_062 = 공지가 취소되었습니다.
|
||||
MSG_063 = 에러가 있는 패킷 수신 - SS:0x%p, Cmd:0x%p, Err:%d
|
||||
MSG_064 = 통계서버(1ST) 다운
|
||||
MSG_065 = 통계서버(2ND) 다운
|
||||
MSG_066 = 메인 배경색 변경: 색상을 선택한 후 Apply!
|
||||
MSG_067 = 인증 실패 - 에러코드: %d (이미 로그인되어 있습니다)
|
||||
MSG_068 = 인증 실패 - 에러코드: %d (존재하지 않는 유저입니다)
|
||||
MSG_069 = 인증 실패 - 에러코드: %d (패스워드가 일치하지 않습니다)
|
||||
MSG_070 = 인증 실패 - 에러코드: %d (등록된 IP와 일치하지 않습니다)
|
||||
170
Server/ManageTool/Executable/RylSetupServerGroup.ini
Normal file
170
Server/ManageTool/Executable/RylSetupServerGroup.ini
Normal file
@@ -0,0 +1,170 @@
|
||||
// <Release Note>
|
||||
// '//'는 주석 표시입니다.
|
||||
|
||||
// 2004-07-27
|
||||
// 1. GENERAL 섹션에 LOGIN_SERVER_NUM 키 추가. 로그인 서버 관리 및 로그인 서버 상태 표시에 영향을 미칩니다.
|
||||
|
||||
// 2004-07-28
|
||||
// 1. 로그인 서버 기능 추가. 로그인 서버 메뉴와 서버 그룹 메뉴에 접속 단계 조절 기능 추가.
|
||||
// (각 단계별 접속 가능 IP는 매뉴얼 참고)
|
||||
|
||||
// 2004-11-03
|
||||
// 1. STATSERVER_SEND_USER_INFO 섹션을 GLOBAL_STATSERVER_INFO 섹션으로 변경하였습니다.
|
||||
// 2. 기존에 STATSERVER_SEND_USER_INFO 섹션에 있던 NATION_INDEX 키를 GENERAL 섹션으로 이동했습니다.
|
||||
// 3. LOCAL_STATSERVER_INFO 섹션이 추가 되었습니다.
|
||||
// 이 섹션은 한국의 통계서버 이외에 별도의 통계서버를 운영하고자 할때 해당 통계서버의 정보를 설정하시면 됩니다.
|
||||
// 설정 내용은 GLOBAL_STATSERVER_INFO 섹션과 동일합니다.
|
||||
|
||||
// 2005-05-25 (ver: 1480.01)
|
||||
// 1. GAMESERVER 섹션에 존16 다크 카나번이 추가되었습니다.
|
||||
// 2. Ping체크 기능이 추가되어서 오래동안 ManageTool과 ManageServer가 핑을 주고 받지 않는 경우 연결이 끊깁니다.
|
||||
// 3. ManageTool에서 ManageServer와 StatServer의 연결 상태를 확인할 수 있습니다.
|
||||
|
||||
// 2005-09-29
|
||||
// 1. GLOBAL_STATSERVER_INFO와 LOCAL_STATSERVER_INFO를 STATSERVER_INFO로 통합했습니다.
|
||||
// 2. 기존의 한국, 로컬 두개의 통계서버를 두는 체계에서 한국에만 두개의 통계서버를 두는 형태로 변경되었습니다.
|
||||
// 3. 셋팅은 특별한 문제가 없는한 항상 두곳(1ST, 2ND)으로 보내도록 셋팅하시면 됩니다.
|
||||
|
||||
[GENERAL]
|
||||
|
||||
// NATION_INDEX : 국가 코드. 반드시 국가에 맞는 코드로 설정해주세요!
|
||||
// 한국 = 1
|
||||
// 대만 = 2
|
||||
// 중국(북경) = 31, 중국(상해) = 32, 중국(광주) = 33, 중국(성도) = 34
|
||||
// 태국 = 4
|
||||
// 말레이시아 = 5
|
||||
// 인도네시아 = 6, 인도네시아 배틀로한 = 61
|
||||
// 미국 = 7
|
||||
// 베트남 = 8
|
||||
// 일본 = 9
|
||||
|
||||
NATION_INDEX = 1
|
||||
|
||||
// LOGIN_SERVER_NUM : 관리툴로 관리할 로그인 서버의 갯수
|
||||
LOGIN_SERVER_NUM = 2
|
||||
|
||||
// GAME_CHANNEL_NUM : 게임 채널의 갯수 (구 버전은 단일채널만 지원됩니다)
|
||||
GAME_CHANNEL_NUM = 1
|
||||
|
||||
// #표시는 숫자 생략입니다. 모든 섹션 공통으로 0부터 1씩 차례로 증가하게 셋팅하면 됩니다.
|
||||
|
||||
// GAME_CHANNEL_KEY# : 게임 채널 인덱스. 채널인덱스는 0부터 1씩 증가합니다.
|
||||
// 일반적으로 유저가 보는 1번 채널은 내부 인덱스로 0입니다.
|
||||
GAME_CHANNEL_KEY0 = 0
|
||||
// GAME_CHANNEL_STRING# : 해당 게임 채널 명칭. 단순히 알아보기 쉽게 기록하면 됩니다. 예)CH1, Channel1
|
||||
GAME_CHANNEL_STRING0 = CH1
|
||||
|
||||
GAME_CHANNEL_KEY1 = 1
|
||||
GAME_CHANNEL_STRING1 = CH2
|
||||
|
||||
GAME_CHANNEL_KEY2 = 2
|
||||
GAME_CHANNEL_STRING2 = CH3
|
||||
|
||||
|
||||
[SERVER_TYPE]
|
||||
|
||||
// SERVER_TYPE_NUM : 서버 종류의 갯수
|
||||
SERVER_TYPE_NUM = 8
|
||||
|
||||
// SERVER_TYPE_KEY# : 해당 서버 타입의 인덱스. 혹 서버 종류가 늘면 새로 인덱스를 알려드리겠습니다.
|
||||
SERVER_TYPE_KEY0 = 0
|
||||
// SERVER_TYPE_STRING# : 해당 서버 타입의 이름.
|
||||
SERVER_TYPE_STRING0 = Login
|
||||
|
||||
SERVER_TYPE_KEY1 = 1
|
||||
SERVER_TYPE_STRING1 = Auth
|
||||
|
||||
SERVER_TYPE_KEY2 = 2
|
||||
SERVER_TYPE_STRING2 = Game
|
||||
|
||||
SERVER_TYPE_KEY3 = 3
|
||||
SERVER_TYPE_STRING3 = Agent
|
||||
|
||||
SERVER_TYPE_KEY4 = 4
|
||||
SERVER_TYPE_STRING4 = UID
|
||||
|
||||
SERVER_TYPE_KEY5 = 5
|
||||
SERVER_TYPE_STRING5 = Admin
|
||||
|
||||
SERVER_TYPE_KEY6 = 6
|
||||
SERVER_TYPE_STRING6 = Log
|
||||
|
||||
SERVER_TYPE_KEY7 = 7
|
||||
SERVER_TYPE_STRING7 = Chat
|
||||
|
||||
|
||||
[SERVER_GROUP]
|
||||
|
||||
// SERVER_GROUP_NUM : 서버 그룹 수
|
||||
SERVER_GROUP_NUM = 2
|
||||
|
||||
// SERVER_GROUP_KEY# : 해당 서버 그룹의 인덱스
|
||||
SERVER_GROUP_KEY0 = 0
|
||||
// SERVER_GROUP_STRING# : 해당 서버 그룹의 이름
|
||||
SERVER_GROUP_STRING0 = 테스트
|
||||
|
||||
SERVER_GROUP_KEY1 = 1
|
||||
SERVER_GROUP_STRING1 = Ichman
|
||||
|
||||
//SERVER_GROUP_KEY2 = 2
|
||||
//SERVER_GROUP_STRING2 = 라타르
|
||||
|
||||
//SERVER_GROUP_KEY3 = 3
|
||||
//SERVER_GROUP_STRING3 = 루안
|
||||
|
||||
|
||||
|
||||
[GAMESERVER]
|
||||
|
||||
// GAME_ZONE_NUM : 게임 존 갯수
|
||||
GAME_ZONE_NUM = 10
|
||||
|
||||
// GAME_ZONE_KEY : 게임존의 인덱스를 뜻합니다. 예) 카나번 = 8, 그랜드 코스트 = 1
|
||||
GAME_ZONE_KEY0 = 1
|
||||
// GAME_ZONE_STRING : 해당 존의 이름
|
||||
GAME_ZONE_STRING0 = Zone1
|
||||
|
||||
GAME_ZONE_KEY1 = 2
|
||||
GAME_ZONE_STRING1 = Zone2
|
||||
|
||||
GAME_ZONE_KEY2 = 4
|
||||
GAME_ZONE_STRING2 = Zone4
|
||||
|
||||
GAME_ZONE_KEY3 = 5
|
||||
GAME_ZONE_STRING3 = Zone5
|
||||
|
||||
GAME_ZONE_KEY4 = 8
|
||||
GAME_ZONE_STRING4 = Zone8
|
||||
|
||||
GAME_ZONE_KEY5 = 12
|
||||
GAME_ZONE_STRING5 = Zone12
|
||||
|
||||
GAME_ZONE_KEY6 = 14
|
||||
GAME_ZONE_STRING6 = Prizon
|
||||
|
||||
GAME_ZONE_KEY7 = 16
|
||||
GAME_ZONE_STRING7 = Zone16
|
||||
|
||||
GAME_ZONE_KEY8 = 17
|
||||
GAME_ZONE_STRING8 = Zone17
|
||||
|
||||
GAME_ZONE_KEY9 = 18
|
||||
GAME_ZONE_STRING9 = Zone18
|
||||
|
||||
// 통계 서버 정보
|
||||
[STATSERVER_INFO]
|
||||
|
||||
// SEND_STAT_SERVER_1ST : 첫번째 통계서버로 정보를 보낼지 여부. 1은 보내기이고 1이외의 문자는 보내지 않음.
|
||||
SEND_STAT_SERVER_1ST = 0
|
||||
// STAT_SERVER_1ST_IP : 첫번째 통계서버의 아이피 61.251.229.189(한국 Frac 서버)로 셋팅
|
||||
STAT_SERVER_1ST_IP = 61.251.229.189
|
||||
|
||||
// SEND_STAT_SERVER_2ND : 두번째 통계서버로 정보를 보낼지 여부. 1은 보내기이고 1이외의 문자는 보내지 않음.
|
||||
SEND_STAT_SERVER_2ND = 0
|
||||
// STAT_SERVER_2ND_IP: 두번째 통계서버의 아이피 61.251.229.187(한국 Fusion 서버)로 셋팅
|
||||
STAT_SERVER_2ND_IP = 61.251.229.187
|
||||
|
||||
// 옵션 셋팅
|
||||
[SETTING]
|
||||
// 0: 체크 안함, 1: 체크
|
||||
USER_IP_CHECK = 0
|
||||
218
Server/ManageTool/GridControl/GridControl.vcproj
Normal file
218
Server/ManageTool/GridControl/GridControl.vcproj
Normal file
@@ -0,0 +1,218 @@
|
||||
<?xml version="1.0" encoding="ks_c_5601-1987"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="GridControl"
|
||||
ProjectGUID="{EE20E867-1836-4550-A08D-1BBA2F7B2EA3}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../Library/$(ConfigurationName)"
|
||||
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
UseOfMFC="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="3"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/GridControl.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../Library/$(ConfigurationName)"
|
||||
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
UseOfMFC="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="FALSE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="3"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/GridControl.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="소스 파일"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="헤더 파일"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath=".\stdafx.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="리소스 파일"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="GridCtrl_src"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\CellRange.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\GridCell.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\GridCell.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\GridCellBase.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\GridCellBase.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\GridCtrl.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\GridCtrl.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\GridDropTarget.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\GridDropTarget.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\InPlaceEdit.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\InPlaceEdit.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\MemDC.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\TitleTip.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GridCtrl_src\TitleTip.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="NewCellTypes"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\NewCellTypes\GridCellCheck.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NewCellTypes\GridCellCheck.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NewCellTypes\GridCellCombo.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NewCellTypes\GridCellCombo.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NewCellTypes\GridCellDateTime.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NewCellTypes\GridCellDateTime.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NewCellTypes\GridCellNumeric.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NewCellTypes\GridCellNumeric.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NewCellTypes\GridURLCell.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NewCellTypes\GridURLCell.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\ReadMe.txt">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
148
Server/ManageTool/GridControl/GridCtrl_src/CellRange.h
Normal file
148
Server/ManageTool/GridControl/GridCtrl_src/CellRange.h
Normal file
@@ -0,0 +1,148 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CellRange.h: header file
|
||||
//
|
||||
// MFC Grid Control - interface for the CCellRange class.
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.20+
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_CELLRANGE_H__F86EF761_725A_11D1_ABBA_00A0243D1382__INCLUDED_)
|
||||
#define AFX_CELLRANGE_H__F86EF761_725A_11D1_ABBA_00A0243D1382__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
// The code contained in this file is based on the original
|
||||
// WorldCom Grid control written by Joe Willcoxson,
|
||||
// mailto:chinajoe@aol.com
|
||||
// http://users.aol.com/chinajoe
|
||||
|
||||
class AFX_EXT_CLASS CCellID
|
||||
{
|
||||
// Attributes
|
||||
public:
|
||||
int row, col;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
explicit CCellID(int nRow = -1, int nCol = -1) : row(nRow), col(nCol) {}
|
||||
|
||||
int IsValid() const { return (row >= 0 && col >= 0); }
|
||||
int operator==(const CCellID& rhs) const { return (row == rhs.row && col == rhs.col); }
|
||||
int operator!=(const CCellID& rhs) const { return !operator==(rhs); }
|
||||
};
|
||||
|
||||
class AFX_EXT_CLASS CCellRange
|
||||
{
|
||||
public:
|
||||
|
||||
CCellRange(int nMinRow = -1, int nMinCol = -1, int nMaxRow = -1, int nMaxCol = -1)
|
||||
{
|
||||
Set(nMinRow, nMinCol, nMaxRow, nMaxCol);
|
||||
}
|
||||
|
||||
void Set(int nMinRow = -1, int nMinCol = -1, int nMaxRow = -1, int nMaxCol = -1);
|
||||
|
||||
int IsValid() const;
|
||||
int InRange(int row, int col) const;
|
||||
int InRange(const CCellID& cellID) const;
|
||||
int Count() { return (m_nMaxRow - m_nMinRow + 1) * (m_nMaxCol - m_nMinCol + 1); }
|
||||
|
||||
CCellID GetTopLeft() const;
|
||||
CCellRange Intersect(const CCellRange& rhs) const;
|
||||
|
||||
int GetMinRow() const {return m_nMinRow;}
|
||||
void SetMinRow(int minRow) {m_nMinRow = minRow;}
|
||||
|
||||
int GetMinCol() const {return m_nMinCol;}
|
||||
void SetMinCol(int minCol) {m_nMinCol = minCol;}
|
||||
|
||||
int GetMaxRow() const {return m_nMaxRow;}
|
||||
void SetMaxRow(int maxRow) {m_nMaxRow = maxRow;}
|
||||
|
||||
int GetMaxCol() const {return m_nMaxCol;}
|
||||
void SetMaxCol(int maxCol) {m_nMaxCol = maxCol;}
|
||||
|
||||
int GetRowSpan() const {return m_nMaxRow - m_nMinRow + 1;}
|
||||
int GetColSpan() const {return m_nMaxCol - m_nMinCol + 1;}
|
||||
|
||||
void operator=(const CCellRange& rhs);
|
||||
int operator==(const CCellRange& rhs);
|
||||
int operator!=(const CCellRange& rhs);
|
||||
|
||||
protected:
|
||||
int m_nMinRow;
|
||||
int m_nMinCol;
|
||||
int m_nMaxRow;
|
||||
int m_nMaxCol;
|
||||
};
|
||||
|
||||
inline void CCellRange::Set(int minRow, int minCol, int maxRow, int maxCol)
|
||||
{
|
||||
m_nMinRow = minRow;
|
||||
m_nMinCol = minCol;
|
||||
m_nMaxRow = maxRow;
|
||||
m_nMaxCol = maxCol;
|
||||
}
|
||||
|
||||
inline void CCellRange::operator=(const CCellRange& rhs)
|
||||
{
|
||||
if (this != &rhs) Set(rhs.m_nMinRow, rhs.m_nMinCol, rhs.m_nMaxRow, rhs.m_nMaxCol);
|
||||
}
|
||||
|
||||
inline int CCellRange::operator==(const CCellRange& rhs)
|
||||
{
|
||||
return ((m_nMinRow == rhs.m_nMinRow) && (m_nMinCol == rhs.m_nMinCol) &&
|
||||
(m_nMaxRow == rhs.m_nMaxRow) && (m_nMaxCol == rhs.m_nMaxCol));
|
||||
}
|
||||
|
||||
inline int CCellRange::operator!=(const CCellRange& rhs)
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
inline int CCellRange::IsValid() const
|
||||
{
|
||||
return (m_nMinRow >= 0 && m_nMinCol >= 0 && m_nMaxRow >= 0 && m_nMaxCol >= 0 &&
|
||||
m_nMinRow <= m_nMaxRow && m_nMinCol <= m_nMaxCol);
|
||||
}
|
||||
|
||||
inline int CCellRange::InRange(int row, int col) const
|
||||
{
|
||||
return (row >= m_nMinRow && row <= m_nMaxRow && col >= m_nMinCol && col <= m_nMaxCol);
|
||||
}
|
||||
|
||||
inline int CCellRange::InRange(const CCellID& cellID) const
|
||||
{
|
||||
return InRange(cellID.row, cellID.col);
|
||||
}
|
||||
|
||||
inline CCellID CCellRange::GetTopLeft() const
|
||||
{
|
||||
return CCellID(m_nMinRow, m_nMinCol);
|
||||
}
|
||||
|
||||
inline CCellRange CCellRange::Intersect(const CCellRange& rhs) const
|
||||
{
|
||||
return CCellRange(max(m_nMinRow,rhs.m_nMinRow), max(m_nMinCol,rhs.m_nMinCol),
|
||||
min(m_nMaxRow,rhs.m_nMaxRow), min(m_nMaxCol,rhs.m_nMaxCol));
|
||||
}
|
||||
|
||||
#endif // !defined(AFX_CELLRANGE_H__F86EF761_725A_11D1_ABBA_00A0243D1382__INCLUDED_)
|
||||
278
Server/ManageTool/GridControl/GridCtrl_src/GridCell.cpp
Normal file
278
Server/ManageTool/GridControl/GridCtrl_src/GridCell.cpp
Normal file
@@ -0,0 +1,278 @@
|
||||
// GridCell.cpp : implementation file
|
||||
//
|
||||
// MFC Grid Control - Main grid cell class
|
||||
//
|
||||
// Provides the implementation for the "default" cell type of the
|
||||
// grid control. Adds in cell editing.
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.20+
|
||||
//
|
||||
// History:
|
||||
// Eric Woodruff - 20 Feb 2000 - Added PrintCell() plus other minor changes
|
||||
// Ken Bertelson - 12 Apr 2000 - Split CGridCell into CGridCell and CGridCellBase
|
||||
// <kenbertelson@hotmail.com>
|
||||
// C Maunder - 17 Jun 2000 - Font handling optimsed, Added CGridDefaultCell
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "GridCell.h"
|
||||
#include "InPlaceEdit.h"
|
||||
#include "GridCtrl.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
IMPLEMENT_DYNCREATE(CGridCell, CGridCellBase)
|
||||
IMPLEMENT_DYNCREATE(CGridDefaultCell, CGridCell)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GridCell
|
||||
|
||||
CGridCell::CGridCell()
|
||||
{
|
||||
m_plfFont = NULL;
|
||||
CGridCell::Reset();
|
||||
}
|
||||
|
||||
CGridCell::~CGridCell()
|
||||
{
|
||||
delete m_plfFont;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GridCell Attributes
|
||||
|
||||
void CGridCell::operator=(const CGridCell& cell)
|
||||
{
|
||||
if (this != &cell) CGridCellBase::operator=(cell);
|
||||
}
|
||||
|
||||
void CGridCell::Reset()
|
||||
{
|
||||
CGridCellBase::Reset();
|
||||
|
||||
m_strText.Empty();
|
||||
m_nImage = -1;
|
||||
m_pGrid = NULL;
|
||||
m_bEditing = FALSE;
|
||||
m_pEditWnd = NULL;
|
||||
|
||||
m_nFormat = (DWORD)-1; // Use default from CGridDefaultCell
|
||||
m_crBkClr = CLR_DEFAULT; // Background colour (or CLR_DEFAULT)
|
||||
m_crFgClr = CLR_DEFAULT; // Forground colour (or CLR_DEFAULT)
|
||||
m_nMargin = (UINT)-1; // Use default from CGridDefaultCell
|
||||
|
||||
delete m_plfFont;
|
||||
m_plfFont = NULL; // Cell font
|
||||
}
|
||||
|
||||
void CGridCell::SetFont(const LOGFONT* plf)
|
||||
{
|
||||
if (plf == NULL)
|
||||
{
|
||||
delete m_plfFont;
|
||||
m_plfFont = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_plfFont)
|
||||
m_plfFont = new LOGFONT;
|
||||
if (m_plfFont)
|
||||
memcpy(m_plfFont, plf, sizeof(LOGFONT));
|
||||
}
|
||||
}
|
||||
|
||||
LOGFONT* CGridCell::GetFont() const
|
||||
{
|
||||
if (m_plfFont == NULL)
|
||||
{
|
||||
CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell();
|
||||
if (!pDefaultCell)
|
||||
return NULL;
|
||||
|
||||
return pDefaultCell->GetFont();
|
||||
}
|
||||
|
||||
return m_plfFont;
|
||||
}
|
||||
|
||||
CFont* CGridCell::GetFontObject() const
|
||||
{
|
||||
// If the default font is specified, use the default cell implementation
|
||||
if (m_plfFont == NULL)
|
||||
{
|
||||
CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell();
|
||||
if (!pDefaultCell)
|
||||
return NULL;
|
||||
|
||||
return pDefaultCell->GetFontObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
static CFont Font;
|
||||
Font.DeleteObject();
|
||||
Font.CreateFontIndirect(m_plfFont);
|
||||
return &Font;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD CGridCell::GetFormat() const
|
||||
{
|
||||
if (m_nFormat == (DWORD)-1)
|
||||
{
|
||||
CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell();
|
||||
if (!pDefaultCell)
|
||||
return 0;
|
||||
|
||||
return pDefaultCell->GetFormat();
|
||||
}
|
||||
|
||||
return m_nFormat;
|
||||
}
|
||||
|
||||
UINT CGridCell::GetMargin() const
|
||||
{
|
||||
if (m_nMargin == (UINT)-1)
|
||||
{
|
||||
CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell();
|
||||
if (!pDefaultCell)
|
||||
return 0;
|
||||
|
||||
return pDefaultCell->GetMargin();
|
||||
}
|
||||
|
||||
return m_nMargin;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GridCell Operations
|
||||
|
||||
BOOL CGridCell::Edit(int nRow, int nCol, CRect rect, CPoint /* point */, UINT nID, UINT nChar)
|
||||
{
|
||||
if ( m_bEditing )
|
||||
{
|
||||
if (m_pEditWnd)
|
||||
m_pEditWnd->SendMessage ( WM_CHAR, nChar );
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwStyle = ES_LEFT;
|
||||
if (GetFormat() & DT_RIGHT)
|
||||
dwStyle = ES_RIGHT;
|
||||
else if (GetFormat() & DT_CENTER)
|
||||
dwStyle = ES_CENTER;
|
||||
|
||||
m_bEditing = TRUE;
|
||||
|
||||
// InPlaceEdit auto-deletes itself
|
||||
CGridCtrl* pGrid = GetGrid();
|
||||
m_pEditWnd = new CInPlaceEdit(pGrid, rect, dwStyle, nID, nRow, nCol, GetText(), nChar);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CGridCell::EndEdit()
|
||||
{
|
||||
if (m_pEditWnd)
|
||||
((CInPlaceEdit*)m_pEditWnd)->EndEdit();
|
||||
}
|
||||
|
||||
void CGridCell::OnEndEdit()
|
||||
{
|
||||
m_bEditing = FALSE;
|
||||
m_pEditWnd = NULL;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGridDefaultCell
|
||||
|
||||
CGridDefaultCell::CGridDefaultCell()
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
m_nFormat = DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX;
|
||||
#else
|
||||
m_nFormat = DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX | DT_END_ELLIPSIS;
|
||||
#endif
|
||||
m_crFgClr = CLR_DEFAULT;
|
||||
m_crBkClr = CLR_DEFAULT;
|
||||
m_Size = CSize(30,10);
|
||||
m_dwStyle = 0;
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
LOGFONT lf;
|
||||
GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), &lf);
|
||||
SetFont(&lf);
|
||||
#else // not CE
|
||||
NONCLIENTMETRICS ncm;
|
||||
ncm.cbSize = sizeof(NONCLIENTMETRICS);
|
||||
VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0));
|
||||
SetFont(&(ncm.lfMessageFont));
|
||||
#endif
|
||||
}
|
||||
|
||||
CGridDefaultCell::~CGridDefaultCell()
|
||||
{
|
||||
m_Font.DeleteObject();
|
||||
}
|
||||
|
||||
void CGridDefaultCell::SetFont(const LOGFONT* plf)
|
||||
{
|
||||
ASSERT(plf);
|
||||
|
||||
if (!plf) return;
|
||||
|
||||
m_Font.DeleteObject();
|
||||
m_Font.CreateFontIndirect(plf);
|
||||
|
||||
CGridCell::SetFont(plf);
|
||||
|
||||
// Get the font size and hence the default cell size
|
||||
CDC* pDC = CDC::FromHandle(::GetDC(NULL));
|
||||
if (pDC)
|
||||
{
|
||||
CFont* pOldFont = pDC->SelectObject(&m_Font);
|
||||
|
||||
SetMargin(pDC->GetTextExtent(_T(" "), 1).cx);
|
||||
m_Size = pDC->GetTextExtent(_T(" XXXXXXXXXXXX "), 14);
|
||||
m_Size.cy = (m_Size.cy * 3) / 2;
|
||||
|
||||
pDC->SelectObject(pOldFont);
|
||||
ReleaseDC(NULL, pDC->GetSafeHdc());
|
||||
}
|
||||
else
|
||||
{
|
||||
SetMargin(3);
|
||||
m_Size = CSize(40,16);
|
||||
}
|
||||
}
|
||||
|
||||
LOGFONT* CGridDefaultCell::GetFont() const
|
||||
{
|
||||
ASSERT(m_plfFont); // This is the default - it CAN'T be NULL!
|
||||
return m_plfFont;
|
||||
}
|
||||
|
||||
CFont* CGridDefaultCell::GetFontObject() const
|
||||
{
|
||||
ASSERT(m_Font.GetSafeHandle());
|
||||
return (CFont*) &m_Font;
|
||||
}
|
||||
143
Server/ManageTool/GridControl/GridCtrl_src/GridCell.h
Normal file
143
Server/ManageTool/GridControl/GridCtrl_src/GridCell.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GridCell.h : header file
|
||||
//
|
||||
// MFC Grid Control - Grid cell class header file
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.20+
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_GRIDCELL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
|
||||
#define AFX_GRIDCELL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
class CGridCtrl;
|
||||
#include "GridCellBase.h"
|
||||
|
||||
// Each cell contains one of these. Fields "row" and "column" are not stored since we
|
||||
// will usually have acces to them in other ways, and they are an extra 8 bytes per
|
||||
// cell that is probably unnecessary.
|
||||
|
||||
class AFX_EXT_CLASS CGridCell : public CGridCellBase
|
||||
{
|
||||
friend class CGridCtrl;
|
||||
DECLARE_DYNCREATE(CGridCell)
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CGridCell();
|
||||
virtual ~CGridCell();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
void operator=(const CGridCell& cell);
|
||||
|
||||
virtual void SetText(LPCTSTR szText) { m_strText = szText; }
|
||||
virtual void SetImage(int nImage) { m_nImage = nImage; }
|
||||
virtual void SetData(LPARAM lParam) { m_lParam = lParam; }
|
||||
virtual void SetGrid(CGridCtrl* pGrid) { m_pGrid = pGrid; }
|
||||
// virtual void SetState(const DWORD nState); - use base class version
|
||||
virtual void SetFormat(DWORD nFormat) { m_nFormat = nFormat; }
|
||||
virtual void SetTextClr(COLORREF clr) { m_crFgClr = clr; }
|
||||
virtual void SetBackClr(COLORREF clr) { m_crBkClr = clr; }
|
||||
virtual void SetFont(const LOGFONT* plf);
|
||||
virtual void SetMargin(UINT nMargin) { m_nMargin = nMargin; }
|
||||
virtual CWnd* GetEditWnd() const { return m_pEditWnd; }
|
||||
virtual void SetCoords(int /*nRow*/, int /*nCol*/) {} // don't need to know the row and
|
||||
// column for base implementation
|
||||
|
||||
virtual LPCTSTR GetText() const { return (m_strText.IsEmpty())? _T("") : LPCTSTR(m_strText); }
|
||||
virtual int GetImage() const { return m_nImage; }
|
||||
virtual LPARAM GetData() const { return m_lParam; }
|
||||
virtual CGridCtrl* GetGrid() const { return m_pGrid; }
|
||||
// virtual DWORD GetState() const - use base class
|
||||
virtual DWORD GetFormat() const;
|
||||
virtual COLORREF GetTextClr() const { return m_crFgClr; } // TODO: change to use default cell
|
||||
virtual COLORREF GetBackClr() const { return m_crBkClr; }
|
||||
virtual LOGFONT* GetFont() const;
|
||||
virtual CFont* GetFontObject() const;
|
||||
virtual UINT GetMargin() const;
|
||||
|
||||
virtual BOOL IsEditing() const { return m_bEditing; }
|
||||
virtual BOOL IsDefaultFont() const { return (m_plfFont == NULL); }
|
||||
virtual void Reset();
|
||||
|
||||
// editing cells
|
||||
public:
|
||||
virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar);
|
||||
virtual void EndEdit();
|
||||
protected:
|
||||
virtual void OnEndEdit();
|
||||
|
||||
protected:
|
||||
CString m_strText; // Cell text (or binary data if you wish...)
|
||||
LPARAM m_lParam; // 32-bit value to associate with item
|
||||
int m_nImage; // Index of the list view item’s icon
|
||||
DWORD m_nFormat;
|
||||
COLORREF m_crFgClr;
|
||||
COLORREF m_crBkClr;
|
||||
LOGFONT* m_plfFont;
|
||||
UINT m_nMargin;
|
||||
|
||||
BOOL m_bEditing; // Cell being edited?
|
||||
|
||||
CGridCtrl* m_pGrid; // Parent grid control
|
||||
CWnd* m_pEditWnd;
|
||||
};
|
||||
|
||||
// This class is for storing grid default values. It's a little heavy weight, so
|
||||
// don't use it in bulk
|
||||
class AFX_EXT_CLASS CGridDefaultCell : public CGridCell
|
||||
{
|
||||
DECLARE_DYNCREATE(CGridDefaultCell)
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CGridDefaultCell();
|
||||
virtual ~CGridDefaultCell();
|
||||
|
||||
public:
|
||||
virtual DWORD GetStyle() const { return m_dwStyle; }
|
||||
virtual void SetStyle(DWORD dwStyle) { m_dwStyle = dwStyle; }
|
||||
virtual int GetWidth() const { return m_Size.cx; }
|
||||
virtual int GetHeight() const { return m_Size.cy; }
|
||||
virtual void SetWidth(int nWidth) { m_Size.cx = nWidth; }
|
||||
virtual void SetHeight(int nHeight) { m_Size.cy = nHeight; }
|
||||
|
||||
// Disable these properties
|
||||
virtual void SetData(LPARAM /*lParam*/) { ASSERT(FALSE); }
|
||||
virtual void SetState(DWORD /*nState*/) { ASSERT(FALSE); }
|
||||
virtual DWORD GetState() const { return CGridCell::GetState()|GVIS_READONLY; }
|
||||
virtual void SetCoords( int /*row*/, int /*col*/) { ASSERT(FALSE); }
|
||||
virtual void SetFont(const LOGFONT* /*plf*/);
|
||||
virtual LOGFONT* GetFont() const;
|
||||
virtual CFont* GetFontObject() const;
|
||||
|
||||
protected:
|
||||
CSize m_Size; // Default Size
|
||||
CFont m_Font; // Cached font
|
||||
DWORD m_dwStyle; // Cell Style - unused
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_GRIDCELL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
|
||||
749
Server/ManageTool/GridControl/GridCtrl_src/GridCellBase.cpp
Normal file
749
Server/ManageTool/GridControl/GridCtrl_src/GridCellBase.cpp
Normal file
@@ -0,0 +1,749 @@
|
||||
// GridCellBase.cpp : implementation file
|
||||
//
|
||||
// MFC Grid Control - Main grid cell base class
|
||||
//
|
||||
// Provides the implementation for the base cell type of the
|
||||
// grid control. No data is stored (except for state) but default
|
||||
// implementations of drawing, printingetc provided. MUST be derived
|
||||
// from to be used.
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.22+
|
||||
//
|
||||
// History:
|
||||
// Ken Bertelson - 12 Apr 2000 - Split CGridCell into CGridCell and CGridCellBase
|
||||
// C Maunder - 19 May 2000 - Fixed sort arrow drawing (Ivan Ilinov)
|
||||
// C Maunder - 29 Aug 2000 - operator= checks for NULL font before setting (Martin Richter)
|
||||
// C Maunder - 15 Oct 2000 - GetTextExtent fixed (Martin Richter)
|
||||
// C Maunder - 1 Jan 2001 - Added ValidateEdit
|
||||
//
|
||||
// NOTES: Each grid cell should take care of it's own drawing, though the Draw()
|
||||
// method takes an "erase background" paramter that is called if the grid
|
||||
// decides to draw the entire grid background in on hit. Certain ambient
|
||||
// properties such as the default font to use, and hints on how to draw
|
||||
// fixed cells should be fetched from the parent grid. The grid trusts the
|
||||
// cells will behave in a certain way, and the cells trust the grid will
|
||||
// supply accurate information.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "GridCtrl.h"
|
||||
#include "GridCellBase.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
IMPLEMENT_DYNAMIC(CGridCellBase, CObject)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GridCellBase
|
||||
|
||||
CGridCellBase::CGridCellBase()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
CGridCellBase::~CGridCellBase()
|
||||
{
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GridCellBase Operations
|
||||
|
||||
void CGridCellBase::Reset()
|
||||
{
|
||||
m_nState = 0;
|
||||
}
|
||||
|
||||
void CGridCellBase::operator=(const CGridCellBase& cell)
|
||||
{
|
||||
if (this == &cell) return;
|
||||
|
||||
SetGrid(cell.GetGrid()); // do first in case of dependencies
|
||||
|
||||
SetText(cell.GetText());
|
||||
SetImage(cell.GetImage());
|
||||
SetData(cell.GetData());
|
||||
SetState(cell.GetState());
|
||||
SetFormat(cell.GetFormat());
|
||||
SetTextClr(cell.GetTextClr());
|
||||
SetBackClr(cell.GetBackClr());
|
||||
SetFont(cell.IsDefaultFont()? NULL : cell.GetFont());
|
||||
SetMargin(cell.GetMargin());
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGridCellBase Attributes
|
||||
|
||||
// Returns a pointer to a cell that holds default values for this particular type of cell
|
||||
CGridCellBase* CGridCellBase::GetDefaultCell() const
|
||||
{
|
||||
if (GetGrid())
|
||||
return GetGrid()->GetDefaultCell(IsFixedRow(), IsFixedCol());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGridCellBase Operations
|
||||
|
||||
// EFW - Various changes to make it draw cells better when using alternate
|
||||
// color schemes. Also removed printing references as that's now done
|
||||
// by PrintCell() and fixed the sort marker so that it doesn't draw out
|
||||
// of bounds.
|
||||
BOOL CGridCellBase::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd /*=TRUE*/)
|
||||
{
|
||||
// Note - all through this function we totally brutalise 'rect'. Do not
|
||||
// depend on it's value being that which was passed in.
|
||||
|
||||
CGridCtrl* pGrid = GetGrid();
|
||||
ASSERT(pGrid);
|
||||
|
||||
if (!pGrid || !pDC)
|
||||
return FALSE;
|
||||
|
||||
if( rect.Width() <= 0 || rect.Height() <= 0) // prevents imagelist item from drawing even
|
||||
return FALSE; // though cell is hidden
|
||||
|
||||
//TRACE3("Drawing %scell %d, %d\n", IsFixed()? _T("Fixed ") : _T(""), nRow, nCol);
|
||||
|
||||
int nSavedDC = pDC->SaveDC();
|
||||
pDC->SetBkMode(TRANSPARENT);
|
||||
|
||||
// Get the default cell implementation for this kind of cell. We use it if this cell
|
||||
// has anything marked as "default"
|
||||
CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell();
|
||||
if (!pDefaultCell)
|
||||
return FALSE;
|
||||
|
||||
// Set up text and background colours
|
||||
COLORREF TextClr, TextBkClr;
|
||||
|
||||
TextClr = (GetTextClr() == CLR_DEFAULT)? pDefaultCell->GetTextClr() : GetTextClr();
|
||||
if (GetBackClr() == CLR_DEFAULT)
|
||||
TextBkClr = pDefaultCell->GetBackClr();
|
||||
else
|
||||
{
|
||||
bEraseBkgnd = TRUE;
|
||||
TextBkClr = GetBackClr();
|
||||
}
|
||||
|
||||
// Draw cell background and highlighting (if necessary)
|
||||
if ( IsFocused() || IsDropHighlighted() )
|
||||
{
|
||||
// Always draw even in list mode so that we can tell where the
|
||||
// cursor is at. Use the highlight colors though.
|
||||
if(GetState() & GVIS_SELECTED)
|
||||
{
|
||||
TextBkClr = ::GetSysColor(COLOR_HIGHLIGHT);
|
||||
TextClr = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
|
||||
bEraseBkgnd = TRUE;
|
||||
}
|
||||
|
||||
rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom
|
||||
if (bEraseBkgnd)
|
||||
{
|
||||
TRY
|
||||
{
|
||||
CBrush brush(TextBkClr);
|
||||
pDC->FillRect(rect, &brush);
|
||||
}
|
||||
CATCH(CResourceException, e)
|
||||
{
|
||||
//e->ReportError();
|
||||
}
|
||||
END_CATCH
|
||||
}
|
||||
|
||||
// Don't adjust frame rect if no grid lines so that the
|
||||
// whole cell is enclosed.
|
||||
if(pGrid->GetGridLines() != GVL_NONE)
|
||||
{
|
||||
rect.right--;
|
||||
rect.bottom--;
|
||||
}
|
||||
|
||||
if (pGrid->GetFrameFocusCell())
|
||||
{
|
||||
// Use same color as text to outline the cell so that it shows
|
||||
// up if the background is black.
|
||||
TRY
|
||||
{
|
||||
CBrush brush(TextClr);
|
||||
pDC->FrameRect(rect, &brush);
|
||||
}
|
||||
CATCH(CResourceException, e)
|
||||
{
|
||||
//e->ReportError();
|
||||
}
|
||||
END_CATCH
|
||||
}
|
||||
pDC->SetTextColor(TextClr);
|
||||
|
||||
// Adjust rect after frame draw if no grid lines
|
||||
if(pGrid->GetGridLines() == GVL_NONE)
|
||||
{
|
||||
rect.right--;
|
||||
rect.bottom--;
|
||||
}
|
||||
|
||||
rect.DeflateRect(0,1,1,1);
|
||||
}
|
||||
else if ((GetState() & GVIS_SELECTED))
|
||||
{
|
||||
rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom
|
||||
pDC->FillSolidRect(rect, ::GetSysColor(COLOR_HIGHLIGHT));
|
||||
rect.right--; rect.bottom--;
|
||||
pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bEraseBkgnd)
|
||||
{
|
||||
rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom
|
||||
CBrush brush(TextBkClr);
|
||||
pDC->FillRect(rect, &brush);
|
||||
rect.right--; rect.bottom--;
|
||||
}
|
||||
pDC->SetTextColor(TextClr);
|
||||
}
|
||||
|
||||
// Draw lines only when wanted
|
||||
if (IsFixed() && pGrid->GetGridLines() != GVL_NONE)
|
||||
{
|
||||
CCellID FocusCell = pGrid->GetFocusCell();
|
||||
|
||||
// As above, always show current location even in list mode so
|
||||
// that we know where the cursor is at.
|
||||
BOOL bHiliteFixed = pGrid->GetTrackFocusCell() && pGrid->IsValid(FocusCell) &&
|
||||
(FocusCell.row == nRow || FocusCell.col == nCol);
|
||||
|
||||
// If this fixed cell is on the same row/col as the focus cell,
|
||||
// highlight it.
|
||||
if (bHiliteFixed)
|
||||
{
|
||||
rect.right++; rect.bottom++;
|
||||
pDC->DrawEdge(rect, BDR_SUNKENINNER /*EDGE_RAISED*/, BF_RECT);
|
||||
rect.DeflateRect(1,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
CPen lightpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DHIGHLIGHT)),
|
||||
darkpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DDKSHADOW)),
|
||||
*pOldPen = pDC->GetCurrentPen();
|
||||
|
||||
pDC->SelectObject(&lightpen);
|
||||
pDC->MoveTo(rect.right, rect.top);
|
||||
pDC->LineTo(rect.left, rect.top);
|
||||
pDC->LineTo(rect.left, rect.bottom);
|
||||
|
||||
pDC->SelectObject(&darkpen);
|
||||
pDC->MoveTo(rect.right, rect.top);
|
||||
pDC->LineTo(rect.right, rect.bottom);
|
||||
pDC->LineTo(rect.left, rect.bottom);
|
||||
|
||||
pDC->SelectObject(pOldPen);
|
||||
rect.DeflateRect(1,1);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw Text and image
|
||||
#if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
|
||||
if (!pDC->m_bPrinting)
|
||||
#endif
|
||||
{
|
||||
CFont *pFont = GetFontObject();
|
||||
ASSERT(pFont);
|
||||
if (pFont)
|
||||
pDC->SelectObject(pFont);
|
||||
}
|
||||
|
||||
rect.DeflateRect(GetMargin(), 0);
|
||||
|
||||
if (pGrid->GetImageList() && GetImage() >= 0)
|
||||
{
|
||||
IMAGEINFO Info;
|
||||
if (pGrid->GetImageList()->GetImageInfo(GetImage(), &Info))
|
||||
{
|
||||
// would like to use a clipping region but seems to have issue
|
||||
// working with CMemDC directly. Instead, don't display image
|
||||
// if any part of it cut-off
|
||||
//
|
||||
// CRgn rgn;
|
||||
// rgn.CreateRectRgnIndirect(rect);
|
||||
// pDC->SelectClipRgn(&rgn);
|
||||
// rgn.DeleteObject();
|
||||
|
||||
int nImageWidth = Info.rcImage.right-Info.rcImage.left+1;
|
||||
int nImageHeight = Info.rcImage.bottom-Info.rcImage.top+1;
|
||||
|
||||
if( nImageWidth + rect.left <= rect.right + (int)(2*GetMargin())
|
||||
&& nImageHeight + rect.top <= rect.bottom + (int)(2*GetMargin()) )
|
||||
{
|
||||
pGrid->GetImageList()->Draw(pDC, GetImage(), rect.TopLeft(), ILD_NORMAL);
|
||||
}
|
||||
|
||||
//rect.left += nImageWidth+GetMargin();
|
||||
}
|
||||
}
|
||||
|
||||
// Draw sort arrow
|
||||
if (pGrid->GetSortColumn() == nCol && nRow == 0)
|
||||
{
|
||||
CSize size = pDC->GetTextExtent(_T("M"));
|
||||
int nOffset = 2;
|
||||
|
||||
// Base the size of the triangle on the smaller of the column
|
||||
// height or text height with a slight offset top and bottom.
|
||||
// Otherwise, it can get drawn outside the bounds of the cell.
|
||||
size.cy -= (nOffset * 2);
|
||||
|
||||
if (size.cy >= rect.Height())
|
||||
size.cy = rect.Height() - (nOffset * 2);
|
||||
|
||||
size.cx = size.cy; // Make the dimensions square
|
||||
|
||||
// Kludge for vertical text
|
||||
BOOL bVertical = (GetFont()->lfEscapement == 900);
|
||||
|
||||
// Only draw if it'll fit!
|
||||
if (size.cx + rect.left < rect.right + (int)(2*GetMargin()))
|
||||
{
|
||||
int nTriangleBase = rect.bottom - nOffset - size.cy; // Triangle bottom right
|
||||
//int nTriangleBase = (rect.top + rect.bottom - size.cy)/2; // Triangle middle right
|
||||
//int nTriangleBase = rect.top + nOffset; // Triangle top right
|
||||
|
||||
//int nTriangleLeft = rect.right - size.cx; // Triangle RHS
|
||||
//int nTriangleLeft = (rect.right + rect.left - size.cx)/2; // Triangle middle
|
||||
//int nTriangleLeft = rect.left; // Triangle LHS
|
||||
|
||||
int nTriangleLeft;
|
||||
if (bVertical)
|
||||
nTriangleLeft = (rect.right + rect.left - size.cx)/2; // Triangle middle
|
||||
else
|
||||
nTriangleLeft = rect.right - size.cx; // Triangle RHS
|
||||
|
||||
CPen penShadow(PS_SOLID, 0, ::GetSysColor(COLOR_3DSHADOW));
|
||||
CPen penLight(PS_SOLID, 0, ::GetSysColor(COLOR_3DHILIGHT));
|
||||
if (pGrid->GetSortAscending())
|
||||
{
|
||||
// Draw triangle pointing upwards
|
||||
CPen *pOldPen = (CPen*) pDC->SelectObject(&penLight);
|
||||
pDC->MoveTo( nTriangleLeft + 1, nTriangleBase + size.cy + 1);
|
||||
pDC->LineTo( nTriangleLeft + (size.cx / 2) + 1, nTriangleBase + 1 );
|
||||
pDC->LineTo( nTriangleLeft + size.cx + 1, nTriangleBase + size.cy + 1);
|
||||
pDC->LineTo( nTriangleLeft + 1, nTriangleBase + size.cy + 1);
|
||||
|
||||
pDC->SelectObject(&penShadow);
|
||||
pDC->MoveTo( nTriangleLeft, nTriangleBase + size.cy );
|
||||
pDC->LineTo( nTriangleLeft + (size.cx / 2), nTriangleBase );
|
||||
pDC->LineTo( nTriangleLeft + size.cx, nTriangleBase + size.cy );
|
||||
pDC->LineTo( nTriangleLeft, nTriangleBase + size.cy );
|
||||
pDC->SelectObject(pOldPen);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw triangle pointing downwards
|
||||
CPen *pOldPen = (CPen*) pDC->SelectObject(&penLight);
|
||||
pDC->MoveTo( nTriangleLeft + 1, nTriangleBase + 1 );
|
||||
pDC->LineTo( nTriangleLeft + (size.cx / 2) + 1, nTriangleBase + size.cy + 1 );
|
||||
pDC->LineTo( nTriangleLeft + size.cx + 1, nTriangleBase + 1 );
|
||||
pDC->LineTo( nTriangleLeft + 1, nTriangleBase + 1 );
|
||||
|
||||
pDC->SelectObject(&penShadow);
|
||||
pDC->MoveTo( nTriangleLeft, nTriangleBase );
|
||||
pDC->LineTo( nTriangleLeft + (size.cx / 2), nTriangleBase + size.cy );
|
||||
pDC->LineTo( nTriangleLeft + size.cx, nTriangleBase );
|
||||
pDC->LineTo( nTriangleLeft, nTriangleBase );
|
||||
pDC->SelectObject(pOldPen);
|
||||
}
|
||||
|
||||
if (!bVertical)
|
||||
rect.right -= size.cy;
|
||||
}
|
||||
}
|
||||
|
||||
// We want to see '&' characters so use DT_NOPREFIX
|
||||
GetTextRect(rect);
|
||||
DrawText(pDC->m_hDC, GetText(), -1, rect, GetFormat() | DT_NOPREFIX);
|
||||
|
||||
pDC->RestoreDC(nSavedDC);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGridCellBase Mouse and Cursor events
|
||||
|
||||
// Not yet implemented
|
||||
void CGridCellBase::OnMouseEnter()
|
||||
{
|
||||
TRACE0("Mouse entered cell\n");
|
||||
}
|
||||
|
||||
void CGridCellBase::OnMouseOver()
|
||||
{
|
||||
//TRACE0("Mouse over cell\n");
|
||||
}
|
||||
|
||||
// Not Yet Implemented
|
||||
void CGridCellBase::OnMouseLeave()
|
||||
{
|
||||
TRACE0("Mouse left cell\n");
|
||||
}
|
||||
|
||||
void CGridCellBase::OnClick( CPoint PointCellRelative)
|
||||
{
|
||||
UNUSED_ALWAYS(PointCellRelative);
|
||||
TRACE2("Mouse Left btn up in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y);
|
||||
}
|
||||
|
||||
void CGridCellBase::OnClickDown( CPoint PointCellRelative)
|
||||
{
|
||||
UNUSED_ALWAYS(PointCellRelative);
|
||||
TRACE2("Mouse Left btn down in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y);
|
||||
}
|
||||
|
||||
void CGridCellBase::OnRClick( CPoint PointCellRelative)
|
||||
{
|
||||
UNUSED_ALWAYS(PointCellRelative);
|
||||
TRACE2("Mouse right-clicked in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y);
|
||||
}
|
||||
|
||||
void CGridCellBase::OnDblClick( CPoint PointCellRelative)
|
||||
{
|
||||
UNUSED_ALWAYS(PointCellRelative);
|
||||
TRACE2("Mouse double-clicked in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y);
|
||||
}
|
||||
|
||||
// Return TRUE if you set the cursor
|
||||
BOOL CGridCellBase::OnSetCursor()
|
||||
{
|
||||
#ifndef _WIN32_WCE_NO_CURSOR
|
||||
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGridCellBase editing
|
||||
|
||||
void CGridCellBase::OnEndEdit()
|
||||
{
|
||||
ASSERT( FALSE);
|
||||
}
|
||||
|
||||
BOOL CGridCellBase::ValidateEdit(LPCTSTR str)
|
||||
{
|
||||
UNUSED_ALWAYS(str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGridCellBase Sizing
|
||||
|
||||
BOOL CGridCellBase::GetTextRect( LPRECT pRect) // i/o: i=dims of cell rect; o=dims of text rect
|
||||
{
|
||||
if (GetImage() >= 0)
|
||||
{
|
||||
IMAGEINFO Info;
|
||||
|
||||
CGridCtrl* pGrid = GetGrid();
|
||||
CImageList* pImageList = pGrid->GetImageList();
|
||||
|
||||
if (pImageList && pImageList->GetImageInfo( GetImage(), &Info))
|
||||
{
|
||||
int nImageWidth = Info.rcImage.right-Info.rcImage.left+1;
|
||||
pRect->left += nImageWidth + GetMargin();
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// By default this uses the selected font (which is a bigger font)
|
||||
CSize CGridCellBase::GetTextExtent(LPCTSTR szText, CDC* pDC /*= NULL*/)
|
||||
{
|
||||
CGridCtrl* pGrid = GetGrid();
|
||||
ASSERT(pGrid);
|
||||
|
||||
BOOL bReleaseDC = FALSE;
|
||||
if (pDC == NULL || szText == NULL)
|
||||
{
|
||||
if (szText)
|
||||
pDC = pGrid->GetDC();
|
||||
if (pDC == NULL || szText == NULL)
|
||||
{
|
||||
CGridDefaultCell* pDefCell = (CGridDefaultCell*) GetDefaultCell();
|
||||
ASSERT(pDefCell);
|
||||
return CSize(pDefCell->GetWidth(), pDefCell->GetHeight());
|
||||
}
|
||||
bReleaseDC = TRUE;
|
||||
}
|
||||
|
||||
CFont *pOldFont = NULL,
|
||||
*pFont = GetFontObject();
|
||||
if (pFont)
|
||||
pOldFont = pDC->SelectObject(pFont);
|
||||
|
||||
CSize size;
|
||||
int nFormat = GetFormat();
|
||||
|
||||
// If the cell is a multiline cell, then use the width of the cell
|
||||
// to get the height
|
||||
if ((nFormat & DT_WORDBREAK) && !(nFormat & DT_SINGLELINE))
|
||||
{
|
||||
CString str = szText;
|
||||
int nMaxWidth = 0;
|
||||
while (TRUE)
|
||||
{
|
||||
int nPos = str.Find(_T('\n'));
|
||||
CString TempStr = (nPos < 0)? str : str.Left(nPos);
|
||||
int nTempWidth = pDC->GetTextExtent(TempStr).cx;
|
||||
if (nTempWidth > nMaxWidth)
|
||||
nMaxWidth = nTempWidth;
|
||||
|
||||
if (nPos < 0)
|
||||
break;
|
||||
str = str.Mid(nPos + 1); // Bug fix by Thomas Steinborn
|
||||
}
|
||||
|
||||
CRect rect;
|
||||
rect.SetRect(0,0, nMaxWidth+1, 0);
|
||||
pDC->DrawText(szText, -1, rect, nFormat | DT_CALCRECT);
|
||||
size = rect.Size();
|
||||
}
|
||||
else
|
||||
size = pDC->GetTextExtent(szText, _tcslen(szText));
|
||||
|
||||
TEXTMETRIC tm;
|
||||
pDC->GetTextMetrics(&tm);
|
||||
size.cx += (tm.tmOverhang);
|
||||
|
||||
if (pOldFont)
|
||||
pDC->SelectObject(pOldFont);
|
||||
|
||||
size += CSize(4*GetMargin(), 2*GetMargin());
|
||||
|
||||
// Kludge for vertical text
|
||||
LOGFONT *pLF = GetFont();
|
||||
if (pLF->lfEscapement == 900 || pLF->lfEscapement == -900)
|
||||
{
|
||||
int nTemp = size.cx;
|
||||
size.cx = size.cy;
|
||||
size.cy = nTemp;
|
||||
size += CSize(0, 4*GetMargin());
|
||||
}
|
||||
|
||||
if (bReleaseDC)
|
||||
pGrid->ReleaseDC(pDC);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
CSize CGridCellBase::GetCellExtent(CDC* pDC)
|
||||
{
|
||||
CSize size = GetTextExtent(GetText(), pDC);
|
||||
CSize ImageSize(0,0);
|
||||
|
||||
int nImage = GetImage();
|
||||
if (nImage >= 0)
|
||||
{
|
||||
CGridCtrl* pGrid = GetGrid();
|
||||
ASSERT(pGrid);
|
||||
|
||||
if (pGrid->GetImageList())
|
||||
{
|
||||
IMAGEINFO Info;
|
||||
if (pGrid->GetImageList()->GetImageInfo(nImage, &Info))
|
||||
ImageSize = CSize(Info.rcImage.right-Info.rcImage.left+1,
|
||||
Info.rcImage.bottom-Info.rcImage.top+1);
|
||||
}
|
||||
}
|
||||
|
||||
return CSize(size.cx + ImageSize.cx, max(size.cy, ImageSize.cy));
|
||||
}
|
||||
|
||||
// EFW - Added to print cells so that grids that use different colors are
|
||||
// printed correctly.
|
||||
BOOL CGridCellBase::PrintCell(CDC* pDC, int /*nRow*/, int /*nCol*/, CRect rect)
|
||||
{
|
||||
#if defined(_WIN32_WCE_NO_PRINTING) || defined(GRIDCONTROL_NO_PRINTING)
|
||||
return FALSE;
|
||||
#else
|
||||
COLORREF crFG, crBG;
|
||||
GV_ITEM Item;
|
||||
|
||||
CGridCtrl* pGrid = GetGrid();
|
||||
if (!pGrid || !pDC)
|
||||
return FALSE;
|
||||
|
||||
if( rect.Width() <= 0
|
||||
|| rect.Height() <= 0) // prevents imagelist item from drawing even
|
||||
return FALSE; // though cell is hidden
|
||||
|
||||
int nSavedDC = pDC->SaveDC();
|
||||
|
||||
pDC->SetBkMode(TRANSPARENT);
|
||||
|
||||
if (pGrid->GetShadedPrintOut())
|
||||
{
|
||||
// Get the default cell implementation for this kind of cell. We use it if this cell
|
||||
// has anything marked as "default"
|
||||
CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell();
|
||||
if (!pDefaultCell)
|
||||
return FALSE;
|
||||
|
||||
// Use custom color if it doesn't match the default color and the
|
||||
// default grid background color. If not, leave it alone.
|
||||
if(IsFixed())
|
||||
crBG = (GetBackClr() != CLR_DEFAULT) ? GetBackClr() : pDefaultCell->GetBackClr();
|
||||
else
|
||||
crBG = (GetBackClr() != CLR_DEFAULT && GetBackClr() != pDefaultCell->GetBackClr()) ?
|
||||
GetBackClr() : CLR_DEFAULT;
|
||||
|
||||
// Use custom color if the background is different or if it doesn't
|
||||
// match the default color and the default grid text color.
|
||||
if(IsFixed())
|
||||
crFG = (GetBackClr() != CLR_DEFAULT) ? GetTextClr() : pDefaultCell->GetTextClr();
|
||||
else
|
||||
crFG = (GetBackClr() != CLR_DEFAULT) ? GetTextClr() : pDefaultCell->GetTextClr();
|
||||
|
||||
// If not printing on a color printer, adjust the foreground color
|
||||
// to a gray scale if the background color isn't used so that all
|
||||
// colors will be visible. If not, some colors turn to solid black
|
||||
// or white when printed and may not show up. This may be caused by
|
||||
// coarse dithering by the printer driver too (see image note below).
|
||||
if(pDC->GetDeviceCaps(NUMCOLORS) == 2 && crBG == CLR_DEFAULT)
|
||||
crFG = RGB(GetRValue(crFG) * 0.30, GetGValue(crFG) * 0.59,
|
||||
GetBValue(crFG) * 0.11);
|
||||
|
||||
// Only erase the background if the color is not the default
|
||||
// grid background color.
|
||||
if(crBG != CLR_DEFAULT)
|
||||
{
|
||||
CBrush brush(crBG);
|
||||
rect.right++; rect.bottom++;
|
||||
pDC->FillRect(rect, &brush);
|
||||
rect.right--; rect.bottom--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
crBG = CLR_DEFAULT;
|
||||
crFG = RGB(0, 0, 0);
|
||||
}
|
||||
|
||||
pDC->SetTextColor(crFG);
|
||||
|
||||
CFont *pFont = GetFontObject();
|
||||
if (pFont)
|
||||
pDC->SelectObject(pFont);
|
||||
|
||||
/*
|
||||
// ***************************************************
|
||||
// Disabled - if you need this functionality then you'll need to rewrite.
|
||||
// Create the appropriate font and select into DC.
|
||||
CFont Font;
|
||||
// Bold the fixed cells if not shading the print out. Use italic
|
||||
// font it it is enabled.
|
||||
const LOGFONT* plfFont = GetFont();
|
||||
if(IsFixed() && !pGrid->GetShadedPrintOut())
|
||||
{
|
||||
Font.CreateFont(plfFont->lfHeight, 0, 0, 0, FW_BOLD, plfFont->lfItalic, 0, 0,
|
||||
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||
#ifndef _WIN32_WCE
|
||||
PROOF_QUALITY,
|
||||
#else
|
||||
DEFAULT_QUALITY,
|
||||
#endif
|
||||
VARIABLE_PITCH | FF_SWISS, plfFont->lfFaceName);
|
||||
}
|
||||
else
|
||||
Font.CreateFontIndirect(plfFont);
|
||||
|
||||
pDC->SelectObject(&Font);
|
||||
// ***************************************************
|
||||
*/
|
||||
|
||||
// Draw lines only when wanted on fixed cells. Normal cell grid lines
|
||||
// are handled in OnPrint.
|
||||
if(pGrid->GetGridLines() != GVL_NONE && IsFixed())
|
||||
{
|
||||
CPen lightpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DHIGHLIGHT)),
|
||||
darkpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DDKSHADOW)),
|
||||
*pOldPen = pDC->GetCurrentPen();
|
||||
|
||||
pDC->SelectObject(&lightpen);
|
||||
pDC->MoveTo(rect.right, rect.top);
|
||||
pDC->LineTo(rect.left, rect.top);
|
||||
pDC->LineTo(rect.left, rect.bottom);
|
||||
|
||||
pDC->SelectObject(&darkpen);
|
||||
pDC->MoveTo(rect.right, rect.top);
|
||||
pDC->LineTo(rect.right, rect.bottom);
|
||||
pDC->LineTo(rect.left, rect.bottom);
|
||||
|
||||
rect.DeflateRect(1,1);
|
||||
pDC->SelectObject(pOldPen);
|
||||
}
|
||||
|
||||
rect.DeflateRect(GetMargin(), 0);
|
||||
|
||||
if(pGrid->GetImageList() && GetImage() >= 0)
|
||||
{
|
||||
// NOTE: If your printed images look like fuzzy garbage, check the
|
||||
// settings on your printer driver. If it's using coarse
|
||||
// dithering and/or vector graphics, they may print wrong.
|
||||
// Changing to fine dithering and raster graphics makes them
|
||||
// print properly. My HP 4L had that problem.
|
||||
|
||||
IMAGEINFO Info;
|
||||
if(pGrid->GetImageList()->GetImageInfo(GetImage(), &Info))
|
||||
{
|
||||
int nImageWidth = Info.rcImage.right-Info.rcImage.left;
|
||||
pGrid->GetImageList()->Draw(pDC, GetImage(), rect.TopLeft(), ILD_NORMAL);
|
||||
rect.left += nImageWidth+GetMargin();
|
||||
}
|
||||
}
|
||||
|
||||
// Draw without clipping so as not to lose text when printed for real
|
||||
// DT_NOCLIP removed 01.01.01. Slower, but who cares - we are printing!
|
||||
DrawText(pDC->m_hDC, GetText(), -1, rect,
|
||||
GetFormat() | /*DT_NOCLIP | */ DT_NOPREFIX);
|
||||
|
||||
pDC->RestoreDC(nSavedDC);
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Callable by derived classes, only
|
||||
*****************************************************************************/
|
||||
LRESULT CGridCellBase::SendMessageToParent(int nRow, int nCol, int nMessage)
|
||||
{
|
||||
CGridCtrl* pGrid = GetGrid();
|
||||
if( pGrid)
|
||||
return pGrid->SendMessageToParent(nRow, nCol, nMessage);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
172
Server/ManageTool/GridControl/GridCtrl_src/GridCellBase.h
Normal file
172
Server/ManageTool/GridControl/GridCtrl_src/GridCellBase.h
Normal file
@@ -0,0 +1,172 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GridCellBase.h : header file
|
||||
//
|
||||
// MFC Grid Control - Grid cell base class header file
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.22+
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_GRIDCELLBASE_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
|
||||
#define AFX_GRIDCELLBASE_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
class CGridCtrl;
|
||||
|
||||
// Cell states
|
||||
#define GVIS_FOCUSED 0x0001
|
||||
#define GVIS_SELECTED 0x0002
|
||||
#define GVIS_DROPHILITED 0x0004
|
||||
#define GVIS_READONLY 0x0008
|
||||
#define GVIS_FIXED 0x0010
|
||||
#define GVIS_FIXEDROW 0x0020
|
||||
#define GVIS_FIXEDCOL 0x0040
|
||||
#define GVIS_MODIFIED 0x0080
|
||||
|
||||
// Cell data mask
|
||||
#define GVIF_TEXT LVIF_TEXT
|
||||
#define GVIF_IMAGE LVIF_IMAGE
|
||||
#define GVIF_PARAM LVIF_PARAM
|
||||
#define GVIF_STATE LVIF_STATE
|
||||
#define GVIF_BKCLR (GVIF_STATE<<1)
|
||||
#define GVIF_FGCLR (GVIF_STATE<<2)
|
||||
#define GVIF_FORMAT (GVIF_STATE<<3)
|
||||
#define GVIF_FONT (GVIF_STATE<<4)
|
||||
#define GVIF_MARGIN (GVIF_STATE<<5)
|
||||
#define GVIF_ALL (GVIF_TEXT|GVIF_IMAGE|GVIF_PARAM|GVIF_STATE|GVIF_BKCLR|GVIF_FGCLR| \
|
||||
GVIF_FORMAT|GVIF_FONT|GVIF_MARGIN)
|
||||
|
||||
// Used for Get/SetItem calls.
|
||||
typedef struct _GV_ITEM {
|
||||
int row,col; // Row and Column of item
|
||||
UINT mask; // Mask for use in getting/setting cell data
|
||||
UINT nState; // cell state (focus/hilighted etc)
|
||||
DWORD nFormat; // Format of cell
|
||||
int iImage; // index of the list view item’s icon
|
||||
COLORREF crBkClr; // Background colour (or CLR_DEFAULT)
|
||||
COLORREF crFgClr; // Forground colour (or CLR_DEFAULT)
|
||||
LPARAM lParam; // 32-bit value to associate with item
|
||||
LOGFONT lfFont; // Cell font
|
||||
UINT nMargin; // Internal cell margin
|
||||
CString strText; // Text in cell
|
||||
} GV_ITEM;
|
||||
|
||||
|
||||
// Each cell contains one of these. Fields "row" and "column" are not stored since we
|
||||
// will usually have acces to them in other ways, and they are an extra 8 bytes per
|
||||
// cell that is probably unnecessary.
|
||||
|
||||
class AFX_EXT_CLASS CGridCellBase : public CObject
|
||||
{
|
||||
friend class CGridCtrl;
|
||||
DECLARE_DYNAMIC(CGridCellBase)
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CGridCellBase();
|
||||
virtual ~CGridCellBase();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
virtual void SetText(LPCTSTR /* szText */) = 0 ;
|
||||
virtual void SetImage(int /* nImage */) = 0 ;
|
||||
virtual void SetData(LPARAM /* lParam */) = 0 ;
|
||||
virtual void SetState(DWORD nState) { m_nState = nState; }
|
||||
virtual void SetFormat(DWORD /* nFormat */) = 0 ;
|
||||
virtual void SetTextClr(COLORREF /* clr */) = 0 ;
|
||||
virtual void SetBackClr(COLORREF /* clr */) = 0 ;
|
||||
virtual void SetFont(const LOGFONT* /* plf */) = 0 ;
|
||||
virtual void SetMargin( UINT /* nMargin */) = 0 ;
|
||||
virtual void SetGrid(CGridCtrl* /* pGrid */) = 0 ;
|
||||
virtual void SetCoords( int /* nRow */, int /* nCol */) = 0 ;
|
||||
|
||||
virtual LPCTSTR GetText() const = 0 ;
|
||||
virtual LPCTSTR GetTipText() const { return GetText(); } // may override TitleTip return
|
||||
virtual int GetImage() const = 0 ;
|
||||
virtual LPARAM GetData() const = 0 ;
|
||||
virtual DWORD GetState() const { return m_nState; }
|
||||
virtual DWORD GetFormat() const = 0 ;
|
||||
virtual COLORREF GetTextClr() const = 0 ;
|
||||
virtual COLORREF GetBackClr() const = 0 ;
|
||||
virtual LOGFONT * GetFont() const = 0 ;
|
||||
virtual CFont * GetFontObject() const = 0 ;
|
||||
virtual CGridCtrl* GetGrid() const = 0 ;
|
||||
virtual CWnd * GetEditWnd() const = 0 ;
|
||||
virtual UINT GetMargin() const = 0 ;
|
||||
|
||||
virtual CGridCellBase* GetDefaultCell() const;
|
||||
|
||||
virtual BOOL IsDefaultFont() const = 0 ;
|
||||
virtual BOOL IsEditing() const = 0 ;
|
||||
virtual BOOL IsFocused() const { return (m_nState & GVIS_FOCUSED); }
|
||||
virtual BOOL IsFixed() const { return (m_nState & GVIS_FIXED); }
|
||||
virtual BOOL IsFixedCol() const { return (m_nState & GVIS_FIXEDCOL); }
|
||||
virtual BOOL IsFixedRow() const { return (m_nState & GVIS_FIXEDROW); }
|
||||
virtual BOOL IsSelected() const { return (m_nState & GVIS_SELECTED); }
|
||||
virtual BOOL IsReadOnly() const { return (m_nState & GVIS_READONLY); }
|
||||
virtual BOOL IsModified() const { return (m_nState & GVIS_MODIFIED); }
|
||||
virtual BOOL IsDropHighlighted() const { return (m_nState & GVIS_DROPHILITED); }
|
||||
|
||||
// Operators
|
||||
public:
|
||||
virtual void operator=(const CGridCellBase& cell);
|
||||
|
||||
// Operations
|
||||
public:
|
||||
virtual void Reset();
|
||||
|
||||
virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd = TRUE);
|
||||
virtual BOOL GetTextRect( LPRECT pRect); // i/o: i=dims of cell rect; o=dims of text rect
|
||||
virtual BOOL GetTipTextRect( LPRECT pRect) { return GetTextRect( pRect); } // may override for btns, etc.
|
||||
virtual CSize GetTextExtent(LPCTSTR str, CDC* pDC = NULL);
|
||||
virtual CSize GetCellExtent(CDC* pDC);
|
||||
|
||||
// Editing
|
||||
virtual BOOL Edit( int /* nRow */, int /* nCol */, CRect /* rect */, CPoint /* point */,
|
||||
UINT /* nID */, UINT /* nChar */) { ASSERT( FALSE); return FALSE;}
|
||||
virtual BOOL ValidateEdit(LPCTSTR str);
|
||||
virtual void EndEdit() {}
|
||||
|
||||
// EFW - Added to print cells properly
|
||||
virtual BOOL PrintCell(CDC* pDC, int nRow, int nCol, CRect rect);
|
||||
|
||||
// add additional protected grid members required of cells
|
||||
LRESULT SendMessageToParent(int nRow, int nCol, int nMessage);
|
||||
|
||||
protected:
|
||||
virtual void OnEndEdit();
|
||||
virtual void OnMouseEnter();
|
||||
virtual void OnMouseOver();
|
||||
virtual void OnMouseLeave();
|
||||
virtual void OnClick( CPoint PointCellRelative);
|
||||
virtual void OnClickDown( CPoint PointCellRelative);
|
||||
virtual void OnRClick( CPoint PointCellRelative);
|
||||
virtual void OnDblClick( CPoint PointCellRelative);
|
||||
virtual BOOL OnSetCursor();
|
||||
|
||||
protected:
|
||||
DWORD m_nState; // Cell state (selected/focus etc)
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_GRIDCELLBASE_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
|
||||
7297
Server/ManageTool/GridControl/GridCtrl_src/GridCtrl.cpp
Normal file
7297
Server/ManageTool/GridControl/GridCtrl_src/GridCtrl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
872
Server/ManageTool/GridControl/GridCtrl_src/GridCtrl.h
Normal file
872
Server/ManageTool/GridControl/GridCtrl_src/GridCtrl.h
Normal file
@@ -0,0 +1,872 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GridCtrl.h : header file
|
||||
//
|
||||
// MFC Grid Control - main header
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.20+
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_GRIDCTRL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
|
||||
#define AFX_GRIDCTRL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#include "CellRange.h"
|
||||
#include "GridCell.h"
|
||||
#include <afxtempl.h>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Defines - these determine the features (and the final size) of the final code
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//#define GRIDCONTROL_NO_TITLETIPS // Do not use titletips for cells with large data
|
||||
//#define GRIDCONTROL_NO_DRAGDROP // Do not use OLE drag and drop
|
||||
//#define GRIDCONTROL_NO_CLIPBOARD // Do not use clipboard routines
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
# define GRIDCONTROL_NO_TITLETIPS // Do not use titletips for cells with large data
|
||||
# define GRIDCONTROL_NO_DRAGDROP // Do not use OLE drag and drop
|
||||
# define GRIDCONTROL_NO_CLIPBOARD // Do not use clipboard routines
|
||||
# define GRIDCONTROL_NO_PRINTING // Do not use printing routines
|
||||
# ifdef WCE_NO_PRINTING // Older versions of CE had different #def's
|
||||
# define _WIN32_WCE_NO_PRINTING
|
||||
# endif
|
||||
# ifdef WCE_NO_CURSOR
|
||||
# define _WIN32_WCE_NO_CURSOR
|
||||
# endif
|
||||
#endif // _WIN32_WCE
|
||||
|
||||
// Use this as the classname when inserting this control as a custom control
|
||||
// in the MSVC++ dialog editor
|
||||
#define GRIDCTRL_CLASSNAME _T("MFCGridCtrl") // Window class name
|
||||
#define IDC_INPLACE_CONTROL 8 // ID of inplace edit controls
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Conditional includes
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GRIDCONTROL_NO_TITLETIPS
|
||||
# include "TitleTip.h"
|
||||
#endif
|
||||
|
||||
#ifndef GRIDCONTROL_NO_DRAGDROP
|
||||
# include "GridDropTarget.h"
|
||||
# undef GRIDCONTROL_NO_CLIPBOARD // Force clipboard functions on
|
||||
#endif
|
||||
|
||||
#ifndef GRIDCONTROL_NO_CLIPBOARD
|
||||
# include <afxole.h>
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Helper functions
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Handy functions
|
||||
#define IsSHIFTpressed() ( (GetKeyState(VK_SHIFT) & (1 << (sizeof(SHORT)*8-1))) != 0 )
|
||||
#define IsCTRLpressed() ( (GetKeyState(VK_CONTROL) & (1 << (sizeof(SHORT)*8-1))) != 0 )
|
||||
|
||||
// Backwards compatibility for pre 2.20 grid versions
|
||||
#define DDX_GridControl(pDX, nIDC, rControl) DDX_Control(pDX, nIDC, rControl)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Structures
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This structure sent to Grid's parent in a WM_NOTIFY message
|
||||
typedef struct tagNM_GRIDVIEW {
|
||||
NMHDR hdr;
|
||||
int iRow;
|
||||
int iColumn;
|
||||
} NM_GRIDVIEW;
|
||||
|
||||
// This is sent to the Grid from child in-place edit controls
|
||||
typedef struct tagGV_DISPINFO {
|
||||
NMHDR hdr;
|
||||
GV_ITEM item;
|
||||
} GV_DISPINFO;
|
||||
|
||||
// This is sent to the Grid from child in-place edit controls
|
||||
typedef struct tagGV_CACHEHINT {
|
||||
NMHDR hdr;
|
||||
CCellRange range;
|
||||
} GV_CACHEHINT;
|
||||
|
||||
// storage typedef for each row in the grid
|
||||
typedef CTypedPtrArray<CObArray, CGridCellBase*> GRID_ROW;
|
||||
|
||||
// For virtual mode callback
|
||||
typedef BOOL (CALLBACK* GRIDCALLBACK)(GV_DISPINFO *, LPARAM);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Defines
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Grid line/scrollbar selection
|
||||
#define GVL_NONE 0L // Neither
|
||||
#define GVL_HORZ 1L // Horizontal line or scrollbar
|
||||
#define GVL_VERT 2L // Vertical line or scrollbar
|
||||
#define GVL_BOTH 3L // Both
|
||||
|
||||
// Autosizing option
|
||||
#define GVS_DEFAULT 0
|
||||
#define GVS_HEADER 1 // Size using column fixed cells data only
|
||||
#define GVS_DATA 2 // Size using column non-fixed cells data only
|
||||
#define GVS_BOTH 3 // Size using column fixed and non-fixed
|
||||
|
||||
// Cell Searching options
|
||||
#define GVNI_FOCUSED 0x0001
|
||||
#define GVNI_SELECTED 0x0002
|
||||
#define GVNI_DROPHILITED 0x0004
|
||||
#define GVNI_READONLY 0x0008
|
||||
#define GVNI_FIXED 0x0010
|
||||
#define GVNI_MODIFIED 0x0020
|
||||
|
||||
#define GVNI_ABOVE LVNI_ABOVE
|
||||
#define GVNI_BELOW LVNI_BELOW
|
||||
#define GVNI_TOLEFT LVNI_TOLEFT
|
||||
#define GVNI_TORIGHT LVNI_TORIGHT
|
||||
#define GVNI_ALL (LVNI_BELOW|LVNI_TORIGHT|LVNI_TOLEFT)
|
||||
#define GVNI_AREA (LVNI_BELOW|LVNI_TORIGHT)
|
||||
|
||||
// Hit test values (not yet implemented)
|
||||
#define GVHT_DATA 0x0000
|
||||
#define GVHT_TOPLEFT 0x0001
|
||||
#define GVHT_COLHDR 0x0002
|
||||
#define GVHT_ROWHDR 0x0004
|
||||
#define GVHT_COLSIZER 0x0008
|
||||
#define GVHT_ROWSIZER 0x0010
|
||||
#define GVHT_LEFT 0x0020
|
||||
#define GVHT_RIGHT 0x0040
|
||||
#define GVHT_ABOVE 0x0080
|
||||
#define GVHT_BELOW 0x0100
|
||||
|
||||
// Messages sent to the grid's parent (More will be added in future)
|
||||
#define GVN_BEGINDRAG LVN_BEGINDRAG // LVN_FIRST-9
|
||||
#define GVN_BEGINLABELEDIT LVN_BEGINLABELEDIT // LVN_FIRST-5
|
||||
#define GVN_BEGINRDRAG LVN_BEGINRDRAG
|
||||
#define GVN_COLUMNCLICK LVN_COLUMNCLICK
|
||||
#define GVN_DELETEITEM LVN_DELETEITEM
|
||||
#define GVN_ENDLABELEDIT LVN_ENDLABELEDIT // LVN_FIRST-6
|
||||
#define GVN_SELCHANGING LVN_ITEMCHANGING
|
||||
#define GVN_SELCHANGED LVN_ITEMCHANGED
|
||||
#define GVN_GETDISPINFO LVN_GETDISPINFO
|
||||
#define GVN_ODCACHEHINT LVN_ODCACHEHINT
|
||||
|
||||
class CGridCtrl;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGridCtrl window
|
||||
|
||||
class AFX_EXT_CLASS CGridCtrl : public CWnd
|
||||
{
|
||||
DECLARE_DYNCREATE(CGridCtrl)
|
||||
friend class CGridCell;
|
||||
friend class CGridCellBase;
|
||||
|
||||
// Construction
|
||||
public:
|
||||
CGridCtrl(int nRows = 0, int nCols = 0, int nFixedRows = 0, int nFixedCols = 0);
|
||||
|
||||
BOOL Create(const RECT& rect, CWnd* parent, UINT nID,
|
||||
DWORD dwStyle = WS_CHILD | WS_BORDER | WS_TABSTOP | WS_VISIBLE);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Attributes
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
int GetRowCount() const { return m_nRows; }
|
||||
int GetColumnCount() const { return m_nCols; }
|
||||
int GetFixedRowCount() const { return m_nFixedRows; }
|
||||
int GetFixedColumnCount() const { return m_nFixedCols; }
|
||||
BOOL SetRowCount(int nRows = 10);
|
||||
BOOL SetColumnCount(int nCols = 10);
|
||||
BOOL SetFixedRowCount(int nFixedRows = 1);
|
||||
BOOL SetFixedColumnCount(int nFixedCols = 1);
|
||||
|
||||
int GetRowHeight(int nRow) const;
|
||||
BOOL SetRowHeight(int row, int height);
|
||||
int GetColumnWidth(int nCol) const;
|
||||
BOOL SetColumnWidth(int col, int width);
|
||||
|
||||
BOOL GetCellOrigin(int nRow, int nCol, LPPOINT p);
|
||||
BOOL GetCellOrigin(const CCellID& cell, LPPOINT p);
|
||||
BOOL GetCellRect(int nRow, int nCol, LPRECT pRect);
|
||||
BOOL GetCellRect(const CCellID& cell, LPRECT pRect);
|
||||
|
||||
BOOL GetTextRect(const CCellID& cell, LPRECT pRect);
|
||||
BOOL GetTextRect(int nRow, int nCol, LPRECT pRect);
|
||||
|
||||
CCellID GetCellFromPt(CPoint point, BOOL bAllowFixedCellCheck = TRUE);
|
||||
|
||||
int GetFixedRowHeight() const;
|
||||
int GetFixedColumnWidth() const;
|
||||
long GetVirtualWidth() const;
|
||||
long GetVirtualHeight() const;
|
||||
|
||||
CSize GetTextExtent(int nRow, int nCol, LPCTSTR str);
|
||||
// EFW - Get extent of current text in cell
|
||||
inline CSize GetCellTextExtent(int nRow, int nCol) { return GetTextExtent(nRow, nCol, GetItemText(nRow,nCol)); }
|
||||
|
||||
void SetGridBkColor(COLORREF clr) { m_crGridBkColour = clr; }
|
||||
COLORREF GetGridBkColor() const { return m_crGridBkColour; }
|
||||
void SetGridLineColor(COLORREF clr) { m_crGridLineColour = clr; }
|
||||
COLORREF GetGridLineColor() const { return m_crGridLineColour; }
|
||||
|
||||
void SetTitleTipBackClr(COLORREF clr = CLR_DEFAULT) { m_crTTipBackClr = clr; }
|
||||
COLORREF GetTitleTipBackClr() { return m_crTTipBackClr; }
|
||||
void SetTitleTipTextClr(COLORREF clr = CLR_DEFAULT) { m_crTTipTextClr = clr; }
|
||||
COLORREF GetTitleTipTextClr() { return m_crTTipTextClr; }
|
||||
|
||||
// ***************************************************************************** //
|
||||
// These have been deprecated. Use GetDefaultCell and then set the colors
|
||||
void SetTextColor(COLORREF clr) { m_cellDefault.SetTextClr(clr); }
|
||||
COLORREF GetTextColor() { return m_cellDefault.GetTextClr(); }
|
||||
void SetTextBkColor(COLORREF clr) { m_cellDefault.SetBackClr(clr); }
|
||||
COLORREF GetTextBkColor() { return m_cellDefault.GetBackClr(); }
|
||||
void SetFixedTextColor(COLORREF clr) { m_cellFixedRowDef.SetTextClr(clr);
|
||||
m_cellFixedColDef.SetTextClr(clr);
|
||||
m_cellFixedRowColDef.SetTextClr(clr); }
|
||||
COLORREF GetFixedTextColor() const { return m_cellFixedRowDef.GetTextClr(); }
|
||||
void SetFixedBkColor(COLORREF clr) { m_cellFixedRowDef.SetBackClr(clr);
|
||||
m_cellFixedColDef.SetBackClr(clr);
|
||||
m_cellFixedRowColDef.SetBackClr(clr); }
|
||||
COLORREF GetFixedBkColor() const { return m_cellFixedRowDef.GetBackClr(); }
|
||||
void SetGridColor(COLORREF clr) { SetGridLineColor(clr); }
|
||||
COLORREF GetGridColor() { return GetGridLineColor(); }
|
||||
void SetBkColor(COLORREF clr) { SetGridBkColor(clr); }
|
||||
COLORREF GetBkColor() { return GetGridBkColor(); }
|
||||
|
||||
void SetDefCellMargin( int nMargin) { m_cellDefault.SetMargin(nMargin);
|
||||
m_cellFixedRowDef.SetMargin(nMargin);
|
||||
m_cellFixedColDef.SetMargin(nMargin);
|
||||
m_cellFixedRowColDef.SetMargin(nMargin); }
|
||||
int GetDefCellMargin() const { return m_cellDefault.GetMargin(); }
|
||||
|
||||
int GetDefCellHeight() const { return m_cellDefault.GetHeight(); }
|
||||
void SetDefCellHeight(int nHeight) { m_cellDefault.SetHeight(nHeight);
|
||||
m_cellFixedRowDef.SetHeight(nHeight);
|
||||
m_cellFixedColDef.SetHeight(nHeight);
|
||||
m_cellFixedRowColDef.SetHeight(nHeight); }
|
||||
int GetDefCellWidth() const { return m_cellDefault.GetWidth(); }
|
||||
void SetDefCellWidth(int nWidth) { m_cellDefault.SetWidth(nWidth);
|
||||
m_cellFixedRowDef.SetWidth(nWidth);
|
||||
m_cellFixedColDef.SetWidth(nWidth);
|
||||
m_cellFixedRowColDef.SetWidth(nWidth); }
|
||||
|
||||
// ***************************************************************************** //
|
||||
|
||||
int GetSelectedCount() const { return (int)m_SelectedCellMap.GetCount(); }
|
||||
|
||||
CCellID SetFocusCell(CCellID cell);
|
||||
CCellID SetFocusCell(int nRow, int nCol);
|
||||
CCellID GetFocusCell() const { return m_idCurrentCell; }
|
||||
|
||||
|
||||
void SetVirtualMode(BOOL bVirtual);
|
||||
BOOL GetVirtualMode() const { return m_bVirtualMode; }
|
||||
void SetCallbackFunc(GRIDCALLBACK pCallback,
|
||||
LPARAM lParam) { m_pfnCallback = pCallback; m_lParam = lParam; }
|
||||
GRIDCALLBACK GetCallbackFunc() { return m_pfnCallback; }
|
||||
|
||||
|
||||
void SetImageList(CImageList* pList) { m_pImageList = pList; }
|
||||
CImageList* GetImageList() const { return m_pImageList; }
|
||||
|
||||
void SetGridLines(int nWhichLines = GVL_BOTH);
|
||||
int GetGridLines() const { return m_nGridLines; }
|
||||
void SetEditable(BOOL bEditable = TRUE) { m_bEditable = bEditable; }
|
||||
BOOL IsEditable() const { return m_bEditable; }
|
||||
void SetListMode(BOOL bEnableListMode = TRUE);
|
||||
BOOL GetListMode() const { return m_bListMode; }
|
||||
void SetSingleRowSelection(BOOL bSing = TRUE) { m_bSingleRowSelection = bSing; }
|
||||
BOOL GetSingleRowSelection() { return m_bSingleRowSelection & m_bListMode; }
|
||||
void SetSingleColSelection(BOOL bSing = TRUE) { m_bSingleColSelection = bSing; }
|
||||
BOOL GetSingleColSelection() { return m_bSingleColSelection; }
|
||||
void EnableSelection(BOOL bEnable = TRUE) { ResetSelectedRange(); m_bEnableSelection = bEnable; ResetSelectedRange(); }
|
||||
BOOL IsSelectable() const { return m_bEnableSelection; }
|
||||
void SetFixedColumnSelection(BOOL bSelect) { m_bFixedColumnSelection = bSelect;}
|
||||
BOOL GetFixedColumnSelection() { return m_bFixedColumnSelection; }
|
||||
void SetFixedRowSelection(BOOL bSelect) { m_bFixedRowSelection = bSelect; }
|
||||
BOOL GetFixedRowSelection() { return m_bFixedRowSelection; }
|
||||
void EnableDragAndDrop(BOOL bAllow = TRUE) { m_bAllowDragAndDrop = bAllow; }
|
||||
BOOL GetDragAndDrop() const { return m_bAllowDragAndDrop; }
|
||||
void SetRowResize(BOOL bResize = TRUE) { m_bAllowRowResize = bResize; }
|
||||
BOOL GetRowResize() const { return m_bAllowRowResize; }
|
||||
void SetColumnResize(BOOL bResize = TRUE) { m_bAllowColumnResize = bResize; }
|
||||
BOOL GetColumnResize() const { return m_bAllowColumnResize; }
|
||||
void SetHeaderSort(BOOL bSortOnClick = TRUE) { m_bSortOnClick = bSortOnClick; }
|
||||
BOOL GetHeaderSort() const { return m_bSortOnClick; }
|
||||
void SetHandleTabKey(BOOL bHandleTab = TRUE) { m_bHandleTabKey = bHandleTab; }
|
||||
BOOL GetHandleTabKey() const { return m_bHandleTabKey; }
|
||||
void SetDoubleBuffering(BOOL bBuffer = TRUE) { m_bDoubleBuffer = bBuffer; }
|
||||
BOOL GetDoubleBuffering() const { return m_bDoubleBuffer; }
|
||||
void EnableTitleTips(BOOL bEnable = TRUE) { m_bTitleTips = bEnable; }
|
||||
BOOL GetTitleTips() { return m_bTitleTips; }
|
||||
void SetSortColumn(int nCol);
|
||||
int GetSortColumn() const { return m_nSortColumn; }
|
||||
void SetSortAscending(BOOL bAscending) { m_bAscending = bAscending; }
|
||||
BOOL GetSortAscending() const { return m_bAscending; }
|
||||
void SetTrackFocusCell(BOOL bTrack) { m_bTrackFocusCell = bTrack; }
|
||||
BOOL GetTrackFocusCell() { return m_bTrackFocusCell; }
|
||||
void SetFrameFocusCell(BOOL bFrame) { m_bFrameFocus = bFrame; }
|
||||
BOOL GetFrameFocusCell() { return m_bFrameFocus; }
|
||||
void SetAutoSizeStyle(int nStyle = GVS_BOTH) { m_nAutoSizeColumnStyle = nStyle; }
|
||||
int GetAutoSizeStyle() { return m_nAutoSizeColumnStyle; }
|
||||
|
||||
void EnableHiddenColUnhide(BOOL bEnable = TRUE){ m_bHiddenColUnhide = bEnable; }
|
||||
BOOL GetHiddenColUnhide() { return m_bHiddenColUnhide; }
|
||||
void EnableHiddenRowUnhide(BOOL bEnable = TRUE){ m_bHiddenRowUnhide = bEnable; }
|
||||
BOOL GetHiddenRowUnhide() { return m_bHiddenRowUnhide; }
|
||||
|
||||
void EnableColumnHide(BOOL bEnable = TRUE) { m_bAllowColHide = bEnable; }
|
||||
BOOL GetColumnHide() { return m_bAllowColHide; }
|
||||
void EnableRowHide(BOOL bEnable = TRUE) { m_bAllowRowHide = bEnable; }
|
||||
BOOL GetRowHide() { return m_bAllowRowHide; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// default Grid cells. Use these for setting default values such as colors and fonts
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
CGridCellBase* GetDefaultCell(BOOL bFixedRow, BOOL bFixedCol) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Grid cell Attributes
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
CGridCellBase* GetCell(int nRow, int nCol) const; // Get the actual cell!
|
||||
|
||||
void SetModified(BOOL bModified = TRUE, int nRow = -1, int nCol = -1);
|
||||
BOOL GetModified(int nRow = -1, int nCol = -1);
|
||||
BOOL IsCellFixed(int nRow, int nCol);
|
||||
|
||||
BOOL SetItem(const GV_ITEM* pItem);
|
||||
BOOL GetItem(GV_ITEM* pItem);
|
||||
BOOL SetItemText(int nRow, int nCol, LPCTSTR str);
|
||||
// The following was virtual. If you want to override, use
|
||||
// CGridCellBase-derived class's GetText() to accomplish same thing
|
||||
CString GetItemText(int nRow, int nCol) const;
|
||||
|
||||
// EFW - 06/13/99 - Added to support printf-style formatting codes.
|
||||
// Also supports use with a string resource ID
|
||||
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 210)
|
||||
BOOL SetItemTextFmt(int nRow, int nCol, LPCTSTR szFmt, ...);
|
||||
BOOL SetItemTextFmtID(int nRow, int nCol, UINT nID, ...);
|
||||
#endif
|
||||
|
||||
BOOL SetItemData(int nRow, int nCol, LPARAM lParam);
|
||||
LPARAM GetItemData(int nRow, int nCol) const;
|
||||
BOOL SetItemImage(int nRow, int nCol, int iImage);
|
||||
int GetItemImage(int nRow, int nCol) const;
|
||||
BOOL SetItemState(int nRow, int nCol, UINT state);
|
||||
UINT GetItemState(int nRow, int nCol) const;
|
||||
BOOL SetItemFormat(int nRow, int nCol, UINT nFormat);
|
||||
UINT GetItemFormat(int nRow, int nCol) const;
|
||||
BOOL SetItemBkColour(int nRow, int nCol, COLORREF cr = CLR_DEFAULT);
|
||||
COLORREF GetItemBkColour(int nRow, int nCol) const;
|
||||
BOOL SetItemFgColour(int nRow, int nCol, COLORREF cr = CLR_DEFAULT);
|
||||
COLORREF GetItemFgColour(int nRow, int nCol) const;
|
||||
BOOL SetItemFont(int nRow, int nCol, const LOGFONT* lf);
|
||||
const LOGFONT* GetItemFont(int nRow, int nCol);
|
||||
|
||||
BOOL IsItemEditing(int nRow, int nCol);
|
||||
|
||||
BOOL SetCellType(int nRow, int nCol, CRuntimeClass* pRuntimeClass);
|
||||
BOOL SetDefaultCellType( CRuntimeClass* pRuntimeClass);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Operations
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
int InsertColumn(LPCTSTR strHeading, UINT nFormat = DT_CENTER|DT_VCENTER|DT_SINGLELINE,
|
||||
int nColumn = -1);
|
||||
int InsertRow(LPCTSTR strHeading, int nRow = -1);
|
||||
BOOL DeleteColumn(int nColumn);
|
||||
BOOL DeleteRow(int nRow);
|
||||
BOOL DeleteNonFixedRows();
|
||||
BOOL DeleteAllItems();
|
||||
|
||||
void ClearCells(CCellRange Selection);
|
||||
|
||||
BOOL AutoSizeRow(int nRow, BOOL bResetScroll = TRUE);
|
||||
BOOL AutoSizeColumn(int nCol, UINT nAutoSizeStyle = GVS_DEFAULT, BOOL bResetScroll = TRUE);
|
||||
void AutoSizeRows();
|
||||
void AutoSizeColumns(UINT nAutoSizeStyle = GVS_DEFAULT);
|
||||
void AutoSize(UINT nAutoSizeStyle = GVS_DEFAULT);
|
||||
void ExpandColumnsToFit(BOOL bExpandFixed = TRUE);
|
||||
void ExpandLastColumn();
|
||||
void ExpandRowsToFit(BOOL bExpandFixed = TRUE);
|
||||
void ExpandToFit(BOOL bExpandFixed = TRUE);
|
||||
|
||||
void Refresh();
|
||||
void AutoFill(); // Fill grid with blank cells
|
||||
|
||||
void EnsureVisible(CCellID &cell) { EnsureVisible(cell.row, cell.col); }
|
||||
void EnsureVisible(int nRow, int nCol);
|
||||
BOOL IsCellVisible(int nRow, int nCol);
|
||||
BOOL IsCellVisible(CCellID cell);
|
||||
BOOL IsCellEditable(int nRow, int nCol) const;
|
||||
BOOL IsCellEditable(CCellID &cell) const;
|
||||
BOOL IsCellSelected(int nRow, int nCol) const;
|
||||
BOOL IsCellSelected(CCellID &cell) const;
|
||||
|
||||
// SetRedraw stops/starts redraws on things like changing the # rows/columns
|
||||
// and autosizing, but not for user-intervention such as resizes
|
||||
void SetRedraw(BOOL bAllowDraw, BOOL bResetScrollBars = FALSE);
|
||||
BOOL RedrawCell(int nRow, int nCol, CDC* pDC = NULL);
|
||||
BOOL RedrawCell(const CCellID& cell, CDC* pDC = NULL);
|
||||
BOOL RedrawRow(int row);
|
||||
BOOL RedrawColumn(int col);
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
BOOL Save(LPCTSTR filename, TCHAR chSeparator = _T(','));
|
||||
BOOL Load(LPCTSTR filename, TCHAR chSeparator = _T(','));
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Cell Ranges
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
CCellRange GetCellRange() const;
|
||||
CCellRange GetSelectedCellRange() const;
|
||||
void SetSelectedRange(const CCellRange& Range, BOOL bForceRepaint = FALSE, BOOL bSelectCells = TRUE);
|
||||
void SetSelectedRange(int nMinRow, int nMinCol, int nMaxRow, int nMaxCol,
|
||||
BOOL bForceRepaint = FALSE, BOOL bSelectCells = TRUE);
|
||||
BOOL IsValid(int nRow, int nCol) const;
|
||||
BOOL IsValid(const CCellID& cell) const;
|
||||
BOOL IsValid(const CCellRange& range) const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Clipboard, drag and drop, and cut n' paste operations
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef GRIDCONTROL_NO_CLIPBOARD
|
||||
virtual void CutSelectedText();
|
||||
virtual COleDataSource* CopyTextFromGrid();
|
||||
virtual BOOL PasteTextToGrid(CCellID cell, COleDataObject* pDataObject, BOOL bSelectPastedCells=TRUE);
|
||||
#endif
|
||||
|
||||
#ifndef GRIDCONTROL_NO_DRAGDROP
|
||||
public:
|
||||
virtual void OnBeginDrag();
|
||||
virtual DROPEFFECT OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
|
||||
virtual DROPEFFECT OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
|
||||
virtual void OnDragLeave();
|
||||
virtual BOOL OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point);
|
||||
#endif
|
||||
|
||||
#ifndef GRIDCONTROL_NO_CLIPBOARD
|
||||
virtual void OnEditCut();
|
||||
virtual void OnEditCopy();
|
||||
virtual void OnEditPaste();
|
||||
#endif
|
||||
virtual void OnEditSelectAll();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Misc.
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
CCellID GetNextItem(CCellID& cell, int nFlags) const;
|
||||
|
||||
BOOL SortItems(int nCol, BOOL bAscending, LPARAM data = 0);
|
||||
BOOL SortTextItems(int nCol, BOOL bAscending, LPARAM data = 0);
|
||||
BOOL SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending, LPARAM data = 0);
|
||||
|
||||
void SetCompareFunction(PFNLVCOMPARE pfnCompare);
|
||||
|
||||
// in-built sort functions
|
||||
static int CALLBACK pfnCellTextCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
|
||||
static int CALLBACK pfnCellNumericCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Printing
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
|
||||
public:
|
||||
void Print(CPrintDialog* pPrntDialog = NULL);
|
||||
|
||||
// EFW - New printing support functions
|
||||
void EnableWysiwygPrinting(BOOL bEnable = TRUE) { m_bWysiwygPrinting = bEnable; }
|
||||
BOOL GetWysiwygPrinting() { return m_bWysiwygPrinting; }
|
||||
|
||||
void SetShadedPrintOut(BOOL bEnable = TRUE) { m_bShadedPrintOut = bEnable; }
|
||||
BOOL GetShadedPrintOut(void) { return m_bShadedPrintOut; }
|
||||
|
||||
// Use -1 to have it keep the existing value
|
||||
void SetPrintMarginInfo(int nHeaderHeight, int nFooterHeight,
|
||||
int nLeftMargin, int nRightMargin, int nTopMargin,
|
||||
int nBottomMargin, int nGap);
|
||||
|
||||
void GetPrintMarginInfo(int &nHeaderHeight, int &nFooterHeight,
|
||||
int &nLeftMargin, int &nRightMargin, int &nTopMargin,
|
||||
int &nBottomMargin, int &nGap);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Printing overrides for derived classes
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
virtual void OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo);
|
||||
virtual void OnPrint(CDC *pDC, CPrintInfo *pInfo);
|
||||
virtual void OnEndPrinting(CDC *pDC, CPrintInfo *pInfo);
|
||||
|
||||
#endif // #if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CGridCtrl();
|
||||
|
||||
protected:
|
||||
BOOL RegisterWindowClass();
|
||||
BOOL Initialise();
|
||||
void SetupDefaultCells();
|
||||
|
||||
LRESULT SendMessageToParent(int nRow, int nCol, int nMessage) const;
|
||||
LRESULT SendDisplayRequestToParent(GV_DISPINFO* pDisplayInfo) const;
|
||||
LRESULT SendCacheHintToParent(const CCellRange& range) const;
|
||||
|
||||
BOOL InvalidateCellRect(const int row, const int col);
|
||||
BOOL InvalidateCellRect(const CCellID& cell);
|
||||
BOOL InvalidateCellRect(const CCellRange& cellRange);
|
||||
void EraseBkgnd(CDC* pDC);
|
||||
|
||||
BOOL GetCellRangeRect(const CCellRange& cellRange, LPRECT lpRect);
|
||||
|
||||
BOOL SetCell(int nRow, int nCol, CGridCellBase* pCell);
|
||||
|
||||
int SetMouseMode(int nMode) { int nOldMode = m_MouseMode; m_MouseMode = nMode; return nOldMode; }
|
||||
int GetMouseMode() const { return m_MouseMode; }
|
||||
|
||||
BOOL MouseOverRowResizeArea(CPoint& point);
|
||||
BOOL MouseOverColumnResizeArea(CPoint& point);
|
||||
|
||||
CCellID GetTopleftNonFixedCell(BOOL bForceRecalculation = FALSE);
|
||||
CCellRange GetUnobstructedNonFixedCellRange(BOOL bForceRecalculation = FALSE);
|
||||
CCellRange GetVisibleNonFixedCellRange(LPRECT pRect = NULL, BOOL bForceRecalculation = FALSE);
|
||||
|
||||
BOOL IsVisibleVScroll() { return ( (m_nBarState & GVL_VERT) > 0); }
|
||||
BOOL IsVisibleHScroll() { return ( (m_nBarState & GVL_HORZ) > 0); }
|
||||
void ResetSelectedRange();
|
||||
void ResetScrollBars();
|
||||
void EnableScrollBars(int nBar, BOOL bEnable = TRUE);
|
||||
int GetScrollPos32(int nBar, BOOL bGetTrackPos = FALSE);
|
||||
BOOL SetScrollPos32(int nBar, int nPos, BOOL bRedraw = TRUE);
|
||||
|
||||
BOOL SortTextItems(int nCol, BOOL bAscending, int low, int high);
|
||||
BOOL SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending, LPARAM data,
|
||||
int low, int high);
|
||||
|
||||
CPoint GetPointClicked(int nRow, int nCol, const CPoint& point);
|
||||
|
||||
void ValidateAndModifyCellContents(int nRow, int nCol, LPCTSTR strText);
|
||||
|
||||
// Overrrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CGridCtrl)
|
||||
protected:
|
||||
virtual void PreSubclassWindow();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
protected:
|
||||
#if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
|
||||
// Printing
|
||||
virtual void PrintFixedRowCells(int nStartColumn, int nStopColumn, int& row, CRect& rect,
|
||||
CDC *pDC, BOOL& bFirst);
|
||||
virtual void PrintColumnHeadings(CDC *pDC, CPrintInfo *pInfo);
|
||||
virtual void PrintHeader(CDC *pDC, CPrintInfo *pInfo);
|
||||
virtual void PrintFooter(CDC *pDC, CPrintInfo *pInfo);
|
||||
virtual void PrintRowButtons(CDC *pDC, CPrintInfo* /*pInfo*/);
|
||||
#endif
|
||||
|
||||
#ifndef GRIDCONTROL_NO_DRAGDROP
|
||||
// Drag n' drop
|
||||
virtual CImageList* CreateDragImage(CPoint *pHotSpot); // no longer necessary
|
||||
#endif
|
||||
|
||||
// Mouse Clicks
|
||||
virtual void OnFixedColumnClick(CCellID& cell);
|
||||
virtual void OnFixedRowClick(CCellID& cell);
|
||||
|
||||
// Editing
|
||||
virtual void OnEditCell(int nRow, int nCol, CPoint point, UINT nChar);
|
||||
virtual void OnEndEditCell(int nRow, int nCol, CString str);
|
||||
virtual BOOL ValidateEdit(int nRow, int nCol, LPCTSTR str);
|
||||
virtual void EndEditing();
|
||||
|
||||
// Drawing
|
||||
virtual void OnDraw(CDC* pDC);
|
||||
|
||||
// CGridCellBase Creation and Cleanup
|
||||
virtual CGridCellBase* CreateCell(int nRow, int nCol);
|
||||
virtual void DestroyCell(int nRow, int nCol);
|
||||
|
||||
// Attributes
|
||||
protected:
|
||||
// General attributes
|
||||
COLORREF m_crFixedTextColour, m_crFixedBkColour;
|
||||
COLORREF m_crGridBkColour, m_crGridLineColour;
|
||||
COLORREF m_crWindowText, m_crWindowColour, m_cr3DFace, // System colours
|
||||
m_crShadow;
|
||||
COLORREF m_crTTipBackClr, m_crTTipTextClr; // Titletip colours - FNA
|
||||
|
||||
BOOL m_bVirtualMode;
|
||||
LPARAM m_lParam; // lParam for callback
|
||||
GRIDCALLBACK m_pfnCallback; // The callback function
|
||||
|
||||
int m_nGridLines;
|
||||
BOOL m_bEditable;
|
||||
BOOL m_bModified;
|
||||
BOOL m_bAllowDragAndDrop;
|
||||
BOOL m_bListMode;
|
||||
BOOL m_bSingleRowSelection;
|
||||
BOOL m_bSingleColSelection;
|
||||
BOOL m_bAllowDraw;
|
||||
BOOL m_bEnableSelection;
|
||||
BOOL m_bFixedRowSelection, m_bFixedColumnSelection;
|
||||
BOOL m_bSortOnClick;
|
||||
BOOL m_bHandleTabKey;
|
||||
BOOL m_bDoubleBuffer;
|
||||
BOOL m_bTitleTips;
|
||||
int m_nBarState;
|
||||
BOOL m_bWysiwygPrinting;
|
||||
BOOL m_bHiddenColUnhide, m_bHiddenRowUnhide;
|
||||
BOOL m_bAllowColHide, m_bAllowRowHide;
|
||||
BOOL m_bAutoSizeSkipColHdr;
|
||||
BOOL m_bTrackFocusCell;
|
||||
BOOL m_bFrameFocus;
|
||||
UINT m_nAutoSizeColumnStyle;
|
||||
|
||||
// Cell size details
|
||||
int m_nRows, m_nFixedRows, m_nCols, m_nFixedCols;
|
||||
CUIntArray m_arRowHeights, m_arColWidths;
|
||||
int m_nVScrollMax, m_nHScrollMax;
|
||||
|
||||
// Fonts and images
|
||||
CRuntimeClass* m_pRtcDefault; // determines kind of Grid Cell created by default
|
||||
CGridDefaultCell m_cellDefault; // "default" cell. Contains default colours, font etc.
|
||||
CGridDefaultCell m_cellFixedColDef, m_cellFixedRowDef, m_cellFixedRowColDef;
|
||||
CFont m_PrinterFont; // for the printer
|
||||
CImageList* m_pImageList;
|
||||
|
||||
// Cell data
|
||||
CTypedPtrArray<CObArray, GRID_ROW*> m_RowData;
|
||||
|
||||
// Mouse operations such as cell selection
|
||||
int m_MouseMode;
|
||||
BOOL m_bLMouseButtonDown, m_bRMouseButtonDown;
|
||||
CPoint m_LeftClickDownPoint, m_LastMousePoint;
|
||||
CCellID m_LeftClickDownCell, m_SelectionStartCell;
|
||||
CCellID m_idCurrentCell, m_idTopLeftCell;
|
||||
int m_nTimerID;
|
||||
int m_nTimerInterval;
|
||||
int m_nResizeCaptureRange;
|
||||
BOOL m_bAllowRowResize, m_bAllowColumnResize;
|
||||
int m_nRowsPerWheelNotch;
|
||||
CMap<DWORD,DWORD, CCellID, CCellID&> m_SelectedCellMap, m_PrevSelectedCellMap;
|
||||
|
||||
#ifndef GRIDCONTROL_NO_TITLETIPS
|
||||
CTitleTip m_TitleTip; // Title tips for cells
|
||||
#endif
|
||||
|
||||
// Drag and drop
|
||||
CCellID m_LastDragOverCell;
|
||||
#ifndef GRIDCONTROL_NO_DRAGDROP
|
||||
CGridDropTarget m_DropTarget; // OLE Drop target for the grid
|
||||
#endif
|
||||
|
||||
// Printing information
|
||||
CSize m_CharSize;
|
||||
int m_nPageHeight;
|
||||
CSize m_LogicalPageSize, // Page size in gridctrl units.
|
||||
m_PaperSize; // Page size in device units.
|
||||
// additional properties to support Wysiwyg printing
|
||||
int m_nPageWidth;
|
||||
int m_nPrintColumn;
|
||||
int m_nCurrPrintRow;
|
||||
int m_nNumPages;
|
||||
int m_nPageMultiplier;
|
||||
|
||||
// sorting
|
||||
int m_bAscending;
|
||||
int m_nSortColumn;
|
||||
PFNLVCOMPARE m_pfnCompare;
|
||||
|
||||
// EFW - Added to support shaded/unshaded printout. If true, colored
|
||||
// cells will print as-is. If false, all text prints as black on white.
|
||||
BOOL m_bShadedPrintOut;
|
||||
|
||||
// EFW - Added support for user-definable margins. Top and bottom are in
|
||||
// lines. Left, right, and gap are in characters (avg width is used).
|
||||
int m_nHeaderHeight, m_nFooterHeight, m_nLeftMargin,
|
||||
m_nRightMargin, m_nTopMargin, m_nBottomMargin, m_nGap;
|
||||
|
||||
protected:
|
||||
void SelectAllCells();
|
||||
void SelectColumns(CCellID currentCell, BOOL bForceRedraw=FALSE, BOOL bSelectCells=TRUE);
|
||||
void SelectRows(CCellID currentCell, BOOL bForceRedraw=FALSE, BOOL bSelectCells=TRUE);
|
||||
void SelectCells(CCellID currentCell, BOOL bForceRedraw=FALSE, BOOL bSelectCells=TRUE);
|
||||
void OnSelecting(const CCellID& currentCell);
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CGridCtrl)
|
||||
afx_msg void OnPaint();
|
||||
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
||||
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
||||
afx_msg void OnSize(UINT nType, int cx, int cy);
|
||||
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
|
||||
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
|
||||
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
|
||||
afx_msg void OnTimer(UINT nIDEvent);
|
||||
afx_msg UINT OnGetDlgCode();
|
||||
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
|
||||
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
|
||||
afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
afx_msg void OnUpdateEditSelectAll(CCmdUI* pCmdUI);
|
||||
//}}AFX_MSG
|
||||
#ifndef _WIN32_WCE_NO_CURSOR
|
||||
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
|
||||
#endif
|
||||
#ifndef _WIN32_WCE
|
||||
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
|
||||
afx_msg void OnRButtonUp(UINT nFlags, CPoint point); // EFW - Added
|
||||
afx_msg void OnSysColorChange();
|
||||
#endif
|
||||
#ifndef _WIN32_WCE_NO_CURSOR
|
||||
afx_msg void OnCaptureChanged(CWnd *pWnd);
|
||||
#endif
|
||||
#ifndef GRIDCONTROL_NO_CLIPBOARD
|
||||
afx_msg void OnUpdateEditCopy(CCmdUI* pCmdUI);
|
||||
afx_msg void OnUpdateEditCut(CCmdUI* pCmdUI);
|
||||
afx_msg void OnUpdateEditPaste(CCmdUI* pCmdUI);
|
||||
#endif
|
||||
#if (_MFC_VER >= 0x0421) || (_WIN32_WCE >= 210)
|
||||
afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
|
||||
#endif
|
||||
#if !defined(_WIN32_WCE) && (_MFC_VER >= 0x0421)
|
||||
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
|
||||
#endif
|
||||
afx_msg LRESULT OnSetFont(WPARAM hFont, LPARAM lParam);
|
||||
afx_msg LRESULT OnGetFont(WPARAM hFont, LPARAM lParam);
|
||||
afx_msg LRESULT OnImeChar(WPARAM wCharCode, LPARAM lParam);
|
||||
afx_msg void OnEndInPlaceEdit(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
enum eMouseModes { MOUSE_NOTHING, MOUSE_SELECT_ALL, MOUSE_SELECT_COL, MOUSE_SELECT_ROW,
|
||||
MOUSE_SELECT_CELLS, MOUSE_SCROLLING_CELLS,
|
||||
MOUSE_OVER_ROW_DIVIDE, MOUSE_SIZING_ROW,
|
||||
MOUSE_OVER_COL_DIVIDE, MOUSE_SIZING_COL,
|
||||
MOUSE_PREPARE_EDIT,
|
||||
#ifndef GRIDCONTROL_NO_DRAGDROP
|
||||
MOUSE_PREPARE_DRAG, MOUSE_DRAGGING
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
// Returns the default cell implementation for the given grid region
|
||||
inline CGridCellBase* CGridCtrl::GetDefaultCell(BOOL bFixedRow, BOOL bFixedCol) const
|
||||
{
|
||||
if (bFixedRow && bFixedCol) return (CGridCellBase*) &m_cellFixedRowColDef;
|
||||
if (bFixedRow) return (CGridCellBase*) &m_cellFixedRowDef;
|
||||
if (bFixedCol) return (CGridCellBase*) &m_cellFixedColDef;
|
||||
return (CGridCellBase*) &m_cellDefault;
|
||||
}
|
||||
|
||||
inline CGridCellBase* CGridCtrl::GetCell(int nRow, int nCol) const
|
||||
{
|
||||
if (nRow < 0 || nRow >= m_nRows || nCol < 0 || nCol >= m_nCols)
|
||||
return NULL;
|
||||
|
||||
if (GetVirtualMode())
|
||||
{
|
||||
CGridCellBase* pCell = GetDefaultCell(nRow < m_nFixedRows, nCol < m_nFixedCols);
|
||||
static GV_DISPINFO gvdi;
|
||||
gvdi.item.row = nRow;
|
||||
gvdi.item.col = nCol;
|
||||
gvdi.item.mask = 0xFFFFFFFF;
|
||||
gvdi.item.nState = 0;
|
||||
gvdi.item.nFormat = pCell->GetFormat();
|
||||
gvdi.item.iImage = pCell->GetImage();
|
||||
gvdi.item.crBkClr = pCell->GetBackClr();
|
||||
gvdi.item.crFgClr = pCell->GetTextClr();
|
||||
gvdi.item.lParam = pCell->GetData();
|
||||
memcpy(&gvdi.item.lfFont, pCell->GetFont(), sizeof(LOGFONT));
|
||||
gvdi.item.nMargin = pCell->GetMargin();
|
||||
gvdi.item.strText.Empty();
|
||||
|
||||
// Fix the state bits
|
||||
if (IsCellSelected(nRow, nCol)) gvdi.item.nState |= GVIS_SELECTED;
|
||||
if (nRow < GetFixedRowCount()) gvdi.item.nState |= (GVIS_FIXED | GVIS_FIXEDROW);
|
||||
if (nCol < GetFixedColumnCount()) gvdi.item.nState |= (GVIS_FIXED | GVIS_FIXEDCOL);
|
||||
if (GetFocusCell() == CCellID(nRow, nCol)) gvdi.item.nState |= GVIS_FOCUSED;
|
||||
|
||||
if (m_pfnCallback)
|
||||
m_pfnCallback(&gvdi, m_lParam);
|
||||
else
|
||||
SendDisplayRequestToParent(&gvdi);
|
||||
|
||||
static CGridCell cell;
|
||||
cell.SetState(gvdi.item.nState);
|
||||
cell.SetFormat(gvdi.item.nFormat);
|
||||
cell.SetImage(gvdi.item.iImage);
|
||||
cell.SetBackClr(gvdi.item.crBkClr);
|
||||
cell.SetTextClr(gvdi.item.crFgClr);
|
||||
cell.SetData(gvdi.item.lParam);
|
||||
cell.SetFont(&(gvdi.item.lfFont));
|
||||
cell.SetMargin(gvdi.item.nMargin);
|
||||
cell.SetText(gvdi.item.strText);
|
||||
cell.SetGrid((CGridCtrl*)this);
|
||||
|
||||
return (CGridCellBase*) &cell;
|
||||
}
|
||||
|
||||
GRID_ROW* pRow = m_RowData[nRow];
|
||||
if (!pRow) return NULL;
|
||||
return pRow->GetAt(nCol);
|
||||
}
|
||||
|
||||
inline BOOL CGridCtrl::SetCell(int nRow, int nCol, CGridCellBase* pCell)
|
||||
{
|
||||
if (GetVirtualMode())
|
||||
return FALSE;
|
||||
|
||||
if (nRow < 0 || nRow >= m_nRows || nCol < 0 || nCol >= m_nCols)
|
||||
return FALSE;
|
||||
|
||||
GRID_ROW* pRow = m_RowData[nRow];
|
||||
if (!pRow) return FALSE;
|
||||
|
||||
pCell->SetCoords( nRow, nCol);
|
||||
pRow->SetAt(nCol, pCell);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_GRIDCTRL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
|
||||
156
Server/ManageTool/GridControl/GridCtrl_src/GridDropTarget.cpp
Normal file
156
Server/ManageTool/GridControl/GridCtrl_src/GridDropTarget.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
// GridDropTarget.cpp : implementation file
|
||||
//
|
||||
// MFC Grid Control - Drag/Drop target implementation
|
||||
//
|
||||
// CGridDropTarget is an OLE drop target for CGridCtrl. All it does
|
||||
// is handle the drag and drop windows messages and pass them
|
||||
// directly onto the grid control.
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.10+
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "GridCtrl.h"
|
||||
|
||||
#ifndef GRIDCONTROL_NO_DRAGDROP
|
||||
#include "GridDropTarget.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGridDropTarget
|
||||
|
||||
CGridDropTarget::CGridDropTarget()
|
||||
{
|
||||
m_pGridCtrl = NULL;
|
||||
m_bRegistered = FALSE;
|
||||
}
|
||||
|
||||
CGridDropTarget::~CGridDropTarget()
|
||||
{
|
||||
}
|
||||
|
||||
// Overloaded Register() function performs the normal COleDropTarget::Register
|
||||
// but also serves to connect this COleDropTarget with the parent grid control,
|
||||
// where all drop messages will ultimately be forwarded.
|
||||
BOOL CGridDropTarget::Register(CGridCtrl *pGridCtrl)
|
||||
{
|
||||
if (m_bRegistered)
|
||||
return FALSE;
|
||||
|
||||
// Stop re-entry problems
|
||||
static BOOL bInProcedure = FALSE;
|
||||
if (bInProcedure)
|
||||
return FALSE;
|
||||
bInProcedure = TRUE;
|
||||
|
||||
ASSERT(pGridCtrl->IsKindOf(RUNTIME_CLASS(CGridCtrl)));
|
||||
ASSERT(pGridCtrl);
|
||||
|
||||
if (!pGridCtrl || !pGridCtrl->IsKindOf(RUNTIME_CLASS(CGridCtrl)))
|
||||
{
|
||||
bInProcedure = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_pGridCtrl = pGridCtrl;
|
||||
|
||||
m_bRegistered = COleDropTarget::Register(pGridCtrl);
|
||||
|
||||
bInProcedure = FALSE;
|
||||
return m_bRegistered;
|
||||
}
|
||||
|
||||
void CGridDropTarget::Revoke()
|
||||
{
|
||||
m_bRegistered = FALSE;
|
||||
COleDropTarget::Revoke();
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CGridDropTarget, COleDropTarget)
|
||||
//{{AFX_MSG_MAP(CGridDropTarget)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGridDropTarget message handlers
|
||||
|
||||
DROPEFFECT CGridDropTarget::OnDragScroll(CWnd* pWnd, DWORD dwKeyState, CPoint /*point*/)
|
||||
{
|
||||
// TRACE("In CGridDropTarget::OnDragScroll\n");
|
||||
if (pWnd->GetSafeHwnd() == m_pGridCtrl->GetSafeHwnd())
|
||||
{
|
||||
if (dwKeyState & MK_CONTROL)
|
||||
return DROPEFFECT_COPY;
|
||||
else
|
||||
return DROPEFFECT_MOVE;
|
||||
} else
|
||||
return DROPEFFECT_NONE;
|
||||
}
|
||||
|
||||
DROPEFFECT CGridDropTarget::OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject,
|
||||
DWORD dwKeyState, CPoint point)
|
||||
{
|
||||
TRACE(_T("In CGridDropTarget::OnDragEnter\n"));
|
||||
ASSERT(m_pGridCtrl);
|
||||
|
||||
if (pWnd->GetSafeHwnd() == m_pGridCtrl->GetSafeHwnd())
|
||||
return m_pGridCtrl->OnDragEnter(pDataObject, dwKeyState, point);
|
||||
else
|
||||
return DROPEFFECT_NONE;
|
||||
}
|
||||
|
||||
void CGridDropTarget::OnDragLeave(CWnd* pWnd)
|
||||
{
|
||||
TRACE(_T("In CGridDropTarget::OnDragLeave\n"));
|
||||
ASSERT(m_pGridCtrl);
|
||||
|
||||
if (pWnd->GetSafeHwnd() == m_pGridCtrl->GetSafeHwnd())
|
||||
m_pGridCtrl->OnDragLeave();
|
||||
}
|
||||
|
||||
DROPEFFECT CGridDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
|
||||
DWORD dwKeyState, CPoint point)
|
||||
{
|
||||
// TRACE("In CGridDropTarget::OnDragOver\n");
|
||||
ASSERT(m_pGridCtrl);
|
||||
|
||||
if (pWnd->GetSafeHwnd() == m_pGridCtrl->GetSafeHwnd())
|
||||
return m_pGridCtrl->OnDragOver(pDataObject, dwKeyState, point);
|
||||
else
|
||||
return DROPEFFECT_NONE;
|
||||
}
|
||||
|
||||
BOOL CGridDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
|
||||
DROPEFFECT dropEffect, CPoint point)
|
||||
{
|
||||
TRACE(_T("In CGridDropTarget::OnDrop\n"));
|
||||
ASSERT(m_pGridCtrl);
|
||||
|
||||
if (pWnd->GetSafeHwnd() == m_pGridCtrl->GetSafeHwnd())
|
||||
return m_pGridCtrl->OnDrop(pDataObject, dropEffect, point);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif // GRIDCONTROL_NO_DRAGDROP
|
||||
82
Server/ManageTool/GridControl/GridCtrl_src/GridDropTarget.h
Normal file
82
Server/ManageTool/GridControl/GridCtrl_src/GridDropTarget.h
Normal file
@@ -0,0 +1,82 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// GridDropTarget.h : header file
|
||||
//
|
||||
// MFC Grid Control - Drag/Drop target implementation
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.10+
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_GRIDDROPTARGET_H__5C610981_BD36_11D1_97CD_00A0243D1382__INCLUDED_)
|
||||
#define AFX_GRIDDROPTARGET_H__5C610981_BD36_11D1_97CD_00A0243D1382__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
|
||||
#include <afxole.h>
|
||||
|
||||
class CGridCtrl;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGridDropTarget command target
|
||||
|
||||
class AFX_EXT_CLASS CGridDropTarget : public COleDropTarget
|
||||
{
|
||||
public:
|
||||
CGridDropTarget();
|
||||
virtual ~CGridDropTarget();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
CGridCtrl* m_pGridCtrl;
|
||||
BOOL m_bRegistered;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
BOOL Register(CGridCtrl *pGridCtrl);
|
||||
virtual void Revoke();
|
||||
|
||||
BOOL OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point);
|
||||
DROPEFFECT OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
|
||||
void OnDragLeave(CWnd* pWnd);
|
||||
DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
|
||||
DROPEFFECT OnDragScroll(CWnd* pWnd, DWORD dwKeyState, CPoint point);
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CGridDropTarget)
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CGridDropTarget)
|
||||
//}}AFX_MSG
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_GRIDDROPTARGET_H__5C610981_BD36_11D1_97CD_00A0243D1382__INCLUDED_)
|
||||
263
Server/ManageTool/GridControl/GridCtrl_src/InPlaceEdit.cpp
Normal file
263
Server/ManageTool/GridControl/GridCtrl_src/InPlaceEdit.cpp
Normal file
@@ -0,0 +1,263 @@
|
||||
// InPlaceEdit.cpp : implementation file
|
||||
//
|
||||
// Adapted by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// The code contained in this file is based on the original
|
||||
// CInPlaceEdit from http://www.codeguru.com/listview/edit_subitems.shtml
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.10+
|
||||
//
|
||||
// History:
|
||||
// 10 May 1998 Uses GVN_ notifications instead of LVN_,
|
||||
// Sends notification messages to the parent,
|
||||
// instead of the parent's parent.
|
||||
// 15 May 1998 There was a problem when editing with the in-place editor,
|
||||
// there arises a general protection fault in user.exe, with a
|
||||
// few qualifications:
|
||||
// (1) This only happens with owner-drawn buttons;
|
||||
// (2) This only happens in Win95
|
||||
// (3) This only happens if the handler for the button does not
|
||||
// create a new window (even an AfxMessageBox will avoid the
|
||||
// crash)
|
||||
// (4) This will not happen if Spy++ is running.
|
||||
// PreTranslateMessage was added to route messages correctly.
|
||||
// (Matt Weagle found and fixed this problem)
|
||||
// 26 Jul 1998 Removed the ES_MULTILINE style - that fixed a few probs!
|
||||
// 6 Aug 1998 Added nID to the constructor param list
|
||||
// 6 Sep 1998 Space no longer clears selection when starting edit (Franco Bez)
|
||||
// 10 Apr 1999 Enter, Tab and Esc key prob fixed (Koay Kah Hoe)
|
||||
// Workaround for bizzare "shrinking window" problem in CE
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "TCHAR.h"
|
||||
#include "InPlaceEdit.h"
|
||||
|
||||
#include "GridCtrl.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CInPlaceEdit
|
||||
|
||||
CInPlaceEdit::CInPlaceEdit(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
|
||||
int nRow, int nColumn, CString sInitText,
|
||||
UINT nFirstChar)
|
||||
{
|
||||
m_sInitText = sInitText;
|
||||
m_nRow = nRow;
|
||||
m_nColumn = nColumn;
|
||||
m_nLastChar = 0;
|
||||
m_bExitOnArrows = (nFirstChar != VK_LBUTTON); // If mouse click brought us here,
|
||||
// then no exit on arrows
|
||||
|
||||
m_Rect = rect; // For bizarre CE bug.
|
||||
|
||||
DWORD dwEditStyle = WS_BORDER|WS_CHILD|WS_VISIBLE| ES_AUTOHSCROLL //|ES_MULTILINE
|
||||
| dwStyle;
|
||||
if (!Create(dwEditStyle, rect, pParent, nID)) return;
|
||||
|
||||
SetFont(pParent->GetFont());
|
||||
|
||||
SetWindowText(sInitText);
|
||||
SetFocus();
|
||||
|
||||
switch (nFirstChar){
|
||||
case VK_LBUTTON:
|
||||
case VK_RETURN: SetSel((int)_tcslen(m_sInitText), -1); return;
|
||||
case VK_BACK: SetSel((int)_tcslen(m_sInitText), -1); break;
|
||||
case VK_TAB:
|
||||
case VK_DOWN:
|
||||
case VK_UP:
|
||||
case VK_RIGHT:
|
||||
case VK_LEFT:
|
||||
case VK_NEXT:
|
||||
case VK_PRIOR:
|
||||
case VK_HOME:
|
||||
case VK_SPACE:
|
||||
case VK_END: SetSel(0,-1); return;
|
||||
default: SetSel(0,-1);
|
||||
}
|
||||
|
||||
// Added by KiteFly. When entering DBCS chars into cells the first char was being lost
|
||||
// SenMessage changed to PostMessage (John Lagerquist)
|
||||
if( nFirstChar < 0x80)
|
||||
PostMessage(WM_CHAR, nFirstChar);
|
||||
else
|
||||
PostMessage(WM_IME_CHAR, nFirstChar);
|
||||
}
|
||||
|
||||
CInPlaceEdit::~CInPlaceEdit()
|
||||
{
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CInPlaceEdit, CEdit)
|
||||
//{{AFX_MSG_MAP(CInPlaceEdit)
|
||||
ON_WM_KILLFOCUS()
|
||||
ON_WM_CHAR()
|
||||
ON_WM_KEYDOWN()
|
||||
ON_WM_GETDLGCODE()
|
||||
ON_WM_CREATE()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// CInPlaceEdit message handlers
|
||||
|
||||
// If an arrow key (or associated) is pressed, then exit if
|
||||
// a) The Ctrl key was down, or
|
||||
// b) m_bExitOnArrows == TRUE
|
||||
void CInPlaceEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||||
{
|
||||
if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
|
||||
nChar == VK_DOWN || nChar == VK_UP ||
|
||||
nChar == VK_RIGHT || nChar == VK_LEFT) &&
|
||||
(m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0))
|
||||
{
|
||||
m_nLastChar = nChar;
|
||||
GetParent()->SetFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
|
||||
}
|
||||
|
||||
// As soon as this edit loses focus, kill it.
|
||||
void CInPlaceEdit::OnKillFocus(CWnd* pNewWnd)
|
||||
{
|
||||
CEdit::OnKillFocus(pNewWnd);
|
||||
EndEdit();
|
||||
}
|
||||
|
||||
void CInPlaceEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||||
{
|
||||
if (nChar == VK_TAB || nChar == VK_RETURN)
|
||||
{
|
||||
m_nLastChar = nChar;
|
||||
GetParent()->SetFocus(); // This will destroy this window
|
||||
return;
|
||||
}
|
||||
if (nChar == VK_ESCAPE)
|
||||
{
|
||||
SetWindowText(m_sInitText); // restore previous text
|
||||
m_nLastChar = nChar;
|
||||
GetParent()->SetFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
CEdit::OnChar(nChar, nRepCnt, nFlags);
|
||||
|
||||
// Resize edit control if needed
|
||||
|
||||
// Get text extent
|
||||
CString str;
|
||||
GetWindowText( str );
|
||||
|
||||
// add some extra buffer
|
||||
str += _T(" ");
|
||||
|
||||
CWindowDC dc(this);
|
||||
CFont *pFontDC = dc.SelectObject(GetFont());
|
||||
CSize size = dc.GetTextExtent( str );
|
||||
dc.SelectObject( pFontDC );
|
||||
|
||||
// Get client rect
|
||||
CRect ParentRect;
|
||||
GetParent()->GetClientRect( &ParentRect );
|
||||
|
||||
// Check whether control needs to be resized
|
||||
// and whether there is space to grow
|
||||
if (size.cx > m_Rect.Width())
|
||||
{
|
||||
if( size.cx + m_Rect.left < ParentRect.right )
|
||||
m_Rect.right = m_Rect.left + size.cx;
|
||||
else
|
||||
m_Rect.right = ParentRect.right;
|
||||
MoveWindow( &m_Rect );
|
||||
}
|
||||
}
|
||||
|
||||
UINT CInPlaceEdit::OnGetDlgCode()
|
||||
{
|
||||
return DLGC_WANTALLKEYS;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// CInPlaceEdit overrides
|
||||
|
||||
// Stoopid win95 accelerator key problem workaround - Matt Weagle.
|
||||
BOOL CInPlaceEdit::PreTranslateMessage(MSG* pMsg)
|
||||
{
|
||||
// Catch the Alt key so we don't choke if focus is going to an owner drawn button
|
||||
if (pMsg->message == WM_SYSCHAR)
|
||||
return TRUE;
|
||||
|
||||
return CWnd::PreTranslateMessage(pMsg);
|
||||
}
|
||||
|
||||
// Auto delete
|
||||
void CInPlaceEdit::PostNcDestroy()
|
||||
{
|
||||
CEdit::PostNcDestroy();
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// CInPlaceEdit implementation
|
||||
|
||||
void CInPlaceEdit::EndEdit()
|
||||
{
|
||||
CString str;
|
||||
|
||||
// EFW - BUG FIX - Clicking on a grid scroll bar in a derived class
|
||||
// that validates input can cause this to get called multiple times
|
||||
// causing assertions because the edit control goes away the first time.
|
||||
static BOOL bAlreadyEnding = FALSE;
|
||||
|
||||
if(bAlreadyEnding)
|
||||
return;
|
||||
|
||||
bAlreadyEnding = TRUE;
|
||||
GetWindowText(str);
|
||||
|
||||
// Send Notification to parent
|
||||
GV_DISPINFO dispinfo;
|
||||
|
||||
dispinfo.hdr.hwndFrom = GetSafeHwnd();
|
||||
dispinfo.hdr.idFrom = GetDlgCtrlID();
|
||||
dispinfo.hdr.code = GVN_ENDLABELEDIT;
|
||||
|
||||
dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
|
||||
dispinfo.item.row = m_nRow;
|
||||
dispinfo.item.col = m_nColumn;
|
||||
dispinfo.item.strText = str;
|
||||
dispinfo.item.lParam = (LPARAM) m_nLastChar;
|
||||
|
||||
CWnd* pOwner = GetOwner();
|
||||
if (pOwner)
|
||||
pOwner->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo );
|
||||
|
||||
// Close this window (PostNcDestroy will delete this)
|
||||
if (IsWindow(GetSafeHwnd()))
|
||||
SendMessage(WM_CLOSE, 0, 0);
|
||||
bAlreadyEnding = FALSE;
|
||||
}
|
||||
83
Server/ManageTool/GridControl/GridCtrl_src/InPlaceEdit.h
Normal file
83
Server/ManageTool/GridControl/GridCtrl_src/InPlaceEdit.h
Normal file
@@ -0,0 +1,83 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// InPlaceEdit.h : header file
|
||||
//
|
||||
// MFC Grid Control - inplace editing class
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.10+
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_INPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_)
|
||||
#define AFX_INPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
class AFX_EXT_CLASS CInPlaceEdit : public CEdit
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CInPlaceEdit(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
|
||||
int nRow, int nColumn, CString sInitText, UINT nFirstChar);
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void EndEdit();
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CInPlaceEdit)
|
||||
public:
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||
protected:
|
||||
virtual void PostNcDestroy();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CInPlaceEdit();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CInPlaceEdit)
|
||||
afx_msg void OnKillFocus(CWnd* pNewWnd);
|
||||
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
afx_msg UINT OnGetDlgCode();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
int m_nRow;
|
||||
int m_nColumn;
|
||||
CString m_sInitText;
|
||||
UINT m_nLastChar;
|
||||
BOOL m_bExitOnArrows;
|
||||
CRect m_Rect;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_INPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_)
|
||||
106
Server/ManageTool/GridControl/GridCtrl_src/MemDC.h
Normal file
106
Server/ManageTool/GridControl/GridCtrl_src/MemDC.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#if !defined(AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_)
|
||||
#define AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// MemDC.h : header file
|
||||
//
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// CMemDC - memory DC
|
||||
//
|
||||
// Author: Keith Rule
|
||||
// Email: keithr@europa.com
|
||||
// Copyright 1996-1997, Keith Rule
|
||||
//
|
||||
// You may freely use or modify this code provided this
|
||||
// Copyright is included in all derived versions.
|
||||
//
|
||||
// History - 10/3/97 Fixed scrolling bug.
|
||||
// Added print support.
|
||||
// 25 feb 98 - fixed minor assertion bug
|
||||
//
|
||||
// This class implements a memory Device Context
|
||||
|
||||
class AFX_EXT_CLASS CMemDC : public CDC
|
||||
{
|
||||
public:
|
||||
|
||||
// constructor sets up the memory DC
|
||||
CMemDC(CDC* pDC) : CDC()
|
||||
{
|
||||
ASSERT(pDC != NULL);
|
||||
|
||||
m_pDC = pDC;
|
||||
m_pOldBitmap = NULL;
|
||||
#ifndef _WIN32_WCE_NO_PRINTING
|
||||
m_bMemDC = !pDC->IsPrinting();
|
||||
#else
|
||||
m_bMemDC = FALSE;
|
||||
#endif
|
||||
|
||||
if (m_bMemDC) // Create a Memory DC
|
||||
{
|
||||
pDC->GetClipBox(&m_rect);
|
||||
CreateCompatibleDC(pDC);
|
||||
m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
|
||||
m_pOldBitmap = SelectObject(&m_bitmap);
|
||||
#ifndef _WIN32_WCE
|
||||
SetWindowOrg(m_rect.left, m_rect.top);
|
||||
#endif
|
||||
// EFW - Bug fix - Fill background in case the user has overridden
|
||||
// WM_ERASEBKGND. We end up with garbage otherwise.
|
||||
// CJM - moved to fix a bug in the fix.
|
||||
FillSolidRect(m_rect, pDC->GetBkColor());
|
||||
}
|
||||
else // Make a copy of the relevent parts of the current DC for printing
|
||||
{
|
||||
#if !defined(_WIN32_WCE) || ((_WIN32_WCE > 201) && !defined(_WIN32_WCE_NO_PRINTING))
|
||||
m_bPrinting = pDC->m_bPrinting;
|
||||
#endif
|
||||
m_hDC = pDC->m_hDC;
|
||||
m_hAttribDC = pDC->m_hAttribDC;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Destructor copies the contents of the mem DC to the original DC
|
||||
~CMemDC()
|
||||
{
|
||||
if (m_bMemDC)
|
||||
{
|
||||
// Copy the offscreen bitmap onto the screen.
|
||||
m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
|
||||
this, m_rect.left, m_rect.top, SRCCOPY);
|
||||
|
||||
//Swap back the original bitmap.
|
||||
SelectObject(m_pOldBitmap);
|
||||
} else {
|
||||
// All we need to do is replace the DC with an illegal value,
|
||||
// this keeps us from accidently deleting the handles associated with
|
||||
// the CDC that was passed to the constructor.
|
||||
m_hDC = m_hAttribDC = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow usage as a pointer
|
||||
CMemDC* operator->() {return this;}
|
||||
|
||||
// Allow usage as a pointer
|
||||
operator CMemDC*() {return this;}
|
||||
|
||||
private:
|
||||
CBitmap m_bitmap; // Offscreen bitmap
|
||||
CBitmap* m_pOldBitmap; // bitmap originally found in CMemDC
|
||||
CDC* m_pDC; // Saves CDC passed in constructor
|
||||
CRect m_rect; // Rectangle of drawing area.
|
||||
BOOL m_bMemDC; // TRUE if CDC really is a Memory DC.
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_)
|
||||
341
Server/ManageTool/GridControl/GridCtrl_src/TitleTip.cpp
Normal file
341
Server/ManageTool/GridControl/GridCtrl_src/TitleTip.cpp
Normal file
@@ -0,0 +1,341 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// TitleTip.cpp : implementation file
|
||||
//
|
||||
// Based on code by Zafir Anjum
|
||||
//
|
||||
// Adapted by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.20+
|
||||
//
|
||||
// History
|
||||
// 10 Apr 1999 Now accepts a LOGFONT pointer and
|
||||
// a tracking rect in Show(...) (Chris Maunder)
|
||||
// 18 Apr 1999 Resource leak in Show fixed by Daniel Gehriger
|
||||
// 8 Mar 2000 Added double-click fix found on codeguru
|
||||
// web site but forgot / can't find who contributed it
|
||||
// 28 Mar 2000 Aqiruse (marked with //FNA)
|
||||
// Titletips now use cell color
|
||||
// 18 Jun 2000 Delayed window creation added
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "gridctrl.h"
|
||||
|
||||
#ifndef GRIDCONTROL_NO_TITLETIPS
|
||||
|
||||
#include "TitleTip.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CTitleTip
|
||||
|
||||
CTitleTip::CTitleTip()
|
||||
{
|
||||
// Register the window class if it has not already been registered.
|
||||
WNDCLASS wndcls;
|
||||
HINSTANCE hInst = AfxGetInstanceHandle();
|
||||
if(!(::GetClassInfo(hInst, TITLETIP_CLASSNAME, &wndcls)))
|
||||
{
|
||||
// otherwise we need to register a new class
|
||||
wndcls.style = CS_SAVEBITS;
|
||||
wndcls.lpfnWndProc = ::DefWindowProc;
|
||||
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
|
||||
wndcls.hInstance = hInst;
|
||||
wndcls.hIcon = NULL;
|
||||
wndcls.hCursor = LoadCursor( hInst, IDC_ARROW );
|
||||
wndcls.hbrBackground = (HBRUSH)(COLOR_INFOBK +1);
|
||||
wndcls.lpszMenuName = NULL;
|
||||
wndcls.lpszClassName = TITLETIP_CLASSNAME;
|
||||
|
||||
if (!AfxRegisterClass(&wndcls))
|
||||
AfxThrowResourceException();
|
||||
}
|
||||
|
||||
m_dwLastLButtonDown = ULONG_MAX;
|
||||
m_dwDblClickMsecs = GetDoubleClickTime();
|
||||
m_bCreated = FALSE;
|
||||
m_pParentWnd = NULL;
|
||||
}
|
||||
|
||||
CTitleTip::~CTitleTip()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CTitleTip, CWnd)
|
||||
//{{AFX_MSG_MAP(CTitleTip)
|
||||
ON_WM_MOUSEMOVE()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CTitleTip message handlers
|
||||
|
||||
BOOL CTitleTip::Create(CWnd * pParentWnd)
|
||||
{
|
||||
ASSERT_VALID(pParentWnd);
|
||||
|
||||
// Already created?
|
||||
if (m_bCreated)
|
||||
return TRUE;
|
||||
|
||||
DWORD dwStyle = WS_BORDER | WS_POPUP;
|
||||
DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
|
||||
m_pParentWnd = pParentWnd;
|
||||
|
||||
m_bCreated = CreateEx(dwExStyle, TITLETIP_CLASSNAME, NULL, dwStyle,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
NULL, NULL, NULL );
|
||||
|
||||
return m_bCreated;
|
||||
}
|
||||
|
||||
BOOL CTitleTip::DestroyWindow()
|
||||
{
|
||||
m_bCreated = FALSE;
|
||||
|
||||
return CWnd::DestroyWindow();
|
||||
}
|
||||
|
||||
// Show - Show the titletip if needed
|
||||
// rectTitle - The rectangle within which the original
|
||||
// title is constrained - in client coordinates
|
||||
// lpszTitleText - The text to be displayed
|
||||
// xoffset - Number of pixel that the text is offset from
|
||||
// left border of the cell
|
||||
void CTitleTip::Show(CRect rectTitle, LPCTSTR lpszTitleText, int xoffset /*=0*/,
|
||||
LPRECT lpHoverRect /*=NULL*/,
|
||||
const LOGFONT* lpLogFont /*=NULL*/,
|
||||
COLORREF crTextClr /* CLR_DEFAULT */,
|
||||
COLORREF crBackClr /* CLR_DEFAULT */)
|
||||
{
|
||||
if (!IsWindow(m_hWnd))
|
||||
Create(m_pParentWnd);
|
||||
|
||||
ASSERT( ::IsWindow( GetSafeHwnd() ) );
|
||||
|
||||
if (rectTitle.IsRectEmpty())
|
||||
return;
|
||||
|
||||
// If titletip is already displayed, don't do anything.
|
||||
if( IsWindowVisible() )
|
||||
return;
|
||||
|
||||
m_rectHover = (lpHoverRect != NULL)? lpHoverRect : rectTitle;
|
||||
m_rectHover.right++; m_rectHover.bottom++;
|
||||
|
||||
m_pParentWnd->ClientToScreen( m_rectHover );
|
||||
ScreenToClient( m_rectHover );
|
||||
|
||||
// Do not display the titletip is app does not have focus
|
||||
if( GetFocus() == NULL )
|
||||
return;
|
||||
|
||||
// Define the rectangle outside which the titletip will be hidden.
|
||||
// We add a buffer of one pixel around the rectangle
|
||||
m_rectTitle.top = -1;
|
||||
m_rectTitle.left = -xoffset-1;
|
||||
m_rectTitle.right = rectTitle.Width()-xoffset;
|
||||
m_rectTitle.bottom = rectTitle.Height()+1;
|
||||
|
||||
// Determine the width of the text
|
||||
m_pParentWnd->ClientToScreen( rectTitle );
|
||||
|
||||
CClientDC dc(this);
|
||||
CString strTitle = _T("");
|
||||
strTitle += _T(" ");
|
||||
strTitle += lpszTitleText;
|
||||
strTitle += _T(" ");
|
||||
|
||||
CFont font, *pOldFont = NULL;
|
||||
if (lpLogFont)
|
||||
{
|
||||
font.CreateFontIndirect(lpLogFont);
|
||||
pOldFont = dc.SelectObject( &font );
|
||||
}
|
||||
else
|
||||
{
|
||||
// use same font as ctrl
|
||||
pOldFont = dc.SelectObject( m_pParentWnd->GetFont() );
|
||||
}
|
||||
|
||||
CSize size = dc.GetTextExtent( strTitle );
|
||||
|
||||
TEXTMETRIC tm;
|
||||
dc.GetTextMetrics(&tm);
|
||||
size.cx += tm.tmOverhang;
|
||||
|
||||
CRect rectDisplay = rectTitle;
|
||||
rectDisplay.left += xoffset;
|
||||
rectDisplay.right = rectDisplay.left + size.cx + xoffset;
|
||||
|
||||
// Do not display if the text fits within available space
|
||||
if ( rectDisplay.right > rectTitle.right-xoffset )
|
||||
{
|
||||
// Show the titletip
|
||||
SetWindowPos( &wndTop, rectDisplay.left, rectDisplay.top,
|
||||
rectDisplay.Width(), rectDisplay.Height(),
|
||||
SWP_SHOWWINDOW|SWP_NOACTIVATE );
|
||||
|
||||
// FNA - handle colors correctly
|
||||
if (crBackClr != CLR_DEFAULT)
|
||||
{
|
||||
CBrush backBrush(crBackClr);
|
||||
CBrush* pOldBrush = dc.SelectObject(&backBrush);
|
||||
CRect rect;
|
||||
dc.GetClipBox(&rect); // Erase the area needed
|
||||
|
||||
dc.PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
|
||||
dc.SelectObject(pOldBrush);
|
||||
}
|
||||
// Set color
|
||||
if (crTextClr != CLR_DEFAULT)//FNA
|
||||
dc.SetTextColor(crTextClr);//FA
|
||||
|
||||
dc.SetBkMode( TRANSPARENT );
|
||||
dc.TextOut( 0, 0, strTitle );
|
||||
SetCapture();
|
||||
}
|
||||
|
||||
dc.SelectObject( pOldFont );
|
||||
}
|
||||
|
||||
void CTitleTip::Hide()
|
||||
{
|
||||
if (!::IsWindow(GetSafeHwnd()))
|
||||
return;
|
||||
|
||||
if (GetCapture()->GetSafeHwnd() == GetSafeHwnd())
|
||||
ReleaseCapture();
|
||||
|
||||
ShowWindow( SW_HIDE );
|
||||
}
|
||||
|
||||
void CTitleTip::OnMouseMove(UINT nFlags, CPoint point)
|
||||
{
|
||||
if (!m_rectHover.PtInRect(point))
|
||||
{
|
||||
Hide();
|
||||
|
||||
// Forward the message
|
||||
ClientToScreen( &point );
|
||||
CWnd *pWnd = WindowFromPoint( point );
|
||||
if ( pWnd == this )
|
||||
pWnd = m_pParentWnd;
|
||||
|
||||
int hittest = (int)pWnd->SendMessage(WM_NCHITTEST,0,MAKELONG(point.x,point.y));
|
||||
|
||||
if (hittest == HTCLIENT) {
|
||||
pWnd->ScreenToClient( &point );
|
||||
pWnd->PostMessage( WM_MOUSEMOVE, nFlags, MAKELONG(point.x,point.y) );
|
||||
} else {
|
||||
pWnd->PostMessage( WM_NCMOUSEMOVE, hittest, MAKELONG(point.x,point.y) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CTitleTip::PreTranslateMessage(MSG* pMsg)
|
||||
{
|
||||
// Used to qualify WM_LBUTTONDOWN messages as double-clicks
|
||||
DWORD dwTick=0;
|
||||
BOOL bDoubleClick=FALSE;
|
||||
|
||||
CWnd *pWnd;
|
||||
int hittest;
|
||||
switch (pMsg->message)
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
// Get tick count since last LButtonDown
|
||||
dwTick = GetTickCount();
|
||||
bDoubleClick = ((dwTick - m_dwLastLButtonDown) <= m_dwDblClickMsecs);
|
||||
m_dwLastLButtonDown = dwTick;
|
||||
// NOTE: DO NOT ADD break; STATEMENT HERE! Let code fall through
|
||||
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
{
|
||||
POINTS pts = MAKEPOINTS( pMsg->lParam );
|
||||
POINT point;
|
||||
point.x = pts.x;
|
||||
point.y = pts.y;
|
||||
|
||||
ClientToScreen( &point );
|
||||
Hide();
|
||||
|
||||
pWnd = WindowFromPoint( point );
|
||||
if (!pWnd)
|
||||
return CWnd::PreTranslateMessage(pMsg);
|
||||
|
||||
if( pWnd->GetSafeHwnd() == GetSafeHwnd())
|
||||
pWnd = m_pParentWnd;
|
||||
|
||||
hittest = (int)pWnd->SendMessage(WM_NCHITTEST,0,MAKELONG(point.x,point.y));
|
||||
|
||||
if (hittest == HTCLIENT)
|
||||
{
|
||||
pWnd->ScreenToClient( &point );
|
||||
pMsg->lParam = MAKELONG(point.x,point.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (pMsg->message) {
|
||||
case WM_LBUTTONDOWN:
|
||||
pMsg->message = WM_NCLBUTTONDOWN;
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
pMsg->message = WM_NCRBUTTONDOWN;
|
||||
break;
|
||||
case WM_MBUTTONDOWN:
|
||||
pMsg->message = WM_NCMBUTTONDOWN;
|
||||
break;
|
||||
}
|
||||
pMsg->wParam = hittest;
|
||||
pMsg->lParam = MAKELONG(point.x,point.y);
|
||||
}
|
||||
|
||||
|
||||
// If this is the 2nd WM_LBUTTONDOWN in x milliseconds,
|
||||
// post a WM_LBUTTONDBLCLK message instead of a single click.
|
||||
pWnd->PostMessage( bDoubleClick ? WM_LBUTTONDBLCLK : pMsg->message,
|
||||
pMsg->wParam,
|
||||
pMsg->lParam);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
Hide();
|
||||
m_pParentWnd->PostMessage( pMsg->message, pMsg->wParam, pMsg->lParam );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if( GetFocus() == NULL )
|
||||
{
|
||||
Hide();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return CWnd::PreTranslateMessage(pMsg);
|
||||
}
|
||||
|
||||
#endif // GRIDCONTROL_NO_TITLETIPS
|
||||
87
Server/ManageTool/GridControl/GridCtrl_src/TitleTip.h
Normal file
87
Server/ManageTool/GridControl/GridCtrl_src/TitleTip.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Titletip.h : header file
|
||||
//
|
||||
// MFC Grid Control - cell titletips
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2001. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.10+
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_TITLETIP_H__C7165DA1_187F_11D1_992F_895E185F9C72__INCLUDED_)
|
||||
#define AFX_TITLETIP_H__C7165DA1_187F_11D1_992F_895E185F9C72__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#define TITLETIP_CLASSNAME _T("ZTitleTip")
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CTitleTip window
|
||||
|
||||
class AFX_EXT_CLASS CTitleTip : public CWnd
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CTitleTip();
|
||||
virtual ~CTitleTip();
|
||||
virtual BOOL Create( CWnd *pParentWnd);
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
void SetParentWnd(CWnd* pParentWnd) { m_pParentWnd = pParentWnd; }
|
||||
CWnd* GetParentWnd() { return m_pParentWnd; }
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void Show(CRect rectTitle, LPCTSTR lpszTitleText,
|
||||
int xoffset = 0, LPRECT lpHoverRect = NULL,
|
||||
const LOGFONT* lpLogFont = NULL,
|
||||
COLORREF crTextClr = CLR_DEFAULT, COLORREF crBackClr = CLR_DEFAULT);
|
||||
void Hide();
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CTitleTip)
|
||||
public:
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||
virtual BOOL DestroyWindow();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
CWnd *m_pParentWnd;
|
||||
CRect m_rectTitle;
|
||||
CRect m_rectHover;
|
||||
DWORD m_dwLastLButtonDown;
|
||||
DWORD m_dwDblClickMsecs;
|
||||
BOOL m_bCreated;
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CTitleTip)
|
||||
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_TITLETIP_H__C7165DA1_187F_11D1_992F_895E185F9C72__INCLUDED_)
|
||||
160
Server/ManageTool/GridControl/NewCellTypes/GridCellCheck.cpp
Normal file
160
Server/ManageTool/GridControl/NewCellTypes/GridCellCheck.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
// GridCellCheck.cpp : implementation file
|
||||
//
|
||||
// MFC Grid Control - Main grid cell class
|
||||
//
|
||||
// Provides the implementation for a combobox cell type of the
|
||||
// grid control.
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// Parts of the code contained in this file are based on the original
|
||||
// CInPlaceList from http://www.codeguru.com/listview
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.22+
|
||||
//
|
||||
// History:
|
||||
// 23 Jul 2001 - Complete rewrite
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "../GridCtrl_src/GridCell.h"
|
||||
#include "../GridCtrl_src/GridCtrl.h"
|
||||
|
||||
#include "GridCellCheck.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
IMPLEMENT_DYNCREATE(CGridCellCheck, CGridCell)
|
||||
|
||||
CGridCellCheck::CGridCellCheck() : CGridCell()
|
||||
{
|
||||
m_bChecked = FALSE;
|
||||
//m_Rect.IsRectNull();
|
||||
}
|
||||
|
||||
CSize CGridCellCheck::GetCellExtent(CDC* pDC)
|
||||
{
|
||||
// Using SM_CXHSCROLL as a guide to the size of the checkbox
|
||||
int nWidth = GetSystemMetrics(SM_CXHSCROLL) + 2*GetMargin();
|
||||
return CGridCell::GetCellExtent(pDC) + CSize(nWidth, nWidth);
|
||||
}
|
||||
|
||||
// i/o: i=dims of cell rect; o=dims of text rect
|
||||
BOOL CGridCellCheck::GetTextRect( LPRECT pRect)
|
||||
{
|
||||
BOOL bResult = CGridCell::GetTextRect(pRect);
|
||||
if (bResult)
|
||||
{
|
||||
int nWidth = GetSystemMetrics(SM_CXHSCROLL) + 2*GetMargin();
|
||||
pRect->left += nWidth;
|
||||
if (pRect->left > pRect->right)
|
||||
pRect->left = pRect->right;
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
|
||||
// Override draw so that when the cell is selected, a drop arrow is shown in the RHS.
|
||||
BOOL CGridCellCheck::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd /*=TRUE*/)
|
||||
{
|
||||
BOOL bResult = CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd);
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
// Store the cell's dimensions for later
|
||||
m_Rect = rect;
|
||||
|
||||
CRect CheckRect = GetCheckPlacement();
|
||||
rect.left = CheckRect.right;
|
||||
|
||||
// enough room to draw?
|
||||
// if (CheckRect.Width() < rect.Width() && CheckRect.Height() < rect.Height()) {
|
||||
|
||||
// Do the draw
|
||||
pDC->DrawFrameControl(GetCheckPlacement(), DFC_BUTTON,
|
||||
(m_bChecked)? DFCS_BUTTONCHECK | DFCS_CHECKED : DFCS_BUTTONCHECK);
|
||||
|
||||
// }
|
||||
#endif
|
||||
return bResult;
|
||||
}
|
||||
|
||||
void CGridCellCheck::OnClick(CPoint PointCellRelative)
|
||||
{
|
||||
// PointCellRelative is relative to the topleft of the cell. Convert to client coords
|
||||
PointCellRelative += m_Rect.TopLeft();
|
||||
|
||||
// GetCheckPlacement returns the checkbox dimensions in client coords. Only check/
|
||||
// uncheck if the user clicked in the box
|
||||
if (GetCheckPlacement().PtInRect(PointCellRelative))
|
||||
{
|
||||
m_bChecked = !m_bChecked;
|
||||
GetGrid()->InvalidateRect(m_Rect);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Operations
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL CGridCellCheck::SetCheck(BOOL bChecked /*=TRUE*/)
|
||||
{
|
||||
BOOL bTemp = m_bChecked;
|
||||
m_bChecked = bChecked;
|
||||
if (!m_Rect.IsRectEmpty())
|
||||
GetGrid()->InvalidateRect(m_Rect);
|
||||
|
||||
return bTemp;
|
||||
}
|
||||
|
||||
BOOL CGridCellCheck::GetCheck()
|
||||
{
|
||||
return m_bChecked;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Protected implementation
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Returns the dimensions and placement of the checkbox in client coords.
|
||||
CRect CGridCellCheck::GetCheckPlacement()
|
||||
{
|
||||
int nWidth = GetSystemMetrics(SM_CXHSCROLL);
|
||||
CRect place = m_Rect + CSize(GetMargin(), GetMargin());
|
||||
place.right = place.left + nWidth;
|
||||
place.bottom = place.top + nWidth;
|
||||
|
||||
/* for centering
|
||||
int nDiff = (place.Width() - nWidth)/2;
|
||||
if (nDiff > 0)
|
||||
{
|
||||
place.left += nDiff;
|
||||
place.right = place.left + nWidth;
|
||||
}
|
||||
nDiff = (place.Height() - nWidth)/2;
|
||||
if (nDiff > 0)
|
||||
{
|
||||
place.top += nDiff;
|
||||
place.bottom = place.top + nWidth;
|
||||
}
|
||||
*/
|
||||
|
||||
return place;
|
||||
}
|
||||
68
Server/ManageTool/GridControl/NewCellTypes/GridCellCheck.h
Normal file
68
Server/ManageTool/GridControl/NewCellTypes/GridCellCheck.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#if !defined(AFX_GRIDCELLCHECK_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
|
||||
#define AFX_GRIDCELLCHECK_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GridCellCheck.h : header file
|
||||
//
|
||||
// MFC Grid Control - Grid combo cell class header file
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.22+
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "../GridCtrl_src/GridCell.h"
|
||||
|
||||
|
||||
class AFX_EXT_CLASS CGridCellCheck : public CGridCell
|
||||
{
|
||||
friend class CGridCtrl;
|
||||
DECLARE_DYNCREATE(CGridCellCheck)
|
||||
|
||||
public:
|
||||
CGridCellCheck();
|
||||
|
||||
public:
|
||||
BOOL SetCheck(BOOL bChecked = TRUE);
|
||||
BOOL GetCheck();
|
||||
|
||||
// Operations
|
||||
virtual CSize GetCellExtent(CDC* pDC);
|
||||
virtual void OnClick( CPoint PointCellRelative);
|
||||
virtual BOOL GetTextRect( LPRECT pRect);
|
||||
|
||||
protected:
|
||||
CRect GetCheckPlacement();
|
||||
|
||||
virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd = TRUE);
|
||||
|
||||
protected:
|
||||
BOOL m_bChecked;
|
||||
CRect m_Rect;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_GRIDCELLCHECK_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
|
||||
483
Server/ManageTool/GridControl/NewCellTypes/GridCellCombo.cpp
Normal file
483
Server/ManageTool/GridControl/NewCellTypes/GridCellCombo.cpp
Normal file
@@ -0,0 +1,483 @@
|
||||
// GridCellCombo.cpp : implementation file
|
||||
//
|
||||
// MFC Grid Control - Main grid cell class
|
||||
//
|
||||
// Provides the implementation for a combobox cell type of the
|
||||
// grid control.
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2001. All Rights Reserved.
|
||||
//
|
||||
// Parts of the code contained in this file are based on the original
|
||||
// CInPlaceList from http://www.codeguru.com/listview
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.22+
|
||||
//
|
||||
// History:
|
||||
// 6 Aug 1998 - Added CComboEdit to subclass the edit control - code
|
||||
// provided by Roelf Werkman <rdw@inn.nl>. Added nID to
|
||||
// the constructor param list.
|
||||
// 29 Nov 1998 - bug fix in onkeydown (Markus Irtenkauf)
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "../GridCtrl_src/GridCell.h"
|
||||
#include "../GridCtrl_src/GridCtrl.h"
|
||||
|
||||
#include "GridCellCombo.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CComboEdit
|
||||
|
||||
CComboEdit::CComboEdit()
|
||||
{
|
||||
}
|
||||
|
||||
CComboEdit::~CComboEdit()
|
||||
{
|
||||
}
|
||||
|
||||
// Stoopid win95 accelerator key problem workaround - Matt Weagle.
|
||||
BOOL CComboEdit::PreTranslateMessage(MSG* pMsg)
|
||||
{
|
||||
// Make sure that the keystrokes continue to the appropriate handlers
|
||||
if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP)
|
||||
{
|
||||
::TranslateMessage(pMsg);
|
||||
::DispatchMessage(pMsg);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Catch the Alt key so we don't choke if focus is going to an owner drawn button
|
||||
if (pMsg->message == WM_SYSCHAR)
|
||||
return TRUE;
|
||||
|
||||
return CEdit::PreTranslateMessage(pMsg);
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CComboEdit, CEdit)
|
||||
//{{AFX_MSG_MAP(CComboEdit)
|
||||
ON_WM_KILLFOCUS()
|
||||
ON_WM_KEYDOWN()
|
||||
ON_WM_KEYUP()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CComboEdit message handlers
|
||||
|
||||
void CComboEdit::OnKillFocus(CWnd* pNewWnd)
|
||||
{
|
||||
CEdit::OnKillFocus(pNewWnd);
|
||||
|
||||
CInPlaceList* pOwner = (CInPlaceList*) GetOwner(); // This MUST be a CInPlaceList
|
||||
if (pOwner)
|
||||
pOwner->EndEdit();
|
||||
}
|
||||
|
||||
void CComboEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||||
{
|
||||
if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
|
||||
nChar == VK_DOWN || nChar == VK_UP ||
|
||||
nChar == VK_RIGHT || nChar == VK_LEFT) &&
|
||||
(GetKeyState(VK_CONTROL) < 0 && GetDlgCtrlID() == IDC_COMBOEDIT))
|
||||
{
|
||||
CWnd* pOwner = GetOwner();
|
||||
if (pOwner)
|
||||
pOwner->SendMessage(WM_KEYDOWN, nChar, nRepCnt+ (((DWORD)nFlags)<<16));
|
||||
return;
|
||||
}
|
||||
|
||||
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
|
||||
}
|
||||
|
||||
void CComboEdit::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||||
{
|
||||
if (nChar == VK_ESCAPE)
|
||||
{
|
||||
CWnd* pOwner = GetOwner();
|
||||
if (pOwner)
|
||||
pOwner->SendMessage(WM_KEYUP, nChar, nRepCnt + (((DWORD)nFlags)<<16));
|
||||
return;
|
||||
}
|
||||
|
||||
if (nChar == VK_TAB || nChar == VK_RETURN || nChar == VK_ESCAPE)
|
||||
{
|
||||
CWnd* pOwner = GetOwner();
|
||||
if (pOwner)
|
||||
pOwner->SendMessage(WM_KEYUP, nChar, nRepCnt + (((DWORD)nFlags)<<16));
|
||||
return;
|
||||
}
|
||||
|
||||
CEdit::OnKeyUp(nChar, nRepCnt, nFlags);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CInPlaceList
|
||||
|
||||
CInPlaceList::CInPlaceList(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
|
||||
int nRow, int nColumn,
|
||||
COLORREF crFore, COLORREF crBack,
|
||||
CStringArray& Items, CString sInitText,
|
||||
UINT nFirstChar)
|
||||
{
|
||||
m_crForeClr = crFore;
|
||||
m_crBackClr = crBack;
|
||||
|
||||
m_nNumLines = 4;
|
||||
m_sInitText = sInitText;
|
||||
m_nRow = nRow;
|
||||
m_nCol = nColumn;
|
||||
m_nLastChar = 0;
|
||||
m_bExitOnArrows = FALSE; //(nFirstChar != VK_LBUTTON); // If mouse click brought us here,
|
||||
|
||||
// Create the combobox
|
||||
DWORD dwComboStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL|
|
||||
CBS_AUTOHSCROLL | dwStyle;
|
||||
int nHeight = rect.Height();
|
||||
rect.bottom = rect.bottom + m_nNumLines*nHeight + ::GetSystemMetrics(SM_CYHSCROLL);
|
||||
if (!Create(dwComboStyle, rect, pParent, nID)) return;
|
||||
|
||||
// Add the strings
|
||||
for (int i = 0; i < Items.GetSize(); i++)
|
||||
AddString(Items[i]);
|
||||
|
||||
SetFont(pParent->GetFont());
|
||||
SetItemHeight(-1, nHeight);
|
||||
|
||||
int nMaxLength = GetCorrectDropWidth();
|
||||
/*
|
||||
if (nMaxLength > rect.Width())
|
||||
rect.right = rect.left + nMaxLength;
|
||||
// Resize the edit window and the drop down window
|
||||
MoveWindow(rect);
|
||||
*/
|
||||
|
||||
SetDroppedWidth(nMaxLength);
|
||||
|
||||
SetHorizontalExtent(0); // no horz scrolling
|
||||
|
||||
// Set the initial text to m_sInitText
|
||||
if (::IsWindow(m_hWnd) && SelectString(-1, m_sInitText) == CB_ERR)
|
||||
SetWindowText(m_sInitText); // No text selected, so restore what was there before
|
||||
|
||||
ShowDropDown();
|
||||
|
||||
// Subclass the combobox edit control if style includes CBS_DROPDOWN
|
||||
if ((dwStyle & CBS_DROPDOWNLIST) != CBS_DROPDOWNLIST)
|
||||
{
|
||||
m_edit.SubclassDlgItem(IDC_COMBOEDIT, this);
|
||||
SetFocus();
|
||||
switch (nFirstChar)
|
||||
{
|
||||
case VK_LBUTTON:
|
||||
case VK_RETURN: m_edit.SetSel((int)_tcslen(m_sInitText), -1); return;
|
||||
case VK_BACK: m_edit.SetSel((int)_tcslen(m_sInitText), -1); break;
|
||||
case VK_DOWN:
|
||||
case VK_UP:
|
||||
case VK_RIGHT:
|
||||
case VK_LEFT:
|
||||
case VK_NEXT:
|
||||
case VK_PRIOR:
|
||||
case VK_HOME:
|
||||
case VK_END: m_edit.SetSel(0,-1); return;
|
||||
default: m_edit.SetSel(0,-1);
|
||||
}
|
||||
SendMessage(WM_CHAR, nFirstChar);
|
||||
}
|
||||
else
|
||||
SetFocus();
|
||||
}
|
||||
|
||||
CInPlaceList::~CInPlaceList()
|
||||
{
|
||||
}
|
||||
|
||||
void CInPlaceList::EndEdit()
|
||||
{
|
||||
CString str;
|
||||
if (::IsWindow(m_hWnd))
|
||||
GetWindowText(str);
|
||||
|
||||
// Send Notification to parent
|
||||
GV_DISPINFO dispinfo;
|
||||
|
||||
dispinfo.hdr.hwndFrom = GetSafeHwnd();
|
||||
dispinfo.hdr.idFrom = GetDlgCtrlID();
|
||||
dispinfo.hdr.code = GVN_ENDLABELEDIT;
|
||||
|
||||
dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
|
||||
dispinfo.item.row = m_nRow;
|
||||
dispinfo.item.col = m_nCol;
|
||||
dispinfo.item.strText = str;
|
||||
dispinfo.item.lParam = (LPARAM) m_nLastChar;
|
||||
|
||||
CWnd* pOwner = GetOwner();
|
||||
if (IsWindow(pOwner->GetSafeHwnd()))
|
||||
pOwner->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo );
|
||||
|
||||
// Close this window (PostNcDestroy will delete this)
|
||||
if (::IsWindow(m_hWnd))
|
||||
PostMessage(WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
int CInPlaceList::GetCorrectDropWidth()
|
||||
{
|
||||
const int nMaxWidth = 200; // don't let the box be bigger than this
|
||||
|
||||
// Reset the dropped width
|
||||
int nNumEntries = GetCount();
|
||||
int nWidth = 0;
|
||||
CString str;
|
||||
|
||||
CClientDC dc(this);
|
||||
int nSave = dc.SaveDC();
|
||||
dc.SelectObject(GetFont());
|
||||
|
||||
int nScrollWidth = ::GetSystemMetrics(SM_CXVSCROLL);
|
||||
for (int i = 0; i < nNumEntries; i++)
|
||||
{
|
||||
GetLBText(i, str);
|
||||
int nLength = dc.GetTextExtent(str).cx + nScrollWidth;
|
||||
nWidth = max(nWidth, nLength);
|
||||
}
|
||||
|
||||
// Add margin space to the calculations
|
||||
nWidth += dc.GetTextExtent("0").cx;
|
||||
|
||||
dc.RestoreDC(nSave);
|
||||
|
||||
nWidth = min(nWidth, nMaxWidth);
|
||||
|
||||
return nWidth;
|
||||
//SetDroppedWidth(nWidth);
|
||||
}
|
||||
|
||||
/*
|
||||
// Fix by Ray (raybie@Exabyte.COM)
|
||||
void CInPlaceList::OnSelendOK()
|
||||
{
|
||||
int iIndex = GetCurSel();
|
||||
if( iIndex != CB_ERR)
|
||||
{
|
||||
CString strLbText;
|
||||
GetLBText( iIndex, strLbText);
|
||||
|
||||
if (!((GetStyle() & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST))
|
||||
m_edit.SetWindowText( strLbText);
|
||||
}
|
||||
|
||||
GetParent()->SetFocus();
|
||||
}
|
||||
*/
|
||||
|
||||
void CInPlaceList::PostNcDestroy()
|
||||
{
|
||||
CComboBox::PostNcDestroy();
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CInPlaceList, CComboBox)
|
||||
//{{AFX_MSG_MAP(CInPlaceList)
|
||||
ON_WM_KILLFOCUS()
|
||||
ON_WM_KEYDOWN()
|
||||
ON_WM_KEYUP()
|
||||
ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropdown)
|
||||
ON_WM_GETDLGCODE()
|
||||
ON_WM_CTLCOLOR_REFLECT()
|
||||
//}}AFX_MSG_MAP
|
||||
//ON_CONTROL_REFLECT(CBN_SELENDOK, OnSelendOK)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CInPlaceList message handlers
|
||||
|
||||
UINT CInPlaceList::OnGetDlgCode()
|
||||
{
|
||||
return DLGC_WANTALLKEYS;
|
||||
}
|
||||
|
||||
void CInPlaceList::OnDropdown()
|
||||
{
|
||||
SetDroppedWidth(GetCorrectDropWidth());
|
||||
}
|
||||
|
||||
void CInPlaceList::OnKillFocus(CWnd* pNewWnd)
|
||||
{
|
||||
CComboBox::OnKillFocus(pNewWnd);
|
||||
|
||||
if (GetSafeHwnd() == pNewWnd->GetSafeHwnd())
|
||||
return;
|
||||
|
||||
// Only end editing on change of focus if we're using the CBS_DROPDOWNLIST style
|
||||
if ((GetStyle() & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST)
|
||||
EndEdit();
|
||||
}
|
||||
|
||||
// If an arrow key (or associated) is pressed, then exit if
|
||||
// a) The Ctrl key was down, or
|
||||
// b) m_bExitOnArrows == TRUE
|
||||
void CInPlaceList::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||||
{
|
||||
if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
|
||||
nChar == VK_DOWN || nChar == VK_UP ||
|
||||
nChar == VK_RIGHT || nChar == VK_LEFT) &&
|
||||
(m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0))
|
||||
{
|
||||
m_nLastChar = nChar;
|
||||
GetParent()->SetFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
CComboBox::OnKeyDown(nChar, nRepCnt, nFlags);
|
||||
}
|
||||
|
||||
// Need to keep a lookout for Tabs, Esc and Returns.
|
||||
void CInPlaceList::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||||
{
|
||||
if (nChar == VK_ESCAPE)
|
||||
SetWindowText(m_sInitText); // restore previous text
|
||||
|
||||
if (nChar == VK_TAB || nChar == VK_RETURN || nChar == VK_ESCAPE)
|
||||
{
|
||||
m_nLastChar = nChar;
|
||||
GetParent()->SetFocus(); // This will destroy this window
|
||||
return;
|
||||
}
|
||||
|
||||
CComboBox::OnKeyUp(nChar, nRepCnt, nFlags);
|
||||
}
|
||||
|
||||
HBRUSH CInPlaceList::CtlColor(CDC* /*pDC*/, UINT /*nCtlColor*/)
|
||||
{
|
||||
/*
|
||||
static CBrush brush(m_crBackClr);
|
||||
pDC->SetTextColor(m_crForeClr);
|
||||
pDC->SetBkMode(TRANSPARENT);
|
||||
return (HBRUSH) brush.GetSafeHandle();
|
||||
*/
|
||||
|
||||
// TODO: Return a non-NULL brush if the parent's handler should not be called
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGridCellCombo
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
IMPLEMENT_DYNCREATE(CGridCellCombo, CGridCell)
|
||||
|
||||
CGridCellCombo::CGridCellCombo() : CGridCell()
|
||||
{
|
||||
SetStyle(CBS_DROPDOWN); // CBS_DROPDOWN, CBS_DROPDOWNLIST, CBS_SIMPLE, CBS_SORT
|
||||
}
|
||||
|
||||
// Create a control to do the editing
|
||||
BOOL CGridCellCombo::Edit(int nRow, int nCol, CRect rect, CPoint /* point */, UINT nID, UINT nChar)
|
||||
{
|
||||
m_bEditing = TRUE;
|
||||
|
||||
// CInPlaceList auto-deletes itself
|
||||
m_pEditWnd = new CInPlaceList(GetGrid(), rect, GetStyle(), nID, nRow, nCol,
|
||||
GetTextClr(), GetBackClr(), m_Strings, GetText(), nChar);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CWnd* CGridCellCombo::GetEditWnd() const
|
||||
{
|
||||
if (m_pEditWnd && (m_pEditWnd->GetStyle() & CBS_DROPDOWNLIST) != CBS_DROPDOWNLIST )
|
||||
return &(((CInPlaceList*)m_pEditWnd)->m_edit);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CSize CGridCellCombo::GetCellExtent(CDC* pDC)
|
||||
{
|
||||
CSize sizeScroll(GetSystemMetrics(SM_CXVSCROLL), GetSystemMetrics(SM_CYHSCROLL));
|
||||
|
||||
return CGridCell::GetCellExtent(pDC) + sizeScroll;
|
||||
}
|
||||
|
||||
// Cancel the editing.
|
||||
void CGridCellCombo::EndEdit()
|
||||
{
|
||||
if (m_pEditWnd)
|
||||
((CInPlaceList*)m_pEditWnd)->EndEdit();
|
||||
}
|
||||
|
||||
// Override draw so that when the cell is selected, a drop arrow is shown in the RHS.
|
||||
BOOL CGridCellCombo::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd /*=TRUE*/)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
return CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd);
|
||||
#else
|
||||
// Cell selected?
|
||||
//if ( !IsFixed() && IsFocused())
|
||||
if (GetGrid()->IsCellEditable(nRow, nCol) && !IsEditing())
|
||||
{
|
||||
// Get the size of the scroll box
|
||||
CSize sizeScroll(GetSystemMetrics(SM_CXVSCROLL), GetSystemMetrics(SM_CYHSCROLL));
|
||||
|
||||
// enough room to draw?
|
||||
if (sizeScroll.cy < rect.Width() && sizeScroll.cy < rect.Height())
|
||||
{
|
||||
// Draw control at RHS of cell
|
||||
CRect ScrollRect = rect;
|
||||
ScrollRect.left = rect.right - sizeScroll.cx;
|
||||
ScrollRect.bottom = rect.top + sizeScroll.cy;
|
||||
|
||||
// Do the draw
|
||||
pDC->DrawFrameControl(ScrollRect, DFC_SCROLL, DFCS_SCROLLDOWN);
|
||||
|
||||
// Adjust the remaining space in the cell
|
||||
rect.right = ScrollRect.left;
|
||||
}
|
||||
}
|
||||
|
||||
CString strTempText = GetText();
|
||||
if (IsEditing())
|
||||
SetText(_T(""));
|
||||
|
||||
// drop through and complete the cell drawing using the base class' method
|
||||
BOOL bResult = CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd);
|
||||
|
||||
if (IsEditing())
|
||||
SetText(strTempText);
|
||||
|
||||
return bResult;
|
||||
#endif
|
||||
}
|
||||
|
||||
// For setting the strings that will be displayed in the drop list
|
||||
void CGridCellCombo::SetOptions(CStringArray& ar)
|
||||
{
|
||||
m_Strings.RemoveAll();
|
||||
for (int i = 0; i < ar.GetSize(); i++)
|
||||
m_Strings.Add(ar[i]);
|
||||
}
|
||||
177
Server/ManageTool/GridControl/NewCellTypes/GridCellCombo.h
Normal file
177
Server/ManageTool/GridControl/NewCellTypes/GridCellCombo.h
Normal file
@@ -0,0 +1,177 @@
|
||||
#if !defined(AFX_GRIDCELLCOMBO_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
|
||||
#define AFX_GRIDCELLCOMBO_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GridCellCombo.h : header file
|
||||
//
|
||||
// MFC Grid Control - Grid combo cell class header file
|
||||
//
|
||||
// Written by Chris Maunder <cmaunder@mail.com>
|
||||
// Copyright (c) 1998-2002. All Rights Reserved.
|
||||
//
|
||||
// This code may be used in compiled form in any way you desire. This
|
||||
// file may be redistributed unmodified by any means PROVIDING it is
|
||||
// not sold for profit without the authors written consent, and
|
||||
// providing that this notice and the authors name and all copyright
|
||||
// notices remains intact.
|
||||
//
|
||||
// An email letting me know how you are using it would be nice as well.
|
||||
//
|
||||
// This file is provided "as is" with no expressed or implied warranty.
|
||||
// The author accepts no liability for any damage/loss of business that
|
||||
// this product may cause.
|
||||
//
|
||||
// For use with CGridCtrl v2.10
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "../GridCtrl_src/GridCell.h"
|
||||
|
||||
|
||||
class AFX_EXT_CLASS CGridCellCombo : public CGridCell
|
||||
{
|
||||
friend class CGridCtrl;
|
||||
DECLARE_DYNCREATE(CGridCellCombo)
|
||||
|
||||
public:
|
||||
CGridCellCombo();
|
||||
|
||||
// editing cells
|
||||
public:
|
||||
virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar);
|
||||
virtual CWnd* GetEditWnd() const;
|
||||
virtual void EndEdit();
|
||||
|
||||
// Operations
|
||||
public:
|
||||
virtual CSize GetCellExtent(CDC* pDC);
|
||||
|
||||
// CGridCellCombo specific calls
|
||||
public:
|
||||
void SetOptions(CStringArray& ar);
|
||||
void SetStyle(DWORD dwStyle) { m_dwStyle = dwStyle; }
|
||||
DWORD GetStyle() { return m_dwStyle; }
|
||||
|
||||
protected:
|
||||
virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd = TRUE);
|
||||
|
||||
CStringArray m_Strings;
|
||||
DWORD m_dwStyle;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CComboEdit window
|
||||
|
||||
#define IDC_COMBOEDIT 1001
|
||||
|
||||
class AFX_EXT_CLASS CComboEdit : public CEdit
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CComboEdit();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CComboEdit)
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CComboEdit();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CComboEdit)
|
||||
afx_msg void OnKillFocus(CWnd* pNewWnd);
|
||||
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
//}}AFX_MSG
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CInPlaceList window
|
||||
|
||||
class AFX_EXT_CLASS CInPlaceList : public CComboBox
|
||||
{
|
||||
friend class CComboEdit;
|
||||
|
||||
// Construction
|
||||
public:
|
||||
CInPlaceList(CWnd* pParent, // parent
|
||||
CRect& rect, // dimensions & location
|
||||
DWORD dwStyle, // window/combobox style
|
||||
UINT nID, // control ID
|
||||
int nRow, int nColumn, // row and column
|
||||
COLORREF crFore, COLORREF crBack, // Foreground, background colour
|
||||
CStringArray& Items, // Items in list
|
||||
CString sInitText, // initial selection
|
||||
UINT nFirstChar); // first character to pass to control
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
CComboEdit m_edit; // subclassed edit control
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CInPlaceList)
|
||||
protected:
|
||||
virtual void PostNcDestroy();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CInPlaceList();
|
||||
void EndEdit();
|
||||
|
||||
protected:
|
||||
int GetCorrectDropWidth();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CInPlaceList)
|
||||
afx_msg void OnKillFocus(CWnd* pNewWnd);
|
||||
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
afx_msg void OnDropdown();
|
||||
afx_msg UINT OnGetDlgCode();
|
||||
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
|
||||
//}}AFX_MSG
|
||||
//afx_msg void OnSelendOK();
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
int m_nNumLines;
|
||||
CString m_sInitText;
|
||||
int m_nRow;
|
||||
int m_nCol;
|
||||
UINT m_nLastChar;
|
||||
BOOL m_bExitOnArrows;
|
||||
COLORREF m_crForeClr, m_crBackClr;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_GRIDCELLCOMBO_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
|
||||
257
Server/ManageTool/GridControl/NewCellTypes/GridCellDateTime.cpp
Normal file
257
Server/ManageTool/GridControl/NewCellTypes/GridCellDateTime.cpp
Normal file
@@ -0,0 +1,257 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GridCellDateTime.cpp: implementation of the CGridCellDateTime class.
|
||||
//
|
||||
// Provides the implementation for a datetime picker cell type of the
|
||||
// grid control.
|
||||
//
|
||||
// Written by Podsypalnikov Eugen 15 Mar 2001
|
||||
// Modified:
|
||||
// 31 May 2001 Fixed m_cTime bug (Chris Maunder)
|
||||
//
|
||||
// For use with CGridCtrl v2.22+
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "../GridCtrl_src/GridCtrl.h"
|
||||
#include "../GridCtrl_src/GridCell.h"
|
||||
#include "GridCellDateTime.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[]=__FILE__;
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// CGridCellDateTime
|
||||
|
||||
IMPLEMENT_DYNCREATE(CGridCellDateTime, CGridCell)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CGridCellDateTime::CGridCellDateTime() : CGridCell()
|
||||
{
|
||||
m_dwStyle = 0;
|
||||
m_cTime = CTime::GetCurrentTime();
|
||||
}
|
||||
|
||||
CGridCellDateTime::CGridCellDateTime(DWORD dwStyle) : CGridCell()
|
||||
{
|
||||
Init(dwStyle);
|
||||
}
|
||||
|
||||
CGridCellDateTime::~CGridCellDateTime()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL CGridCellDateTime::Edit(int nRow, int nCol, CRect rect, CPoint /* point */,
|
||||
UINT nID, UINT nChar)
|
||||
{
|
||||
m_bEditing = TRUE;
|
||||
|
||||
// CInPlaceDateTime auto-deletes itself
|
||||
m_pEditWnd = new CInPlaceDateTime(GetGrid(), rect,
|
||||
m_dwStyle|DTS_UPDOWN, nID, nRow, nCol,
|
||||
GetTextClr(), GetBackClr(), GetTime(), nChar);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CWnd* CGridCellDateTime::GetEditWnd() const
|
||||
{
|
||||
return m_pEditWnd;
|
||||
}
|
||||
|
||||
void CGridCellDateTime::EndEdit()
|
||||
{
|
||||
if (m_pEditWnd) ((CInPlaceDateTime*)m_pEditWnd)->EndEdit();
|
||||
}
|
||||
|
||||
void CGridCellDateTime::Init(DWORD dwStyle)
|
||||
{
|
||||
m_dwStyle = dwStyle;
|
||||
|
||||
SetTime(CTime::GetCurrentTime());
|
||||
|
||||
SetFormat(DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX
|
||||
#ifndef _WIN32_WCE
|
||||
|DT_END_ELLIPSIS
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
// Should be changed to use locale settings
|
||||
void CGridCellDateTime::SetTime(CTime time)
|
||||
{
|
||||
m_cTime = time;
|
||||
|
||||
if (DTS_TIMEFORMAT == m_dwStyle)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
CString strTemp;
|
||||
strTemp.Format(_T("%02d:%02d:%02d"),
|
||||
m_cTime.GetHour(), m_cTime.GetMinute(), m_cTime.GetSecond());
|
||||
SetText(strTemp);
|
||||
#else
|
||||
SetText(m_cTime.Format(_T("%H:%M:%S")));
|
||||
#endif
|
||||
}
|
||||
else if (DTS_SHORTDATEFORMAT == m_dwStyle)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
CString strTemp;
|
||||
strTemp.Format(_T("%02d/%02d/%02d"),
|
||||
m_cTime.GetMonth(), m_cTime.GetDay(), m_cTime.GetYear());
|
||||
SetText(strTemp);
|
||||
#else
|
||||
SetText(m_cTime.Format(("%d/%m/%Y")));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CInPlaceDateTime
|
||||
|
||||
CInPlaceDateTime::CInPlaceDateTime(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
|
||||
int nRow, int nColumn,
|
||||
COLORREF crFore, COLORREF crBack,
|
||||
CTime* pcTime,
|
||||
UINT nFirstChar)
|
||||
{
|
||||
m_crForeClr = crFore;
|
||||
m_crBackClr = crBack;
|
||||
m_nRow = nRow;
|
||||
m_nCol = nColumn;
|
||||
m_nLastChar = 0;
|
||||
m_bExitOnArrows = FALSE;
|
||||
m_pcTime = pcTime;
|
||||
|
||||
DWORD dwStl = WS_BORDER|WS_VISIBLE|WS_CHILD|dwStyle;
|
||||
|
||||
if (!Create(dwStl, rect, pParent, nID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetTime(m_pcTime);
|
||||
|
||||
SetFont(pParent->GetFont());
|
||||
SetFocus();
|
||||
|
||||
switch (nFirstChar)
|
||||
{
|
||||
case VK_LBUTTON:
|
||||
case VK_RETURN: return;
|
||||
case VK_BACK: break;
|
||||
case VK_DOWN:
|
||||
case VK_UP:
|
||||
case VK_RIGHT:
|
||||
case VK_LEFT:
|
||||
case VK_NEXT:
|
||||
case VK_PRIOR:
|
||||
case VK_HOME:
|
||||
case VK_END: return;
|
||||
default: break;
|
||||
}
|
||||
SendMessage(WM_CHAR, nFirstChar);
|
||||
}
|
||||
|
||||
CInPlaceDateTime::~CInPlaceDateTime()
|
||||
{
|
||||
}
|
||||
|
||||
void CInPlaceDateTime::EndEdit()
|
||||
{
|
||||
CString str;
|
||||
if (::IsWindow(m_hWnd))
|
||||
{
|
||||
GetWindowText(str);
|
||||
GetTime(*m_pcTime);
|
||||
}
|
||||
|
||||
// Send Notification to parent
|
||||
GV_DISPINFO dispinfo;
|
||||
|
||||
dispinfo.hdr.hwndFrom = GetSafeHwnd();
|
||||
dispinfo.hdr.idFrom = GetDlgCtrlID();
|
||||
dispinfo.hdr.code = GVN_ENDLABELEDIT;
|
||||
|
||||
dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
|
||||
dispinfo.item.row = m_nRow;
|
||||
dispinfo.item.col = m_nCol;
|
||||
dispinfo.item.strText = str;
|
||||
dispinfo.item.lParam = (LPARAM) m_nLastChar;
|
||||
|
||||
CWnd* pOwner = GetOwner();
|
||||
if (IsWindow(pOwner->GetSafeHwnd())) {
|
||||
pOwner->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo);
|
||||
}
|
||||
|
||||
// Close this window (PostNcDestroy will delete this)
|
||||
if (::IsWindow(m_hWnd)) {
|
||||
PostMessage(WM_CLOSE, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CInPlaceDateTime::PostNcDestroy()
|
||||
{
|
||||
CDateTimeCtrl::PostNcDestroy();
|
||||
delete this;
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CInPlaceDateTime, CDateTimeCtrl)
|
||||
//{{AFX_MSG_MAP(CInPlaceDateTime)
|
||||
ON_WM_KILLFOCUS()
|
||||
ON_WM_KEYDOWN()
|
||||
ON_WM_KEYUP()
|
||||
ON_WM_GETDLGCODE()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CInPlaceDateTime message handlers
|
||||
|
||||
void CInPlaceDateTime::OnKillFocus(CWnd* pNewWnd)
|
||||
{
|
||||
CDateTimeCtrl::OnKillFocus(pNewWnd);
|
||||
|
||||
if (GetSafeHwnd() == pNewWnd->GetSafeHwnd()) {
|
||||
return;
|
||||
}
|
||||
EndEdit();
|
||||
}
|
||||
|
||||
UINT CInPlaceDateTime::OnGetDlgCode()
|
||||
{
|
||||
return DLGC_WANTALLKEYS;
|
||||
}
|
||||
|
||||
void CInPlaceDateTime::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||||
{
|
||||
if (( nChar == VK_PRIOR || nChar == VK_NEXT ||
|
||||
nChar == VK_DOWN || nChar == VK_UP ||
|
||||
nChar == VK_RIGHT || nChar == VK_LEFT) &&
|
||||
(m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0))
|
||||
{
|
||||
m_nLastChar = nChar;
|
||||
GetParent()->SetFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
CDateTimeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
|
||||
}
|
||||
|
||||
void CInPlaceDateTime::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||||
{
|
||||
if (nChar == VK_TAB || nChar == VK_RETURN || nChar == VK_ESCAPE)
|
||||
{
|
||||
m_nLastChar = nChar;
|
||||
GetParent()->SetFocus(); // This will destroy this window
|
||||
return;
|
||||
}
|
||||
|
||||
CDateTimeCtrl::OnKeyUp(nChar, nRepCnt, nFlags);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// GridCellDateTime.h: interface for the CGridCellDateTime class.
|
||||
//
|
||||
// Provides the implementation for a datetime picker cell type of the
|
||||
// grid control.
|
||||
//
|
||||
// For use with CGridCtrl v2.22+
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_)
|
||||
#define AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../GridCtrl_src/GridCell.h"
|
||||
#include "afxdtctl.h" // for CDateTimeCtrl
|
||||
|
||||
class AFX_EXT_CLASS CGridCellDateTime : public CGridCell
|
||||
{
|
||||
friend class CGridCtrl;
|
||||
DECLARE_DYNCREATE(CGridCellDateTime)
|
||||
|
||||
CTime m_cTime;
|
||||
DWORD m_dwStyle;
|
||||
|
||||
public:
|
||||
CGridCellDateTime();
|
||||
CGridCellDateTime(DWORD dwStyle);
|
||||
virtual ~CGridCellDateTime();
|
||||
|
||||
// editing cells
|
||||
public:
|
||||
void Init(DWORD dwStyle);
|
||||
virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar);
|
||||
virtual CWnd* GetEditWnd() const;
|
||||
virtual void EndEdit();
|
||||
|
||||
|
||||
CTime* GetTime() {return &m_cTime;};
|
||||
void SetTime(CTime time);
|
||||
};
|
||||
|
||||
class AFX_EXT_CLASS CInPlaceDateTime : public CDateTimeCtrl
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CInPlaceDateTime(CWnd* pParent, // parent
|
||||
CRect& rect, // dimensions & location
|
||||
DWORD dwStyle, // window/combobox style
|
||||
UINT nID, // control ID
|
||||
int nRow, int nColumn, // row and column
|
||||
COLORREF crFore, COLORREF crBack, // Foreground, background colour
|
||||
CTime* pcTime,
|
||||
UINT nFirstChar); // first character to pass to control
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CInPlaceList)
|
||||
protected:
|
||||
virtual void PostNcDestroy();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CInPlaceDateTime();
|
||||
void EndEdit();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CInPlaceList)
|
||||
afx_msg void OnKillFocus(CWnd* pNewWnd);
|
||||
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
afx_msg UINT OnGetDlgCode();
|
||||
//}}AFX_MSG
|
||||
//afx_msg void OnSelendOK();
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
CTime* m_pcTime;
|
||||
int m_nRow;
|
||||
int m_nCol;
|
||||
UINT m_nLastChar;
|
||||
BOOL m_bExitOnArrows;
|
||||
COLORREF m_crForeClr, m_crBackClr;
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_)
|
||||
@@ -0,0 +1,42 @@
|
||||
// GridCellNumeric.cpp: implementation of the CGridCellNumeric class.
|
||||
//
|
||||
// Written by Andrew Truckle [ajtruckle@wsatkins.co.uk]
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "GridCellNumeric.h"
|
||||
#include "../GridCtrl_src/inplaceedit.h"
|
||||
#include "../GridCtrl_src/GridCtrl.h"
|
||||
|
||||
IMPLEMENT_DYNCREATE(CGridCellNumeric, CGridCell)
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[]=__FILE__;
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Create a control to do the editing
|
||||
BOOL CGridCellNumeric::Edit(int nRow, int nCol, CRect rect, CPoint /* point */, UINT nID, UINT nChar)
|
||||
{
|
||||
m_bEditing = TRUE;
|
||||
|
||||
// CInPlaceEdit auto-deletes itself
|
||||
m_pEditWnd = new CInPlaceEdit(GetGrid(), rect, /*GetStyle() |*/ ES_NUMBER, nID, nRow, nCol,
|
||||
GetText(), nChar);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Cancel the editing.
|
||||
void CGridCellNumeric::EndEdit()
|
||||
{
|
||||
if (m_pEditWnd)
|
||||
((CInPlaceEdit*)m_pEditWnd)->EndEdit();
|
||||
}
|
||||
|
||||
26
Server/ManageTool/GridControl/NewCellTypes/GridCellNumeric.h
Normal file
26
Server/ManageTool/GridControl/NewCellTypes/GridCellNumeric.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// GridCellNumeric.h: interface for the CGridCellNumeric class.
|
||||
//
|
||||
// Written by Andrew Truckle [ajtruckle@wsatkins.co.uk]
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_GRIDINTEGERCELL_H__3479ED0D_B57D_4940_B83D_9E2296ED75B5__INCLUDED_)
|
||||
#define AFX_GRIDINTEGERCELL_H__3479ED0D_B57D_4940_B83D_9E2296ED75B5__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../GridCtrl_src/GridCell.h"
|
||||
|
||||
class AFX_EXT_CLASS CGridCellNumeric : public CGridCell
|
||||
{
|
||||
DECLARE_DYNCREATE(CGridCellNumeric)
|
||||
|
||||
public:
|
||||
virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar);
|
||||
virtual void EndEdit();
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_GRIDINTEGERCELL_H__3479ED0D_B57D_4940_B83D_9E2296ED75B5__INCLUDED_)
|
||||
206
Server/ManageTool/GridControl/NewCellTypes/GridURLCell.cpp
Normal file
206
Server/ManageTool/GridControl/NewCellTypes/GridURLCell.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
// GridURLCell.cpp: implementation of the CGridURLCell class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "GridURLCell.h"
|
||||
#include "../GridCtrl_src/GridCtrl.h"
|
||||
|
||||
IMPLEMENT_DYNCREATE(CGridURLCell, CGridCell)
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
HCURSOR CGridURLCell::g_hLinkCursor = NULL;
|
||||
#endif
|
||||
|
||||
// Possible prefixes that indicate a hyperlink
|
||||
URLStruct CGridURLCell::g_szURIprefixes[] = {
|
||||
{ _T("www."), _tcslen(_T("www.")) },
|
||||
{ _T("http:"), _tcslen(_T("http:")) },
|
||||
{ _T("mailto:"), _tcslen(_T("mailto:")) },
|
||||
{ _T("ftp:"), _tcslen(_T("ftp:")) },
|
||||
{ _T("https:"), _tcslen(_T("https:")) },
|
||||
{ _T("news:"), _tcslen(_T("news:")) },
|
||||
{ _T("gopher:"), _tcslen(_T("gopher:")) },
|
||||
{ _T("telnet:"), _tcslen(_T("telnet:")) },
|
||||
{ _T("url:"), _tcslen(_T("url:")) },
|
||||
{ _T("file:"), _tcslen(_T("file:")) },
|
||||
{ _T("ftp."), _tcslen(_T("ftp.")) }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CGridURLCell::CGridURLCell()
|
||||
{
|
||||
#ifndef _WIN32_WCE
|
||||
g_hLinkCursor = GetHandCursor();
|
||||
#endif
|
||||
m_bLaunchUrl = TRUE;
|
||||
m_clrUrl = GetSysColor(COLOR_HIGHLIGHT);
|
||||
}
|
||||
|
||||
CGridURLCell::~CGridURLCell()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL CGridURLCell::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd)
|
||||
{
|
||||
// If url is present then change text color
|
||||
if (HasUrl(GetText()))
|
||||
SetTextClr(m_clrUrl);
|
||||
|
||||
// Good a place as any to store the bounds of the rect
|
||||
m_Rect = rect;
|
||||
|
||||
return CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd);
|
||||
}
|
||||
|
||||
#pragma warning(disable:4100)
|
||||
BOOL CGridURLCell::Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#pragma warning(default:4100)
|
||||
|
||||
void CGridURLCell::OnClick(CPoint PointCellRelative)
|
||||
{
|
||||
#ifndef _WIN32_WCE
|
||||
CString strURL;
|
||||
if (GetAutoLaunchUrl() && OverURL(PointCellRelative, strURL))
|
||||
ShellExecute(NULL, _T("open"), strURL, NULL,NULL, SW_SHOW);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Return TRUE if you set the cursor
|
||||
BOOL CGridURLCell::OnSetCursor()
|
||||
{
|
||||
#ifndef _WIN32_WCE
|
||||
CString strURL;
|
||||
CPoint pt(GetMessagePos());
|
||||
GetGrid()->ScreenToClient(&pt);
|
||||
pt = pt - m_Rect.TopLeft();
|
||||
|
||||
if (OverURL(pt, strURL))
|
||||
{
|
||||
SetCursor(g_hLinkCursor);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return CGridCell::OnSetCursor();
|
||||
}
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
HCURSOR CGridURLCell::GetHandCursor()
|
||||
{
|
||||
if (g_hLinkCursor == NULL) // No cursor handle - load our own
|
||||
{
|
||||
// Get the windows directory
|
||||
CString strWndDir;
|
||||
GetWindowsDirectory(strWndDir.GetBuffer(MAX_PATH), MAX_PATH);
|
||||
strWndDir.ReleaseBuffer();
|
||||
|
||||
strWndDir += _T("\\winhlp32.exe");
|
||||
// This retrieves cursor #106 from winhlp32.exe, which is a hand pointer
|
||||
HMODULE hModule = LoadLibrary(strWndDir);
|
||||
if( hModule )
|
||||
{
|
||||
HCURSOR hHandCursor = ::LoadCursor(hModule, MAKEINTRESOURCE(106));
|
||||
if( hHandCursor )
|
||||
{
|
||||
g_hLinkCursor = CopyCursor(hHandCursor);
|
||||
}
|
||||
}
|
||||
FreeLibrary(hModule);
|
||||
}
|
||||
|
||||
return g_hLinkCursor;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Helper functions
|
||||
|
||||
BOOL CGridURLCell::HasUrl(CString str)
|
||||
{
|
||||
int nNumPrefixes = sizeof(g_szURIprefixes) / sizeof(g_szURIprefixes[0]);
|
||||
for (int i = 0; i < nNumPrefixes; i++)
|
||||
//if (str.Left(g_szURIprefixes[i].nLength) == g_szURIprefixes[i].szURLPrefix)
|
||||
if (str.Find(g_szURIprefixes[i].szURLPrefix) >= 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// here we figure out if we are over a URL or not
|
||||
BOOL CGridURLCell::OverURL(CPoint& pt, CString& strURL)
|
||||
{
|
||||
//TRACE2("Checking point %d,%d\n",pt.x,pt.y);
|
||||
|
||||
BOOL bOverURL = FALSE;
|
||||
CSize size = GetTextExtent(GetText());
|
||||
|
||||
// Add left of cell so we know if we clicked on text or not
|
||||
pt.x += m_Rect.left;
|
||||
CPoint center = m_Rect.CenterPoint();
|
||||
|
||||
if ((m_nFormat & DT_RIGHT) && pt.x >= (m_Rect.right - size.cx))
|
||||
{
|
||||
bOverURL = TRUE;
|
||||
}
|
||||
else if ((m_nFormat & DT_CENTER) &&
|
||||
((center.x - (size.cx/2)) <= pt.x) && (pt.x <= (center.x + (size.cx/2))) )
|
||||
{
|
||||
bOverURL = TRUE;
|
||||
}
|
||||
else if (pt.x <= (size.cx + m_Rect.left))
|
||||
{
|
||||
bOverURL = TRUE;
|
||||
}
|
||||
|
||||
if (!bOverURL)
|
||||
return FALSE;
|
||||
|
||||
// We are over text - but are we over a URL?
|
||||
bOverURL = FALSE;
|
||||
strURL = GetText();
|
||||
|
||||
// Use float, otherwise we get an incorrect letter from the point
|
||||
float width = (float)size.cx/(float)strURL.GetLength();
|
||||
|
||||
// remove left of cell so we have original point again
|
||||
pt.x -= m_Rect.left;
|
||||
if (m_nFormat & DT_RIGHT)
|
||||
{
|
||||
int wide = m_Rect.Width() - size.cx;
|
||||
pt.x -= wide;
|
||||
if (pt.x <= 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (m_nFormat & DT_CENTER)
|
||||
{
|
||||
int wide = m_Rect.Width() - size.cx;
|
||||
pt.x -= (wide/2);
|
||||
if (pt.x <= 0 || pt.x > (size.cx + (wide/2)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Turn point into a letter
|
||||
int ltrs = (int)((float)pt.x/width);
|
||||
#if !defined(_WIN32_WCE) || (_WIN32_WCE > 210)
|
||||
// Find spaces before and after letter, process text between
|
||||
int endSpace = strURL.Find(_T(' '), ltrs);
|
||||
if (endSpace != -1)
|
||||
strURL.Delete(endSpace, strURL.GetLength()-endSpace);
|
||||
|
||||
int beginSpace = strURL.ReverseFind(_T(' '));
|
||||
if (beginSpace != -1)
|
||||
strURL.Delete(0, ++beginSpace);
|
||||
#endif
|
||||
|
||||
// Does text have url
|
||||
return HasUrl(strURL);
|
||||
}
|
||||
|
||||
55
Server/ManageTool/GridControl/NewCellTypes/GridURLCell.h
Normal file
55
Server/ManageTool/GridControl/NewCellTypes/GridURLCell.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// GridURLCell.h: interface for the CGridURLCell class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_GRIDURLCELL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_)
|
||||
#define AFX_GRIDURLCELL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../GridCtrl_src/GridCell.h"
|
||||
|
||||
typedef struct {
|
||||
LPCTSTR szURLPrefix;
|
||||
int nLength;
|
||||
} URLStruct;
|
||||
|
||||
|
||||
|
||||
class AFX_EXT_CLASS CGridURLCell : public CGridCell
|
||||
{
|
||||
DECLARE_DYNCREATE(CGridURLCell)
|
||||
|
||||
public:
|
||||
CGridURLCell();
|
||||
virtual ~CGridURLCell();
|
||||
|
||||
virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd = TRUE);
|
||||
virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar);
|
||||
virtual LPCTSTR GetTipText() { return NULL; }
|
||||
void SetAutoLaunchUrl(BOOL bLaunch = TRUE) { m_bLaunchUrl = bLaunch; }
|
||||
BOOL GetAutoLaunchUrl() { return m_bLaunchUrl; }
|
||||
|
||||
protected:
|
||||
virtual BOOL OnSetCursor();
|
||||
virtual void OnClick(CPoint PointCellRelative);
|
||||
|
||||
BOOL HasUrl(CString str);
|
||||
BOOL OverURL(CPoint& pt, CString& strURL);
|
||||
|
||||
protected:
|
||||
#ifndef _WIN32_WCE
|
||||
static HCURSOR g_hLinkCursor; // Hyperlink mouse cursor
|
||||
HCURSOR GetHandCursor();
|
||||
#endif
|
||||
static URLStruct g_szURIprefixes[];
|
||||
|
||||
protected:
|
||||
COLORREF m_clrUrl;
|
||||
BOOL m_bLaunchUrl;
|
||||
CRect m_Rect;
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_GRIDURLCELL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_)
|
||||
38
Server/ManageTool/GridControl/ReadMe.txt
Normal file
38
Server/ManageTool/GridControl/ReadMe.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
========================================================================
|
||||
정적 라이브러리 : GridControl 프로젝트 개요
|
||||
========================================================================
|
||||
|
||||
응용 프로그램 마법사에서 이 GridControl 라이브러리 프로젝트를 만들었습니다.
|
||||
이 파일에는 GridControl 응용 프로그램을 구성하는 각각의 파일에
|
||||
들어 있는 요약 설명이 포함되어 있습니다.
|
||||
|
||||
|
||||
GridControl.vcproj
|
||||
응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다.
|
||||
해당 파일을 생성한 Visual C++의 버전 정보를 비롯하여
|
||||
응용 프로그램 마법사에서 선택한 플랫폼, 구성 및
|
||||
프로젝트 기능에 대한 정보가 들어 있습니다.
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
StdAfx.h 및 StdAfx.cpp는
|
||||
GridControl.pch라는 이름의 PCH(미리 컴파일된 헤더) 파일과
|
||||
StdAfx.obj라는 이름의 미리 컴파일된 형식 파일을 빌드하는 데 사용됩니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
컴파일러와 링커 스위치가 MFC를 지원할 수 있도록 변경되었습니다.
|
||||
MFC 클래스 마법사를 이 프로젝트와 함께 사용하려면 "resource.h",
|
||||
"GridControl.rc", 그리고 resource.h가 들어 있는 "GridControl.h" 등
|
||||
몇몇 파일을 해당 프로젝트에 추가해야 합니다.
|
||||
Dll 또는 Exe는 rc 파일을 하나씩만 포함할 수 있으므로
|
||||
정적 라이브러리에 rc 파일을 추가하면 문제가 생길 수 있습니다.
|
||||
그러한 경우 해당 라이브러리의 .rc 파일을 부모 프로젝트의 .rc 파일에 포함시키면 문제가 해결됩니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
기타 참고:
|
||||
|
||||
응용 프로그램 마법사에서 사용하는 "TODO:" 주석은 사용자가 추가하거나 사용자 지정해야 하는
|
||||
소스 코드 부분을 나타냅니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
8
Server/ManageTool/GridControl/stdafx.cpp
Normal file
8
Server/ManageTool/GridControl/stdafx.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
// stdafx.cpp : 표준 포함 파일만 들어 있는 소스 파일입니다.
|
||||
// GridControl.pch는 미리 컴파일된 헤더가 됩니다.
|
||||
// stdafx.obj에는 미리 컴파일된 형식 정보가 포함됩니다.
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: 필요한 추가 헤더는
|
||||
// 이 파일이 아닌 STDAFX.H에서 참조합니다.
|
||||
43
Server/ManageTool/GridControl/stdafx.h
Normal file
43
Server/ManageTool/GridControl/stdafx.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// stdafx.h : 잘 변경되지 않고 자주 사용하는
|
||||
// 표준 시스템 포함 파일 및 프로젝트 관련 포함 파일이
|
||||
// 들어 있는 포함 파일입니다.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
#define VC_EXTRALEAN // Windows 헤더에서 거의 사용되지 않는 내용을 제외시킵니다.
|
||||
#endif
|
||||
|
||||
// 아래 지정된 플랫폼보다 우선하는 플랫폼을 대상으로 하는 경우 다음 정의를 수정하십시오.
|
||||
// 다른 플랫폼에 사용되는 해당 값의 최신 정보는 MSDN을 참조하십시오.
|
||||
#ifndef WINVER // Windows 95 및 Windows NT 4 이후 버전에서만 기능을 사용할 수 있습니다.
|
||||
#define WINVER 0x0400 // Windows 98과 Windows 2000 이후 버전에 맞도록 적합한 값으로 변경해 주십시오.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINNT // Windows NT 4 이후 버전에서만 기능을 사용할 수 있습니다.
|
||||
#define _WIN32_WINNT 0x0400 // Windows 98과 Windows 2000 이후 버전에 맞도록 적합한 값으로 변경해 주십시오.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINDOWS // Windows 98 이후 버전에서만 기능을 사용할 수 있습니다.
|
||||
#define _WIN32_WINDOWS 0x0410 // Windows Me 이후 버전에 맞도록 적합한 값으로 변경해 주십시오.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_IE // IE 4.0 이후 버전에서만 기능을 사용할 수 있습니다.
|
||||
#define _WIN32_IE 0x0400 // IE 5.0 이후 버전에 맞도록 적합한 값으로 변경해 주십시오.
|
||||
#endif
|
||||
|
||||
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 일부 CString 생성자는 명시적으로 선언됩니다.
|
||||
|
||||
// MFC의 공통 부분과 무시 가능한 경고 메시지에 대한 숨기기를 해제합니다.
|
||||
#define _AFX_ALL_WARNINGS
|
||||
|
||||
#include <afxwin.h> // MFC 핵심 및 표준 구성 요소
|
||||
#include <afxext.h> // MFC 익스텐션
|
||||
#include <afxdisp.h> // MFC 자동화 클래스
|
||||
|
||||
#include <afxdtctl.h> // Internet Explorer 4 공용 컨트롤에 대한 MFC 지원
|
||||
#ifndef _AFX_NO_AFXCMN_SUPPORT
|
||||
#include <afxcmn.h> // Windows 공용 컨트롤에 대한 MFC 지원
|
||||
#endif // _AFX_NO_AFXCMN_SUPPORT
|
||||
#include <afxdlgs.h>
|
||||
|
||||
400
Server/ManageTool/ManageClient/ManageClient.cpp
Normal file
400
Server/ManageTool/ManageClient/ManageClient.cpp
Normal file
@@ -0,0 +1,400 @@
|
||||
// ManageClient.cpp : Defines the entry point for the application.
|
||||
//
|
||||
#include "stdafx.h"
|
||||
#include "resource.h"
|
||||
#include "ManageClient.h"
|
||||
|
||||
#include <shellapi.h>
|
||||
|
||||
#include <Thread/Lock.h> // CNamedMutex
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Utility/Debug/ExceptionReport.h> // g_CExceptionReport
|
||||
#include <Utility/Time/Pulse/Pulse.h>
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
#include <Network/Session/CreatePolicy.h>
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/IOCP/IOCPNet.h>
|
||||
|
||||
#include <Network/Dispatch/ManageClient/ManageClientDispatch.h>
|
||||
|
||||
#include <Network/Packet/ManagePacketCmd.h>
|
||||
#include <Network/Dispatch/SendManagePacket.h>
|
||||
|
||||
#include <Setup/SetupClient.h>
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
CNamedMutex Mutex("ManageClient", TRUE);
|
||||
|
||||
if(GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
ERRLOG0(g_Log, "ManageClient already server operating now. please shutdown and restart");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long dwExceptionFeatures = CExceptionReport::CATCH_EXCEPTION |
|
||||
CExceptionReport::USE_MINIDUMP | CExceptionReport::USE_REPORT;
|
||||
|
||||
CExceptionReport::GetInstance().Enable(dwExceptionFeatures);
|
||||
|
||||
CManageClient& ManageClient = CManageClient::GetInstance();
|
||||
|
||||
if(ManageClient.Initialize(hInstance,
|
||||
CServerSetup::GetInstance().GetManageClientWindowName(),
|
||||
lpCmdLine, IDI_MANAGECLIENT, IDC_MANAGECLIENT))
|
||||
{
|
||||
ManageClient.ProcessMessage();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
class CManageClientProcessThread : public CProcessThread
|
||||
{
|
||||
public:
|
||||
|
||||
enum Const
|
||||
{
|
||||
PROCESS_TPP = 200, // 200ms(0.2초) 에 1틱.
|
||||
CONNECT_CHECK = 10 * (1000 / PROCESS_TPP), // 10초마다 연결 체크
|
||||
PRINT_CHECK = 2 * (1000 / PROCESS_TPP), // 2초마다 콘솔 출력
|
||||
PROCESS_CHECK = 3 * (1000 / PROCESS_TPP) // 5초마다 처리 갱신
|
||||
};
|
||||
|
||||
CManageClientProcessThread(CManageClient& ManageClient)
|
||||
: CProcessThread(ManageClient, PROCESS_TPP),
|
||||
m_ManageClient(ManageClient)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
virtual void Cleanup(CPulse& Pulse)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void InternalRun(CPulse& Pulse)
|
||||
{
|
||||
unsigned long dwCurrentPulse = Pulse.GetCurrentPulse();
|
||||
|
||||
if(0 == (dwCurrentPulse % CONNECT_CHECK))
|
||||
{
|
||||
m_ManageClient.CheckConnectionAndReconnect();
|
||||
}
|
||||
|
||||
if(0 == (dwCurrentPulse % PRINT_CHECK))
|
||||
{
|
||||
m_ManageClient.PrintConnectionStatus();
|
||||
}
|
||||
|
||||
if(0 == (dwCurrentPulse % PROCESS_CHECK))
|
||||
{
|
||||
GET_SINGLE_DISPATCH(lpManageClientDispatch,
|
||||
CManageClientDispatch, CManageClientDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpManageClientDispatch)
|
||||
{
|
||||
lpManageClientDispatch->CheckProcessStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CManageClient& m_ManageClient;
|
||||
};
|
||||
|
||||
|
||||
CManageClient& CManageClient::GetInstance()
|
||||
{
|
||||
static CManageClient manageClient;
|
||||
return manageClient;
|
||||
}
|
||||
|
||||
|
||||
CManageClient::CManageClient()
|
||||
: m_lpClientSessionPolicy(SessionPolicy::CreateTCPPolicy<CManageClientDispatch>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
CManageClient::~CManageClient()
|
||||
{
|
||||
if(0 != m_lpClientSessionPolicy)
|
||||
{
|
||||
m_lpClientSessionPolicy->Release();
|
||||
m_lpClientSessionPolicy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CManageClient::CheckConnectionAndReconnect()
|
||||
{
|
||||
bool bReconnect = false;
|
||||
|
||||
GET_SINGLE_DISPATCH(lpManageClientDispatch,
|
||||
CManageClientDispatch, CManageClientDispatch::GetDispatchTable());
|
||||
|
||||
if(0 == lpManageClientDispatch)
|
||||
{
|
||||
// 연결이 안 되어 있으면 연결을 테스트함.
|
||||
|
||||
CIOCPNet* lpIOCP = GetIOCPNet();
|
||||
|
||||
if(0 != lpIOCP)
|
||||
{
|
||||
ConnectToManageServer();
|
||||
}
|
||||
}
|
||||
else if(lpManageClientDispatch->DoPatchNow())
|
||||
{
|
||||
// 패치를 전부 받고, 패치하기 직전이다. 패치 프로세스를 시작한다.
|
||||
DoSelfPatchProcess(*lpManageClientDispatch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CManageClient::ConnectToManageServer()
|
||||
{
|
||||
CIOCPNet* lpIOCP = GetIOCPNet();
|
||||
|
||||
if(0 != lpIOCP && 0 != m_lpClientSessionPolicy)
|
||||
{
|
||||
INET_Addr& manageServerAddr = ManageSetup::ClientSetup::GetInstance().GetManageServerAddr();
|
||||
|
||||
if(!lpIOCP->Connect(m_lpClientSessionPolicy, manageServerAddr.get_addr_string(),
|
||||
manageServerAddr.get_port_in()))
|
||||
{
|
||||
DETLOG3(g_Log, "this:0x%p/IP:%15s/Port/%02d/ManageServer connect failed.",
|
||||
this, manageServerAddr.get_addr_string(), manageServerAddr.get_port_in());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CManageClient::DoSelfPatchProcess(CManageClientDispatch& ClientDispatch)
|
||||
{
|
||||
/*
|
||||
// temporary .bat file
|
||||
static const TCHAR szTempBatContent[] =
|
||||
_T(":Repeat\r\n")
|
||||
_T("del \"%s\"\r\n") // execute file name(full path)
|
||||
_T("if exist \"%s\" goto Repeat\r\n") // execute file name(full path)
|
||||
_T(":Repeat2\r\n")
|
||||
_T("rename %s %s\r\n") // first - temp file name(full path), second - execute file name only
|
||||
_T("if not exist \"%s\" goto Repeat\r\n") // execute file name(full path)
|
||||
_T("cd %s\r\n") // execute file path(full path)
|
||||
_T("%s\r\n"); // execute file name(full path)
|
||||
|
||||
static const TCHAR szTempBatName[] = "_manageclient_selfpatch.bat" ;
|
||||
|
||||
TCHAR szFullPathModuleName[MAX_PATH]; // absolute path of calling .exe file
|
||||
TCHAR szModulePath[MAX_PATH]; // Module path
|
||||
TCHAR szModuleFileName[MAX_PATH]; // fileName
|
||||
TCHAR szModuleExtension[NAX_PATH]; // extension
|
||||
TCHAR szTempBatPathName[MAX_PATH]; // absolute path of temporary .bat file
|
||||
|
||||
memset(szFullPathModuleName, 0, sizeof(TCHAR) * MAX_PATH);
|
||||
memset(szModulePath, 0, sizeof(TCHAR) * MAX_PATH);
|
||||
memset(szTempBatPathName, 0, sizeof(TCHAR) * MAX_PATH);
|
||||
|
||||
bool bFailedGetName = true;
|
||||
|
||||
unsigned long dwPathLength = GetTempPath(MAX_PATH, szTempBatPathName);
|
||||
if(0 < dwPathLength)
|
||||
{
|
||||
if(0 < _sntprintf(szTempBatPathName + dwPathLength, MAX_PATH - dwPathLength - 1,
|
||||
"%s", szTempBatName))
|
||||
{
|
||||
szTempBatPathName[MAX_PATH - 1] = 0;
|
||||
bFailedGetName = false;
|
||||
}
|
||||
}
|
||||
|
||||
const TCHAR* szErrorMessage = 0;
|
||||
|
||||
if(bFailedGetName)
|
||||
{
|
||||
szErrorMessage = _T("this:0x%p/Failed get tempbat file.");
|
||||
}
|
||||
else
|
||||
{
|
||||
dwPathLength = GetModuleFileName(NULL, szFullPathModuleName, MAX_PATH - 1);
|
||||
szFullPathModuleName[MAX_PATH - 1] = 0;
|
||||
|
||||
_tsplitpath(szFullPathModuleName, 0, 0, szModuleFileName, szModuleExtension);
|
||||
|
||||
_sntprintf(szModuleFileName, szModuleExtension
|
||||
|
||||
szModuleFileName = _tcsrchr(szFullPathModuleName, _T('\\'));
|
||||
if(0 == szModuleFileName)
|
||||
{
|
||||
szModuleFileName = _tcsrchr(szFullPathModuleName, _T('/'));
|
||||
}
|
||||
|
||||
if(0 == szModuleFileName || 0 == dwPathLength)
|
||||
{
|
||||
szErrorMessage = _T("this:0x%p/Failed get module name.");
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(szModulePath, szFullPathModuleName,
|
||||
szModuleFileName - szFullPathModuleName);
|
||||
|
||||
szModulePath[szModuleFileName - szFullPathModuleName] = _T('\0');
|
||||
++szModuleFileName;
|
||||
|
||||
HANDLE hBatFile = CreateFile(szTempBatPathName, GENERIC_WRITE, 0, NULL,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ;
|
||||
|
||||
if (INVALID_HANDLE_VALUE == hBatFile)
|
||||
{
|
||||
szErrorMessage = _T("this:0x%p/Temp bat file create failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwLength = 0;
|
||||
|
||||
unsigned long dwTempBatContentLen = _tcslen(szTempBatContent);
|
||||
unsigned long dwFullPathModuleNameLen = _tcslen(szFullPathModuleName);
|
||||
unsigned long dwTempPathFileLen = _tcslen(ClientDispatch.GetTempPatchFileName());
|
||||
unsigned long dwModuleFileNameLen = _tcslen(szModuleFileName);
|
||||
unsigned long dwModulePathLen = _tcslen(szModulePath);
|
||||
|
||||
TCHAR* szBatBuffer = new TCHAR[dwTempBatContentLen +
|
||||
dwFullPathModuleNameLen * 4 +
|
||||
dwTempPathFileLen +
|
||||
dwModuleFileNameLen +
|
||||
dwModulePathLen +
|
||||
MAX_PATH];
|
||||
|
||||
int nLength = _sntprintf(szBatBuffer, MAX_PATH * 10 - 1, szTempBatContent,
|
||||
szFullPathModuleName, // 지울 파일 이름
|
||||
szFullPathModuleName, // 파일 존재 여부 체크
|
||||
ClientDispatch.GetTempPatchFileName(), // 임시 파일 이름
|
||||
szModuleFileName, // 바뀔 이름
|
||||
szFullPathModuleName, // 바뀐 이름
|
||||
szModulePath, // 경로 이동
|
||||
szFullPathModuleName); // 실행
|
||||
|
||||
if(0 < nLength)
|
||||
{
|
||||
if(!WriteFile(hBatFile, szBatBuffer, _tcslen(szBatBuffer), &dwLength, NULL))
|
||||
{
|
||||
szErrorMessage = _T("this:0x%p/Temp bat file write content failed.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
szErrorMessage = _T("this:0x%p/Temp bat file make content failed.");
|
||||
}
|
||||
|
||||
CloseHandle(hBatFile);
|
||||
|
||||
delete [] szBatBuffer;
|
||||
ShellExecute(NULL, _T("open"), szTempBatContent, NULL, NULL, SW_HIDE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(0 != szErrorMessage)
|
||||
{
|
||||
ERRLOG1(g_Log, szErrorMessage, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 패치 성공. 종료.
|
||||
DETLOG1(g_Log, "this:0x%p/Patch success. restart now.", this);
|
||||
PostMessage(GetWnd(), WM_DESTROY, 0, 0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
bool CManageClient::ApplicationSpecificInit(const TCHAR* szCmdLine)
|
||||
{
|
||||
const TCHAR* szErrorMessage = 0;
|
||||
|
||||
if(!InitializeMsgProc())
|
||||
{
|
||||
szErrorMessage = _T("this:0x%p/InitializeMsgProc failed");
|
||||
}
|
||||
else if(!InitializeCommand())
|
||||
{
|
||||
szErrorMessage = _T("this:0x%p/InitializeCommand failed");
|
||||
}
|
||||
else if(!AddProcessThread(new CManageClientProcessThread(*this)))
|
||||
{
|
||||
szErrorMessage = "this:0x%p/AddProcessThread failed";
|
||||
}
|
||||
|
||||
if(0 != szErrorMessage)
|
||||
{
|
||||
ERRLOG1(g_Log, szErrorMessage, this);
|
||||
return false;
|
||||
}
|
||||
|
||||
CheckConnectionAndReconnect();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CManageClient::PrintConnectionStatus()
|
||||
{
|
||||
const int MAX_BUFFER = 4096;
|
||||
char szBuffer[MAX_BUFFER];
|
||||
|
||||
char szFileName[MAX_PATH];
|
||||
char szExtension[MAX_PATH];
|
||||
|
||||
INET_Addr& manageServerAddr = ManageSetup::ClientSetup::GetInstance().GetManageServerAddr();
|
||||
|
||||
GET_SINGLE_DISPATCH(lpManageClientDispatch,
|
||||
CManageClientDispatch, CManageClientDispatch::GetDispatchTable());
|
||||
|
||||
int nLength = _snprintf(szBuffer, MAX_BUFFER - 1,
|
||||
"ManageClient Console\r\n\r\nManageServer IP:%s, Port:%d %s\r\n\r\n",
|
||||
manageServerAddr.get_addr_string(),
|
||||
manageServerAddr.get_port_in(),
|
||||
(0 != lpManageClientDispatch) ? "Connected" : "Disconnected");
|
||||
|
||||
int nTotalLength = 0;
|
||||
|
||||
if(0 < nLength)
|
||||
{
|
||||
if(0 != lpManageClientDispatch)
|
||||
{
|
||||
nTotalLength += nLength;
|
||||
|
||||
CManageClientDispatch::RunTable& runTable = lpManageClientDispatch->GetRunTable();
|
||||
|
||||
CManageClientDispatch::RunTable::iterator pos = runTable.begin();
|
||||
CManageClientDispatch::RunTable::iterator end = runTable.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
const ServerManage::RunInfo& runInfo = pos->second.m_RunInfo;
|
||||
|
||||
_splitpath(runInfo.m_szPath, 0, 0, szFileName, szExtension);
|
||||
|
||||
nLength = _snprintf(szBuffer + nTotalLength, MAX_BUFFER - nTotalLength,
|
||||
"RunID:%5d / %s%s %s\r\n",
|
||||
runInfo.m_dwRunID, szFileName, szExtension, runInfo.m_szOption);
|
||||
|
||||
if(0 < nLength)
|
||||
{
|
||||
nTotalLength += nLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(0 < nTotalLength && nTotalLength < MAX_BUFFER)
|
||||
{
|
||||
szBuffer[nTotalLength] = 0;
|
||||
PrintInfo(szBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Server/ManageTool/ManageClient/ManageClient.h
Normal file
35
Server/ManageTool/ManageClient/ManageClient.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef _RYL_GM_NETWORK_MANAGE_CLIENT_H_
|
||||
#define _RYL_GM_NETWORK_MANAGE_CLIENT_H_
|
||||
|
||||
#include <Utility/ServerAppFramework/ServerWindowFramework.h>
|
||||
|
||||
// forward decl.
|
||||
class CSessionPolicy;
|
||||
class CManageClientDispatch;
|
||||
|
||||
class CManageClient : public CServerWindowFramework
|
||||
{
|
||||
public:
|
||||
|
||||
static CManageClient& GetInstance();
|
||||
|
||||
void CheckConnectionAndReconnect();
|
||||
void ConnectToManageServer();
|
||||
void DoSelfPatchProcess(CManageClientDispatch& ClientDispatch);
|
||||
|
||||
void PrintConnectionStatus();
|
||||
|
||||
private:
|
||||
|
||||
CManageClient();
|
||||
virtual ~CManageClient();
|
||||
|
||||
virtual bool ApplicationSpecificInit(const TCHAR* szCmdLine);
|
||||
bool InitializeMsgProc();
|
||||
bool InitializeCommand();
|
||||
|
||||
CSessionPolicy* m_lpClientSessionPolicy;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
BIN
Server/ManageTool/ManageClient/ManageClient.ico
Normal file
BIN
Server/ManageTool/ManageClient/ManageClient.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
97
Server/ManageTool/ManageClient/ManageClient.rc
Normal file
97
Server/ManageTool/ManageClient/ManageClient.rc
Normal file
@@ -0,0 +1,97 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Çѱ¹¾î resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_KOR)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
|
||||
#pragma code_page(949)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_SMALL ICON "small.ico"
|
||||
IDI_MANAGECLIENT ICON "ManageClient.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDC_MANAGECLIENT MENU
|
||||
BEGIN
|
||||
POPUP "ManageClient"
|
||||
BEGIN
|
||||
MENUITEM "Open Console(&O)", ID_MANAGECLIENT_OPEN_CONSOLE
|
||||
MENUITEM "Close Console(&C)", ID_MANAGECLIENT_CLOSE_CONSOLE
|
||||
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Reload Setup(&R)", ID_MANAGECLIENT_RELOADSETUP
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Exit(&E)", IDM_EXIT
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Çѱ¹¾î resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
176
Server/ManageTool/ManageClient/ManageClient.vcproj
Normal file
176
Server/ManageTool/ManageClient/ManageClient.vcproj
Normal file
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="ks_c_5601-1987"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="ManageClient"
|
||||
ProjectGUID="{1B7E2874-2F79-4399-ABA5-512ABF1120F6}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../Executable/$(ConfigurationName)"
|
||||
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../../RylServerProject/BaseLibrary;../../RylServerProject/RylServerLibrary;../ManageLibrary"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/ManageClient.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/ManageClient.pdb"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../Executable/$(ConfigurationName)"
|
||||
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="./;../;../../RylServerProject/BaseLibrary;../../RylServerProject/RylServerLibrary;../ManageLibrary"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/ManageClient.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="소스 파일"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\ManageClient.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ManageClientCommand.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ManageClientMsg.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="헤더 파일"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath=".\ManageClient.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Resource.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="리소스 파일"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
||||
<File
|
||||
RelativePath=".\ManageClient.ico">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ManageClient.rc">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\small.ico">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\ReadMe.txt">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
63
Server/ManageTool/ManageClient/ManageClientCommand.cpp
Normal file
63
Server/ManageTool/ManageClient/ManageClientCommand.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "stdafx.h"
|
||||
#include "ManageClient.h"
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Setup/SetupClient.h>
|
||||
#include <Utility/ServerAppFrameWork/ConsoleWindow/ConsoleCMDFactory.h>
|
||||
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Dispatch/ManageClient/ManageClientDispatch.h>
|
||||
|
||||
|
||||
class CCMDPrintLog : public CConsoleCMDSingleton<CCMDPrintLog>
|
||||
{
|
||||
protected:
|
||||
virtual bool DoProcess()
|
||||
{
|
||||
SERLOG0(g_Log, "Flush log.");
|
||||
SERLOG0(g_SessionLog, "Flush log");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CCMDReloadSetup : public CConsoleCMDSingleton<CCMDReloadSetup>
|
||||
{
|
||||
protected:
|
||||
virtual bool DoProcess()
|
||||
{
|
||||
ManageSetup::ClientSetup::GetInstance().Load();
|
||||
|
||||
GET_SINGLE_DISPATCH(lpManageClientDispatch,
|
||||
CManageClientDispatch, CManageClientDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpManageClientDispatch)
|
||||
{
|
||||
// 연결을 끊은 후 재접속을 시도한다.
|
||||
lpManageClientDispatch->GetSession().Shutdown();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool CManageClient::InitializeCommand()
|
||||
{
|
||||
#define INIT_COMMAND_FAILED(detail) TEXT("Command create failed - "##detail)
|
||||
|
||||
#define ADD_COMMAND(cmdstring, cmdobject, errmsg_val) \
|
||||
if(0 == (errmsg_val) && !GetCommandFactory()->AddCommand(cmdstring, new cmdobject)) { \
|
||||
(errmsg_val) = INIT_COMMAND_FAILED(cmdstring); }
|
||||
|
||||
const TCHAR* szErrorMessage = 0;
|
||||
|
||||
ADD_COMMAND("flush", CCMDPrintLog, szErrorMessage);
|
||||
ADD_COMMAND("reload", CCMDReloadSetup, szErrorMessage);
|
||||
|
||||
if(0 != szErrorMessage)
|
||||
{
|
||||
ERRLOG0(g_Log, szErrorMessage);
|
||||
return false;
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
120
Server/ManageTool/ManageClient/ManageClientMsg.cpp
Normal file
120
Server/ManageTool/ManageClient/ManageClientMsg.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#include "stdafx.h"
|
||||
#include "Resource.h"
|
||||
#include "ManageClient.h"
|
||||
#include <Utility/ServerAppFramework/MsgProc/MsgProc.h>
|
||||
#include <Utility/ServerAppFramework/ConsoleWindow/ConsoleWindow.h>
|
||||
#include <Utility/ServerAppFramework/ConsoleWindow/ConsoleCMDFactory.h>
|
||||
#include <Network/Dispatch/ManageClient/ManageClientDispatch.h>
|
||||
|
||||
#include <Network/Dispatch/SendManagePacket.h>
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
class CIPCMessage : public CMsgProc
|
||||
{
|
||||
private:
|
||||
|
||||
virtual LRESULT operator () (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
GET_SINGLE_DISPATCH(lpManageClientDispatch,
|
||||
CManageClientDispatch, CManageClientDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpManageClientDispatch && 0 != lParam)
|
||||
{
|
||||
// µ¥ÀÌÅÍ ¸Þ½ÃÁö.
|
||||
COPYDATASTRUCT& copyDataStruct = *reinterpret_cast<PCOPYDATASTRUCT>(lParam);
|
||||
ServerManage::PktManagePacket* lpPktManage =
|
||||
reinterpret_cast<ServerManage::PktManagePacket*>(copyDataStruct.lpData);
|
||||
|
||||
ServerManage::PktManagePing* lpPktManagePing =
|
||||
static_cast<ServerManage::PktManagePing*>(lpPktManage);
|
||||
|
||||
unsigned long dwRunID = 0;
|
||||
|
||||
if(ServerManage::CMD::IPC_ManagePing == lpPktManage->GetCmd()
|
||||
&& copyDataStruct.cbData == sizeof(ServerManage::PktManagePing)
|
||||
&& lpManageClientDispatch->GetRunIDFromString(
|
||||
lpPktManagePing->m_szAppFullPathName, lpPktManagePing->m_szCommandLine, dwRunID))
|
||||
{
|
||||
HWND hWnd = FindWindow(lpPktManagePing->m_szWindowName,
|
||||
lpPktManagePing->m_szWindowName);
|
||||
|
||||
if(0 != hWnd)
|
||||
{
|
||||
lpManageClientDispatch->SetAppData(dwRunID,
|
||||
hWnd, lpPktManage->m_dwPID, lpPktManagePing->m_dwStatusFlag);
|
||||
}
|
||||
}
|
||||
else if(lpManageClientDispatch->GetRunIDFromPID(lpPktManage->m_dwPID, dwRunID))
|
||||
{
|
||||
ServerManage::SendManagePacket(lpManageClientDispatch->GetSession(),
|
||||
ServerManage::CMD::RelayCommand, WM_COPYDATA, wParam, 0, dwRunID,
|
||||
static_cast<unsigned short>(copyDataStruct.cbData), 0, copyDataStruct.lpData, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CProcessCommandMessage : public CMsgProc
|
||||
{
|
||||
public:
|
||||
|
||||
CProcessCommandMessage(CManageClient& ManageClient) : m_ManageClient(ManageClient) { }
|
||||
|
||||
private:
|
||||
|
||||
virtual LRESULT operator () (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
char* szCommand = 0;
|
||||
|
||||
CConsoleWindow* lpConsoleWindow = m_ManageClient.GetConsoleWindow();
|
||||
if(0 == lpConsoleWindow)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case ID_MANAGECLIENT_OPEN_CONSOLE: lpConsoleWindow->Initialize("ROWManageClient"); break;
|
||||
case ID_MANAGECLIENT_CLOSE_CONSOLE: lpConsoleWindow->Destroy(); break;
|
||||
case ID_MANAGECLIENT_RELOADSETUP: szCommand = "reload"; break;
|
||||
}
|
||||
|
||||
if(0 != szCommand)
|
||||
{
|
||||
lpConsoleWindow->GetCMDProcess().Add(
|
||||
lpConsoleWindow->GetConsoleCMDFactory().Create(szCommand, strlen(szCommand)));
|
||||
}
|
||||
|
||||
if(LOWORD(wParam) == IDM_EXIT)
|
||||
{
|
||||
DETLOG0(g_Log, "Terminate ManageServer System Tray.");
|
||||
PostMessage(hWnd, WM_QUIT, 0, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CManageClient& m_ManageClient;
|
||||
};
|
||||
|
||||
bool CManageClient::InitializeMsgProc()
|
||||
{
|
||||
CMsgProcessMgr* lpMsgProcessMgr = GetMsgProcessMgr();
|
||||
if(0 == lpMsgProcessMgr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int nErrorCount = 0;
|
||||
|
||||
lpMsgProcessMgr->Remove(WM_COPYDATA);
|
||||
|
||||
nErrorCount += lpMsgProcessMgr->Register(WM_COPYDATA, new CIPCMessage) ? 0 : 1;
|
||||
nErrorCount += lpMsgProcessMgr->Register(WM_COMMAND, new CProcessCommandMessage(*this)) ? 0 : 1;
|
||||
|
||||
return 0 == nErrorCount;
|
||||
}
|
||||
53
Server/ManageTool/ManageClient/ReadMe.txt
Normal file
53
Server/ManageTool/ManageClient/ReadMe.txt
Normal file
@@ -0,0 +1,53 @@
|
||||
========================================================================
|
||||
Win32 응용 프로그램 : ManageClient 프로젝트 개요
|
||||
========================================================================
|
||||
|
||||
응용 프로그램 마법사에서 이 ManageClient 응용 프로그램을 만들었습니다.
|
||||
이 파일에는 ManageClient 응용 프로그램을 구성하는 각각의 파일에
|
||||
들어 있는 요약 설명이 포함되어 있습니다.
|
||||
|
||||
|
||||
ManageClient.vcproj
|
||||
응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다.
|
||||
해당 파일을 생성한 Visual C++의 버전 정보를 비롯하여
|
||||
응용 프로그램 마법사에서 선택한 플랫폼, 구성 및
|
||||
프로젝트 기능에 대한 정보가 들어 있습니다.
|
||||
|
||||
ManageClient.cpp
|
||||
기본 응용 프로그램 소스 파일입니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
응용 프로그램 마법사에서 다음 리소스를 만들었습니다.
|
||||
|
||||
ManageClient.rc
|
||||
프로그램에서 사용하는 모든
|
||||
Microsoft Windows 리소스의 목록입니다. RES 하위 디렉터리에 저장된
|
||||
아이콘, 비트맵, 및 커서 등이 여기에 포함됩니다. 이 파일은
|
||||
Microsoft Visual C++에서 직접 편집할 수 있습니다.
|
||||
|
||||
Resource.h
|
||||
새 리소스 ID를 정의하는 표준 헤더 파일입니다.
|
||||
Microsoft Visual C++에서 이 파일을 읽고 업데이트합니다.
|
||||
ManageClient.ico
|
||||
아이콘 파일이며, 응용 프로그램의 아이콘(32x32)으로 사용됩니다.
|
||||
해당 아이콘은 기본 리소스 파일인 ManageClient.rc에 의해 포함됩니다.
|
||||
|
||||
small.ico
|
||||
아이콘 파일이며, 응용 프로그램 아이콘의 더 작은 버전(16x16)이
|
||||
들어 있습니다. 해당 아이콘은 기본 리소스 파일인
|
||||
ManageClient.rc에 의해 포함됩니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
기타 표준 파일:
|
||||
|
||||
StdAfx.h 및 StdAfx.cpp는
|
||||
ManageClient.pch라는 이름의 PCH(미리 컴파일된 헤더) 파일과
|
||||
StdAfx.obj라는 이름의 미리 컴파일된 형식 파일을 빌드하는 데 사용됩니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
기타 참고:
|
||||
|
||||
응용 프로그램 마법사에서 사용하는 "TODO:" 주석은 사용자가 추가하거나 사용자 지정해야 하는
|
||||
소스 코드 부분을 나타냅니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
30
Server/ManageTool/ManageClient/resource.h
Normal file
30
Server/ManageTool/ManageClient/resource.h
Normal file
@@ -0,0 +1,30 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by ManageClient.rc
|
||||
//
|
||||
#define IDC_MYICON 2
|
||||
#define IDD_MANAGECLIENT_DIALOG 102
|
||||
#define IDS_APP_TITLE 103
|
||||
#define IDM_ABOUT 104
|
||||
#define IDM_EXIT 105
|
||||
#define IDI_SMALL 108
|
||||
#define IDC_MANAGECLIENT 109
|
||||
#define IDR_MAINFRAME 128
|
||||
#define IDI_ICON1 129
|
||||
#define IDI_MANAGECLIENT 129
|
||||
#define ID_MANAGECLIENT_RELOADSETUP 32771
|
||||
#define ID_MANAGECLIENT_CLOSE_CONSOLE 32774
|
||||
#define ID_MANAGECLIENT_OPEN_CONSOLE 32775
|
||||
#define IDC_STATIC -1
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 130
|
||||
#define _APS_NEXT_COMMAND_VALUE 32776
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 110
|
||||
#endif
|
||||
#endif
|
||||
BIN
Server/ManageTool/ManageClient/small.ico
Normal file
BIN
Server/ManageTool/ManageClient/small.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
8
Server/ManageTool/ManageClient/stdafx.cpp
Normal file
8
Server/ManageTool/ManageClient/stdafx.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
// stdafx.cpp : 표준 포함 파일만 들어 있는 소스 파일입니다.
|
||||
// ManageClient.pch는 미리 컴파일된 헤더가 됩니다.
|
||||
// stdafx.obj에는 미리 컴파일된 형식 정보가 포함됩니다.
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: 필요한 추가 헤더는
|
||||
// 이 파일이 아닌 STDAFX.H에서 참조합니다.
|
||||
18
Server/ManageTool/ManageClient/stdafx.h
Normal file
18
Server/ManageTool/ManageClient/stdafx.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// stdafx.h : 자주 사용하지만 자주 변경되지는 않는
|
||||
// 표준 시스템 포함 파일 및 프로젝트 관련 포함 파일이
|
||||
// 들어 있는 포함 파일입니다.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // 거의 사용되지 않는 내용은 Windows 헤더에서 제외합니다.
|
||||
// Windows 헤더 파일입니다.
|
||||
#include <windows.h>
|
||||
// C의 런타임 헤더 파일입니다.
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
#include <tchar.h>
|
||||
|
||||
// TODO: 프로그램에 필요한 추가 헤더는 여기에서 참조합니다.
|
||||
84
Server/ManageTool/ManageLibrary/Db/ManageServerDB.cpp
Normal file
84
Server/ManageTool/ManageLibrary/Db/ManageServerDB.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#include "stdafx.h"
|
||||
#include "SQLite.h"
|
||||
|
||||
#include "ManageServerDB.h"
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
const char* CManageServerDB::GetDefaultDBFileName()
|
||||
{
|
||||
return "./ManageServerDB.dat";
|
||||
}
|
||||
|
||||
|
||||
CManageServerDB& CManageServerDB::GetInstance()
|
||||
{
|
||||
static CManageServerDB manageServerDB;
|
||||
return manageServerDB;
|
||||
}
|
||||
|
||||
|
||||
CManageServerDB::CManageServerDB()
|
||||
: m_lpSQLite(new CSQLite)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
CManageServerDB::~CManageServerDB()
|
||||
{
|
||||
if(0 != m_lpSQLite)
|
||||
{
|
||||
delete m_lpSQLite;
|
||||
m_lpSQLite = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CManageServerDB::Initialize(const char* szDBFileName)
|
||||
{
|
||||
if(0 == m_lpSQLite || !m_lpSQLite->Open(szDBFileName))
|
||||
{
|
||||
ERRLOG1(g_Log, "Cannot open database : %s", szDBFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create Tables - 이미 만들어져 있으면 에러가 난다.
|
||||
const int MAX_QUERY_NUM = 5;
|
||||
const char* szCreateTableQuery[MAX_QUERY_NUM] =
|
||||
{
|
||||
"CREATE TABLE TblManageToolUser (ID char(16) PRIMARY KEY, PASS char(16), "
|
||||
"NAME char(32), IP char(16), LEVEL INTEGER)",
|
||||
|
||||
"CREATE TABLE TblServerInfo (IP INTEGER PRIMARY KEY, ServerName char(64))",
|
||||
"CREATE TABLE TblRunPath (PathID INTEGER PRIMARY KEY, RunPath char(260))",
|
||||
"CREATE TABLE TblRunOptions (OptionID INTEGER PRIMARY KEY, RunOption char(260))",
|
||||
"CREATE TABLE TblRunInfo (RunID INTEGER PRIMARY KEY, PathID INTEGER, OptionID INTEGER, ServerIP INTEGER)"
|
||||
};
|
||||
|
||||
m_lpSQLite->SetErrorLog(false);
|
||||
|
||||
for(int nQuery = 0; nQuery < MAX_QUERY_NUM; ++nQuery)
|
||||
{
|
||||
CSQLite::Dataset createUserTable(*m_lpSQLite, szCreateTableQuery[nQuery]);
|
||||
|
||||
if(!createUserTable.Compile() || !createUserTable.Execute())
|
||||
{
|
||||
if(0 != createUserTable.GetLastError())
|
||||
{
|
||||
// Table create failed. if already create failed?
|
||||
char szTableName[MAX_PATH];
|
||||
int nLength = sscanf(createUserTable.GetLastError(), "table %s already exists", szTableName);
|
||||
if(EOF == nLength || 0 == nLength)
|
||||
{
|
||||
m_lpSQLite->SetErrorLog(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_lpSQLite->SetErrorLog(true);
|
||||
return true;
|
||||
}
|
||||
24
Server/ManageTool/ManageLibrary/Db/ManageServerDB.h
Normal file
24
Server/ManageTool/ManageLibrary/Db/ManageServerDB.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef _MANAGE_SERVER_TOOL_DB_FILE_DB_LIB_SQL_LITE_
|
||||
#define _MANAGE_SERVER_TOOL_DB_FILE_DB_LIB_SQL_LITE_
|
||||
|
||||
class CSQLite;
|
||||
|
||||
class CManageServerDB
|
||||
{
|
||||
public:
|
||||
|
||||
static const char* GetDefaultDBFileName();
|
||||
static CManageServerDB& GetInstance();
|
||||
|
||||
bool Initialize(const char* szDBFileName = CManageServerDB::GetDefaultDBFileName());
|
||||
CSQLite& GetSQLite() { return *m_lpSQLite; }
|
||||
|
||||
private:
|
||||
|
||||
CManageServerDB();
|
||||
~CManageServerDB();
|
||||
|
||||
CSQLite* m_lpSQLite;
|
||||
};
|
||||
|
||||
#endif
|
||||
220
Server/ManageTool/ManageLibrary/Db/SQLite.cpp
Normal file
220
Server/ManageTool/ManageLibrary/Db/SQLite.cpp
Normal file
@@ -0,0 +1,220 @@
|
||||
#include "stdafx.h"
|
||||
#include "SQLite.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sqlite-library/sqlite.h>
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
#define SAFE_FREE_SQLITE_ERRMSG(p) if(p) { sqlite_freemem(p); (p) = 0; }
|
||||
|
||||
CSQLite::CSQLite()
|
||||
: m_sqlDB(0), m_szErrorMsg(0), m_bLogError(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CSQLite::~CSQLite()
|
||||
{
|
||||
SAFE_FREE_SQLITE_ERRMSG(m_szErrorMsg);
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
bool CSQLite::Open(const char* szDBFileName)
|
||||
{
|
||||
char* szErrMsg = 0;
|
||||
m_sqlDB = sqlite_open(szDBFileName, 0, &szErrMsg);
|
||||
|
||||
if(0 == m_sqlDB)
|
||||
{
|
||||
if(m_bLogError)
|
||||
{
|
||||
ERRLOG2(g_Log, "Can't open database : %s(%d)",
|
||||
szDBFileName, GetLastError());
|
||||
}
|
||||
|
||||
SAFE_FREE_SQLITE_ERRMSG(m_szErrorMsg);
|
||||
m_szErrorMsg = szErrMsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSQLite::Close()
|
||||
{
|
||||
if(0 != m_sqlDB)
|
||||
{
|
||||
sqlite_close(m_sqlDB);
|
||||
}
|
||||
}
|
||||
|
||||
int CSQLite::GetLastInsertRowID()
|
||||
{
|
||||
return sqlite_last_insert_rowid(m_sqlDB);
|
||||
}
|
||||
|
||||
|
||||
bool CSQLite::ExecuteQuery(const char* szQuery, QueryCallBack fnCallBack, void* callBackArg)
|
||||
{
|
||||
char* szErrorMsg = 0;
|
||||
int nResult = sqlite_exec(m_sqlDB, szQuery, fnCallBack, callBackArg, &szErrorMsg);
|
||||
if(SQLITE_OK != nResult)
|
||||
{
|
||||
if(m_bLogError)
|
||||
{
|
||||
ERRLOG2(g_Log, "Execute Query failed : %s(Query:%s)",
|
||||
szErrorMsg, szQuery);
|
||||
}
|
||||
|
||||
SAFE_FREE_SQLITE_ERRMSG(m_szErrorMsg);
|
||||
m_szErrorMsg = szErrorMsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CSQLite::Dataset::Dataset(CSQLite& sqlite, const char* szQuery)
|
||||
: m_SQLite(sqlite),
|
||||
m_sqlite_vm(0),
|
||||
m_szQuery(szQuery),
|
||||
m_szErrorMsg(0),
|
||||
m_nExecuteResult(SQLITE_ROW)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
CSQLite::Dataset::~Dataset()
|
||||
{
|
||||
Free();
|
||||
SAFE_FREE_SQLITE_ERRMSG(m_szErrorMsg);
|
||||
}
|
||||
|
||||
|
||||
bool CSQLite::Dataset::Compile()
|
||||
{
|
||||
Free();
|
||||
|
||||
const char* szNextQuery = 0;
|
||||
char* szErrorMsg = 0;
|
||||
|
||||
if('\0' == *m_szQuery)
|
||||
{
|
||||
// 쿼리가 끝까지 완료되었으면 빠져나감.
|
||||
return false;
|
||||
}
|
||||
|
||||
int nResult = sqlite_compile(m_SQLite.GetHandle(), m_szQuery,
|
||||
&szNextQuery, &m_sqlite_vm, &szErrorMsg);
|
||||
|
||||
if(SQLITE_OK != nResult)
|
||||
{
|
||||
if(m_SQLite.IsErrorLogging())
|
||||
{
|
||||
ERRLOG2(g_Log, "SQLite error : compile query error - %s(%d)",
|
||||
szErrorMsg, GetLastError());
|
||||
}
|
||||
|
||||
SAFE_FREE_SQLITE_ERRMSG(m_szErrorMsg);
|
||||
m_szErrorMsg = szErrorMsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_szQuery = szNextQuery;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSQLite::Dataset::Execute(int* nColNum_Out,
|
||||
const char *** pazValue,
|
||||
const char *** pazColName)
|
||||
{
|
||||
m_nExecuteResult = sqlite_step(m_sqlite_vm, nColNum_Out, pazValue, pazColName);
|
||||
|
||||
if(SQLITE_ROW == m_nExecuteResult ||
|
||||
SQLITE_DONE == m_nExecuteResult)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_SQLite.IsErrorLogging())
|
||||
{
|
||||
ERRLOG1(g_Log, "SQLite error : Dataset - execute error :%s",
|
||||
sqlite_error_string(m_nExecuteResult));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CSQLite::Dataset::IsExcuteDone()
|
||||
{
|
||||
return (SQLITE_ROW != m_nExecuteResult);
|
||||
}
|
||||
|
||||
|
||||
void CSQLite::Dataset::Free()
|
||||
{
|
||||
if(0 != m_sqlite_vm)
|
||||
{
|
||||
char* szErrorMsg = 0;
|
||||
|
||||
if(SQLITE_OK != sqlite_finalize(m_sqlite_vm, &szErrorMsg))
|
||||
{
|
||||
if(m_SQLite.IsErrorLogging())
|
||||
{
|
||||
ERRLOG2(g_Log, "SQLite error : finalize error - %s(%d)",
|
||||
szErrorMsg, GetLastError());
|
||||
}
|
||||
|
||||
SAFE_FREE_SQLITE_ERRMSG(m_szErrorMsg);
|
||||
m_szErrorMsg = szErrorMsg;
|
||||
}
|
||||
|
||||
m_sqlite_vm = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CSQLite::Tableset::Tableset(CSQLite& sqlite, const char* szQuery)
|
||||
: m_SQLite(sqlite), m_szQuery(szQuery), m_nRow(0), m_nCol(0),
|
||||
m_szResult(0), m_szErrorMsg(0)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
CSQLite::Tableset::~Tableset()
|
||||
{
|
||||
if(0 != m_szResult)
|
||||
{
|
||||
sqlite_free_table(m_szResult);
|
||||
m_szResult = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CSQLite::Tableset::Execute()
|
||||
{
|
||||
char* szErrorMsg = 0;
|
||||
|
||||
if(SQLITE_OK != sqlite_get_table(m_SQLite.GetHandle(), m_szQuery,
|
||||
&m_szResult, &m_nRow, &m_nCol, &szErrorMsg))
|
||||
{
|
||||
if(m_SQLite.IsErrorLogging())
|
||||
{
|
||||
ERRLOG2(g_Log, "SQLite error : get_table error - %s(%d)",
|
||||
szErrorMsg, GetLastError());
|
||||
}
|
||||
|
||||
SAFE_FREE_SQLITE_ERRMSG(m_szErrorMsg);
|
||||
m_szErrorMsg = szErrorMsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
93
Server/ManageTool/ManageLibrary/Db/SQLite.h
Normal file
93
Server/ManageTool/ManageLibrary/Db/SQLite.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#ifndef _MANAGE_TOOL_DB_FILE_DB_LIB_SQL_LITE_
|
||||
#define _MANAGE_TOOL_DB_FILE_DB_LIB_SQL_LITE_
|
||||
|
||||
// forward decl;
|
||||
typedef struct sqlite_vm sqlite_vm;
|
||||
typedef struct sqlite sqlite;
|
||||
|
||||
class CSQLite
|
||||
{
|
||||
public:
|
||||
|
||||
typedef int (*QueryCallBack)(void *callBackArg, int nColumnNum,
|
||||
char **szColumnValues, char **szColumnNames);
|
||||
|
||||
CSQLite();
|
||||
virtual ~CSQLite();
|
||||
|
||||
bool Open(const char* szFileName);
|
||||
void Close();
|
||||
|
||||
int GetLastInsertRowID();
|
||||
bool ExecuteQuery(const char* szQuery, QueryCallBack callBack, void* callBackArg);
|
||||
const char* GetLastError() const { return m_szErrorMsg; }
|
||||
|
||||
void SetErrorLog(bool bLogError) { m_bLogError = bLogError; }
|
||||
bool IsErrorLogging() { return m_bLogError; }
|
||||
|
||||
class Dataset
|
||||
{
|
||||
public:
|
||||
|
||||
Dataset(CSQLite& sqlite, const char* szQuery);
|
||||
~Dataset();
|
||||
|
||||
// 쿼리를 컴파일해서 처리 준비를 한다.
|
||||
bool Compile();
|
||||
|
||||
// 쿼리를 실행하고 결과를 얻어온다.
|
||||
bool Execute(int* nColNum_Out = 0,
|
||||
const char ***pazValue = 0,
|
||||
const char *** pazColName = 0);
|
||||
|
||||
bool IsExcuteDone();
|
||||
|
||||
const char* GetLastError() const { return m_szErrorMsg; }
|
||||
void Free();
|
||||
|
||||
private:
|
||||
|
||||
CSQLite& m_SQLite;
|
||||
sqlite_vm* m_sqlite_vm;
|
||||
const char* m_szQuery;
|
||||
char* m_szErrorMsg;
|
||||
int m_nExecuteResult;
|
||||
};
|
||||
|
||||
class Tableset
|
||||
{
|
||||
public:
|
||||
|
||||
Tableset(CSQLite& sqlite, const char* szQuery);
|
||||
~Tableset();
|
||||
|
||||
bool Execute();
|
||||
|
||||
char** GetResult() { return m_szResult; }
|
||||
int GetMaxRow() { return m_nRow; }
|
||||
int GetMaxCol() { return m_nCol; }
|
||||
|
||||
const char* GetLastError() const { return m_szErrorMsg; }
|
||||
|
||||
private:
|
||||
|
||||
CSQLite& m_SQLite;
|
||||
const char* m_szQuery;
|
||||
char** m_szResult;
|
||||
int m_nRow;
|
||||
int m_nCol;
|
||||
char* m_szErrorMsg;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
sqlite* GetHandle() { return m_sqlDB; }
|
||||
sqlite* m_sqlDB;
|
||||
char* m_szErrorMsg;
|
||||
bool m_bLogError;
|
||||
|
||||
friend class Dataset;
|
||||
friend class Tableset;
|
||||
};
|
||||
|
||||
#endif
|
||||
232
Server/ManageTool/ManageLibrary/ManageLibrary.vcproj
Normal file
232
Server/ManageTool/ManageLibrary/ManageLibrary.vcproj
Normal file
@@ -0,0 +1,232 @@
|
||||
<?xml version="1.0" encoding="ks_c_5601-1987"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="ManageLibrary"
|
||||
ProjectGUID="{9E56BA4B-AEF8-4F86-9B17-50647A98AE64}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../Library/$(ConfigurationName)"
|
||||
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../../RylServerProject/BaseLibrary;../../RylServerProject/RylServerLibrary"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/ManageLibrary.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../Library/$(ConfigurationName)"
|
||||
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="./;../;../../RylServerProject/BaseLibrary;../../RylServerProject/RylServerLibrary"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/ManageLibrary.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Network"
|
||||
Filter="">
|
||||
<Filter
|
||||
Name="Dispatch"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\SendManagePacket.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\SendManagePacket.h">
|
||||
</File>
|
||||
<Filter
|
||||
Name="ManageClient"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\ManageClient\ManageClientDispatch.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\ManageClient\ManageClientDispatch.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="ManageServer"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\ManageServer\ManageServerDispatch.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\ManageServer\ManageServerDispatch.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\ManageServer\ManageToolServerDispatch.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\ManageServer\ManageToolServerDispatch.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\ManageServer\ParseUserManage.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\ManageServer\StatServerDispatch.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\ManageServer\StatServerDispatch.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\ManageServer\StatServerMultiDispatch.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Network\Dispatch\ManageServer\StatServerMultiDispatch.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="UserManage"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\UserManage\ToolUserManageTable.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\UserManage\ToolUserManageTable.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\UserManage\UserStatistics.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\UserManage\UserStatistics.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="ServerManage"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\ServerManage\ManageClientManager.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ServerManage\ManageClientManager.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ServerManage\SendManageInfo.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="DB"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\Db\ManageServerDB.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Db\ManageServerDB.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Db\SQLite.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Db\SQLite.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Setup"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\Setup\RylServerBindRunID.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Setup\RylServerBindRunID.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Setup\RylServerGroupSetup.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Setup\RylServerGroupSetup.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Setup\SetupClient.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Setup\SetupClient.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\ReadMe.txt">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,835 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "ManageClientDispatch.h"
|
||||
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Packet/ManagePacketCmd.h>
|
||||
#include <Setup/SetupClient.h>
|
||||
|
||||
#include <Network/Dispatch/SingleDispatchStorage.h>
|
||||
#include <Network/Dispatch/SendManagePacket.h>
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
#include <tlhelp32.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#pragma comment(lib, "winmm.lib")
|
||||
|
||||
/*
|
||||
// forward decl
|
||||
HANDLE GetProcessHandle(const char* szProcessFullPathName, unsigned long* lpdwPID);
|
||||
*/
|
||||
|
||||
enum ManageClientConst
|
||||
{
|
||||
MANAGE_CLIENT_DEFAULT_DISPATCH_NUM = 10
|
||||
};
|
||||
|
||||
|
||||
CManageClientDispatch::RunExtraInfo::RunExtraInfo(const ServerManage::RunInfo& runInfo,
|
||||
HANDLE hProcess, unsigned long dwProcessID)
|
||||
: m_RunInfo(runInfo), m_hProcess(hProcess), m_dwProcessID(dwProcessID),
|
||||
m_hWnd(0), m_dwCustomStatus(0), m_dwLastSetWindowHandleTime(0)
|
||||
{
|
||||
char szCommand[MAX_PATH];
|
||||
|
||||
_snprintf(szCommand, MAX_PATH - 1, "%s", m_RunInfo.m_szOption);
|
||||
szCommand[MAX_PATH - 1] = 0;
|
||||
|
||||
char* szData = strtok(szCommand, " \t\r\n");
|
||||
while(0 != szData)
|
||||
{
|
||||
m_CommandSet.insert(szData);
|
||||
szData = strtok(0, " \t\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CSingleDispatch& CManageClientDispatch::GetDispatchTable()
|
||||
{
|
||||
static CSingleDispatch singleDispatch;
|
||||
return singleDispatch;
|
||||
}
|
||||
|
||||
|
||||
CManageClientDispatch::CManageClientDispatch(CSession& Session)
|
||||
: CRylServerDispatch(Session, MANAGE_CLIENT_DEFAULT_DISPATCH_NUM),
|
||||
m_hPatchFile(INVALID_HANDLE_VALUE),
|
||||
m_bDoPatchNow(false)
|
||||
{
|
||||
TCHAR* szTempFileName = _T("./mytmp_patch.tmp");
|
||||
|
||||
memset(m_szTempPatchFileName, 0, sizeof(TCHAR) * MAX_PATH);
|
||||
_tcscpy(m_szTempPatchFileName, szTempFileName);
|
||||
|
||||
TCHAR szFullPathModuleName[MAX_PATH];
|
||||
|
||||
GetModuleFileName(NULL, szFullPathModuleName, MAX_PATH - 1);
|
||||
szFullPathModuleName[MAX_PATH - 1] = 0;
|
||||
|
||||
TCHAR szDrive[MAX_PATH];
|
||||
TCHAR szPath[MAX_PATH];
|
||||
TCHAR szName[MAX_PATH];
|
||||
TCHAR szExtension[MAX_PATH];
|
||||
|
||||
_tsplitpath(szFullPathModuleName, szDrive, szPath, szName, szExtension);
|
||||
|
||||
_sntprintf(m_szTempPatchFileName, MAX_PATH - 1,
|
||||
_T("%s\\%s\\%s"), szDrive, szPath, szTempFileName);
|
||||
m_szTempPatchFileName[MAX_PATH - 1] = 0;
|
||||
|
||||
DETLOG1(g_Log, "this:0x%p/CManageClientDispatch Created", this);
|
||||
}
|
||||
|
||||
|
||||
CManageClientDispatch::~CManageClientDispatch()
|
||||
{
|
||||
if(INVALID_HANDLE_VALUE != m_hPatchFile)
|
||||
{
|
||||
// 파일이 아직 열려 있다. 닫는다.
|
||||
ERRLOG2(g_Log, "this:0x%0p/HANDLE:0x%p/PatchFile is not closed. close now", this, m_hPatchFile);
|
||||
CloseHandle(m_hPatchFile);
|
||||
}
|
||||
|
||||
DETLOG1(g_Log, "this:0x%p/CManageClientDispatch Destroyed", this);
|
||||
}
|
||||
|
||||
|
||||
void CManageClientDispatch::Connected()
|
||||
{
|
||||
GetDispatchTable().SetDispatch(this);
|
||||
DETLOG1(g_Log, "this:0x%p/CManageClientDispatch Connected", this);
|
||||
}
|
||||
|
||||
|
||||
void CManageClientDispatch::Disconnected()
|
||||
{
|
||||
GetDispatchTable().RemoveDispatch(this);
|
||||
DETLOG1(g_Log, "this:0x%p/CManageClientDispatch Disconnected", this);
|
||||
}
|
||||
|
||||
|
||||
bool CManageClientDispatch::DispatchPacket(PktBase* lpPktBase)
|
||||
{
|
||||
PktBase::LengthType nPacketLen = lpPktBase->GetLen();
|
||||
|
||||
if(nPacketLen < sizeof(ServerManage::ManageCommand))
|
||||
{
|
||||
ERRLOG3(g_Log, "IP:%15s/PacketLen:%d/Cmd:0x%02x/Invalid packet length or command",
|
||||
GetSession().GetRemoteAddr().get_addr_string(), lpPktBase->GetLen(), lpPktBase->GetCmd());
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerManage::ManageCommand* lpManageCommand =
|
||||
reinterpret_cast<ServerManage::ManageCommand*>(lpPktBase);
|
||||
|
||||
if(nPacketLen != sizeof(ServerManage::ManageCommand) + lpManageCommand->usDataLen)
|
||||
{
|
||||
ERRLOG3(g_Log, "IP:%15s/PacketLen:%d/Cmd:0x%02x/Invalid packet length",
|
||||
GetSession().GetRemoteAddr().get_addr_string(), lpPktBase->GetLen(), lpPktBase->GetCmd());
|
||||
}
|
||||
else
|
||||
{
|
||||
TCHAR* szWindowName = 0;
|
||||
|
||||
char* lpData = (0 != lpManageCommand->usDataLen) ?
|
||||
reinterpret_cast<char*>(lpManageCommand + 1) : 0;
|
||||
|
||||
const TCHAR* szErrorMessage = 0;
|
||||
|
||||
switch(lpManageCommand->GetCmd())
|
||||
{
|
||||
case ServerManage::CMD::UpdateRunList: // 실행 목룍을 준다 (ManageServer -> ManageClient, ManageTool), Ack없음.
|
||||
ProcessUpdateRunList(lpData, lpManageCommand->usDataLen, lpManageCommand->usFlags);
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::RunProcess: // 실행한다. (ManageTool -> ManageServer -> ManageClient), Ack는 반대 순서로 전송
|
||||
ProcessRunServer(lpManageCommand->dwRunID);
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::QuitProcess: // 종료한다. (ManageTool -> ManageServer -> ManageClient), Ack는 반대 순성로 전송
|
||||
ProcessQuitServer(lpManageCommand->dwRunID);
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::ForceTerminate: // 강제 종료한다. (ManageTool -> ManageServer -> ManageClient), Ack는 반대 순서로 전송
|
||||
ProcessTerminateServer(lpManageCommand->dwRunID);
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::RelayCommand: // 패킷 커맨드를 윈도우 메시지를 써서 중계해서 넘긴다.
|
||||
|
||||
/*
|
||||
if(!ProcessRelayCommand(lpManageCommand->nMessage,
|
||||
lpManageCommand->wParam, lpManageCommand->lParam,
|
||||
szWindowName, lpData, lpManageCommand->usDataLen, lpManageCommand->cFlag))
|
||||
{
|
||||
szErrorMessage = _T("RelayCommand : RelayCommand Failed");
|
||||
}
|
||||
*/
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::AutoPatch: // 자기 자신을 패치한다
|
||||
|
||||
if(!ProcessAutoPatch(lpData, lpManageCommand->usDataLen, lpManageCommand->usFlags))
|
||||
{
|
||||
szErrorMessage = _T("AutoPatch : AutoPatch packet process failed");
|
||||
}
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::ChangeSetup: // 설정을 바꾸고 저장한다.
|
||||
|
||||
if(!ManageSetup::ClientSetup::GetInstance().SerializeIn(lpData, lpManageCommand->usDataLen))
|
||||
{
|
||||
szErrorMessage = _T("ChangeSetup : Change setup failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
ManageSetup::ClientSetup::GetInstance().Save();
|
||||
}
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::ReloadSetup: // 설정을 재로드한다.
|
||||
|
||||
ManageSetup::ClientSetup::GetInstance().Load();
|
||||
break;
|
||||
|
||||
|
||||
case ServerManage::CMD::ExecuteCommand:
|
||||
ProcessExecuteConsoleCommand(lpManageCommand);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
szErrorMessage = _T("Unknown message : Process failed");
|
||||
break;
|
||||
}
|
||||
|
||||
if(0 != szErrorMessage)
|
||||
{
|
||||
ERRLOG4(g_Log, "IP:%15s/DetailCmd:0x%02x/Error:%d/%s",
|
||||
GetSession().GetRemoteAddr().get_addr_string(),
|
||||
lpPktBase->GetCmd(), GetLastError(), szErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool CManageClientDispatch::ProcessRelayCommand(unsigned int nMessage, WPARAM wParam, LPARAM lParam,
|
||||
const char* szWindowName, const char* lpData,
|
||||
unsigned short usDataLen, unsigned char cFlag)
|
||||
{
|
||||
if(0 != szWindowName)
|
||||
{
|
||||
HWND hWnd = FindWindow(0, szWindowName);
|
||||
if(0 != hWnd)
|
||||
{
|
||||
if(0 != lpData && WM_COPYDATA == nMessage)
|
||||
{
|
||||
COPYDATASTRUCT copyDataStruct;
|
||||
|
||||
copyDataStruct.dwData = 0;
|
||||
copyDataStruct.cbData = usDataLen;
|
||||
copyDataStruct.lpData = (void*)lpData;
|
||||
|
||||
// 메시지를 보낸다.
|
||||
SendMessage(hWnd, nMessage, wParam,
|
||||
reinterpret_cast<LPARAM>(©DataStruct));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessage(hWnd, nMessage, wParam, lParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CManageClientDispatch::ProcessAutoPatch(const char* lpData, unsigned short usDataLen, unsigned short usFlag)
|
||||
{
|
||||
switch(usFlag)
|
||||
{
|
||||
case ServerManage::ManageCommand::AUTOPATCH_OPENFILE:
|
||||
|
||||
if(INVALID_HANDLE_VALUE != m_hPatchFile)
|
||||
{
|
||||
// 패치 파일이 열려 있음. 닫는다.
|
||||
ERRLOG2(g_Log, "this:0x%0p/HANDLE:0x%p/PatchFile is not closed. close now for create new one",
|
||||
this, m_hPatchFile);
|
||||
|
||||
CloseHandle(m_hPatchFile);
|
||||
}
|
||||
|
||||
// 파일을 생성한다.
|
||||
m_hPatchFile = CreateFile(m_szTempPatchFileName, GENERIC_WRITE, 0, 0,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
||||
if(INVALID_HANDLE_VALUE == m_hPatchFile)
|
||||
{
|
||||
ERRLOG2(g_Log, "this:0x%p/Error:%d/Patch tempfile create failed",
|
||||
this, GetLastError());
|
||||
}
|
||||
break;
|
||||
|
||||
case ServerManage::ManageCommand::AUTOPATCH_DATA:
|
||||
|
||||
if(INVALID_HANDLE_VALUE != m_hPatchFile)
|
||||
{
|
||||
unsigned long dwWritten = 0;
|
||||
unsigned long dwTotalWritten = 0;
|
||||
|
||||
while(usDataLen != dwTotalWritten)
|
||||
{
|
||||
if(!WriteFile(m_hPatchFile, lpData, usDataLen, &dwWritten, 0))
|
||||
{
|
||||
ERRLOG3(g_Log, "this:0x%p/HANDLE:0x%p/Error:%d/Patchfile write failed.",
|
||||
this, m_hPatchFile, GetLastError());
|
||||
|
||||
CloseHandle(m_hPatchFile);
|
||||
m_hPatchFile = INVALID_HANDLE_VALUE;
|
||||
|
||||
DeleteFile(m_szTempPatchFileName);
|
||||
break;
|
||||
}
|
||||
|
||||
dwTotalWritten += dwWritten;
|
||||
}
|
||||
|
||||
if(0 == usDataLen && INVALID_HANDLE_VALUE != m_hPatchFile)
|
||||
{
|
||||
// 파일을 전부 받았다. 이제 전송을 종료하고 패치를 적용한다.
|
||||
m_bDoPatchNow = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG1(g_Log, "this:0x%p/Patchfile is invalid", this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CManageClientDispatch::ProcessUpdateRunList(const char* szData, unsigned short usDataLen,
|
||||
unsigned short usFlags)
|
||||
{
|
||||
if(ServerManage::SEND_RUNINFO_START == usFlags)
|
||||
{
|
||||
// 기존에 열었던 Process들에 대해서 전부 핸들을 닫는다.
|
||||
RunTable::iterator pos = m_RunTable.begin();
|
||||
RunTable::iterator end = m_RunTable.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
RunExtraInfo& runExtraInfo = pos->second;
|
||||
|
||||
if(0 != runExtraInfo.m_hProcess)
|
||||
{
|
||||
CloseHandle(runExtraInfo.m_hProcess);
|
||||
}
|
||||
}
|
||||
|
||||
m_RunTable.clear();
|
||||
}
|
||||
else if(ServerManage::SEND_RUNINFO_NOW == usFlags)
|
||||
{
|
||||
// RunTable에 세팅하고, 프로세스를 연다.
|
||||
const ServerManage::RunInfo* lpRunInfo = reinterpret_cast<const ServerManage::RunInfo*>(szData);
|
||||
const ServerManage::RunInfo* lpEndRunInfo = lpRunInfo + (usDataLen / sizeof(ServerManage::RunInfo));
|
||||
|
||||
for(; lpRunInfo != lpEndRunInfo; ++lpRunInfo)
|
||||
{
|
||||
m_RunTable.insert(RunTable::value_type(lpRunInfo->m_dwRunID,
|
||||
RunExtraInfo(*lpRunInfo, 0, 0)));
|
||||
}
|
||||
}
|
||||
else if(ServerManage::SEND_RUNINFO_FINISH == usFlags)
|
||||
{
|
||||
// 프로세스 상태 갱신 패킷을 보낸다.
|
||||
CheckProcessStatus();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CManageClientDispatch::ProcessRunServer(unsigned long dwRunID)
|
||||
{
|
||||
RunTable::iterator pos = m_RunTable.find(dwRunID);
|
||||
|
||||
if(pos != m_RunTable.end())
|
||||
{
|
||||
RunExtraInfo& runExInfo = pos->second;
|
||||
|
||||
TCHAR szDrive[MAX_PATH];
|
||||
TCHAR szPath[MAX_PATH];
|
||||
|
||||
TCHAR szDefaultPath[MAX_PATH];
|
||||
|
||||
_splitpath(runExInfo.m_RunInfo.m_szPath, szDrive, szPath, 0, 0);
|
||||
|
||||
_snprintf(szDefaultPath, MAX_PATH - 1, "%s%s", szDrive, szPath);
|
||||
szDefaultPath[MAX_PATH - 1] = 0;
|
||||
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
|
||||
// Start the child process.
|
||||
|
||||
|
||||
/*
|
||||
if(CreateProcess(runExInfo.m_RunInfo.m_szPath, runExInfo.m_RunInfo.m_szOption, 0, 0,
|
||||
FALSE, 0, 0, szDefaultPath, &si, &pi))
|
||||
*/
|
||||
char szExecutePath[MAX_PATH * 2];
|
||||
_snprintf(szExecutePath, MAX_PATH * 2 - 1, "\"%s\" %s",
|
||||
runExInfo.m_RunInfo.m_szPath, runExInfo.m_RunInfo.m_szOption);
|
||||
|
||||
szExecutePath[MAX_PATH * 2 - 1] = 0;
|
||||
|
||||
if(CreateProcess(0, szExecutePath, 0, 0,
|
||||
FALSE, 0, 0, szDefaultPath, &si, &pi))
|
||||
|
||||
{
|
||||
runExInfo.m_hProcess = pi.hProcess;
|
||||
runExInfo.m_dwProcessID = pi.dwProcessId;
|
||||
|
||||
DETLOG4(g_Log, "Execute file success, RunID(%u), Path(%s), Option(%s), DefaultPath(%s)",
|
||||
runExInfo.m_RunInfo.m_dwRunID, runExInfo.m_RunInfo.m_szPath,
|
||||
runExInfo.m_RunInfo.m_szOption, szDefaultPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG5(g_Log, "Cannot execute file : CreateProcess failed(%d), RunID(%u), "
|
||||
"Path(%s), Option(%s), DefaultPath(%s)",
|
||||
WSAGetLastError(), runExInfo.m_RunInfo.m_dwRunID,
|
||||
runExInfo.m_RunInfo.m_szPath, runExInfo.m_RunInfo.m_szOption, szDefaultPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG1(g_Log, "Cannot execute file : Unknown RunID(%d)", dwRunID);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CManageClientDispatch::ProcessQuitServer(unsigned long dwRunID)
|
||||
{
|
||||
RunTable::iterator pos = m_RunTable.find(dwRunID);
|
||||
|
||||
if(pos != m_RunTable.end())
|
||||
{
|
||||
RunExtraInfo& runExInfo = pos->second;
|
||||
|
||||
if(0 != runExInfo.m_hWnd)
|
||||
{
|
||||
TCHAR szWindowName[MAX_PATH];
|
||||
GetWindowText(runExInfo.m_hWnd, szWindowName, MAX_PATH - 1);
|
||||
szWindowName[MAX_PATH - 1] = 0;
|
||||
|
||||
SendMessage(runExInfo.m_hWnd, WM_DESTROY, 0, 0);
|
||||
|
||||
DETLOG6(g_Log, "Send quit message : HANDLE(0x%p), PID(0x%08x), WindowName(%s), "
|
||||
"RunID(%u), Path(%s), Option(%s)",
|
||||
runExInfo.m_hProcess, runExInfo.m_dwProcessID, szWindowName,
|
||||
runExInfo.m_RunInfo.m_dwRunID, runExInfo.m_RunInfo.m_szPath,
|
||||
runExInfo.m_RunInfo.m_szOption);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG5(g_Log, "Cannot send quit message (Get window failed) : "
|
||||
"HANDLE(0x%p), PID(0x%08x), RunID(%u), Path(%s), Option(%s)",
|
||||
runExInfo.m_hProcess, runExInfo.m_dwProcessID,
|
||||
runExInfo.m_RunInfo.m_dwRunID, runExInfo.m_RunInfo.m_szPath,
|
||||
runExInfo.m_RunInfo.m_szOption);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CManageClientDispatch::ProcessTerminateServer(unsigned long dwRunID)
|
||||
{
|
||||
RunTable::iterator pos = m_RunTable.find(dwRunID);
|
||||
|
||||
if(pos != m_RunTable.end())
|
||||
{
|
||||
RunExtraInfo& runExInfo = pos->second;
|
||||
|
||||
if(0 != runExInfo.m_hProcess)
|
||||
{
|
||||
if(TerminateProcess(runExInfo.m_hProcess, -1))
|
||||
{
|
||||
DETLOG5(g_Log, "Terminate process. HANDLE(0x%p), PID(0x%08x), "
|
||||
"RunID(%u), Path(%s), Option(%s)",
|
||||
runExInfo.m_hProcess, runExInfo.m_dwProcessID,
|
||||
runExInfo.m_RunInfo.m_dwRunID, runExInfo.m_RunInfo.m_szPath,
|
||||
runExInfo.m_RunInfo.m_szOption);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG6(g_Log, "Cannot terminate process. Err(%d), HANDLE(0x%p), PID(0x%08x), "
|
||||
"RunID(%u), Path(%s), Option(%s)",
|
||||
GetLastError(), runExInfo.m_hProcess, runExInfo.m_dwProcessID,
|
||||
runExInfo.m_RunInfo.m_dwRunID, runExInfo.m_RunInfo.m_szPath,
|
||||
runExInfo.m_RunInfo.m_szOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CManageClientDispatch::ProcessExecuteConsoleCommand(ServerManage::ManageCommand* lpManageCmd)
|
||||
{
|
||||
RunTable::iterator pos = m_RunTable.find(lpManageCmd->dwRunID);
|
||||
|
||||
if(pos != m_RunTable.end())
|
||||
{
|
||||
RunExtraInfo& runExInfo = pos->second;
|
||||
|
||||
if(0 != runExInfo.m_hWnd)
|
||||
{
|
||||
COPYDATASTRUCT copyDataStruct;
|
||||
|
||||
copyDataStruct.dwData = 0;
|
||||
copyDataStruct.cbData = lpManageCmd->GetLen();
|
||||
copyDataStruct.lpData = lpManageCmd;
|
||||
|
||||
SendMessage(runExInfo.m_hWnd, WM_COPYDATA, 0, (LPARAM)©DataStruct);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CManageClientDispatch::CheckProcessStatus()
|
||||
{
|
||||
const int MAX_PROCESS_STATUS_SEND_ONCE =
|
||||
(PktMaxLen - sizeof(ServerManage::ManageCommand)) / sizeof(ServerManage::ProcessStatus);
|
||||
|
||||
ServerManage::ProcessStatus procesStatus[MAX_PROCESS_STATUS_SEND_ONCE];
|
||||
|
||||
RunTable::iterator pos = m_RunTable.begin();
|
||||
RunTable::iterator end = m_RunTable.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
RunExtraInfo& runExtraInfo = pos->second;
|
||||
|
||||
// 체크하고, PID가 있는데 프로세스가 열리지 않은 프로그램은, 프로세스를 연다.
|
||||
if(0 != runExtraInfo.m_dwProcessID && 0 != runExtraInfo.m_hWnd
|
||||
&& 0 == runExtraInfo.m_hProcess)
|
||||
{
|
||||
runExtraInfo.m_hProcess = OpenProcess(PROCESS_ALL_ACCESS,
|
||||
FALSE, runExtraInfo.m_dwProcessID);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long dwExitCode = 0;
|
||||
unsigned long dwErrorCode = 0;
|
||||
unsigned short usSendProcessStatus = 0;
|
||||
|
||||
pos = m_RunTable.begin();
|
||||
end = m_RunTable.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
RunExtraInfo& runExtraInfo = pos->second;
|
||||
|
||||
// Default - Deactivated Process.
|
||||
ServerManage::ProcessStatus* lpCurrentProcessStatus = procesStatus + usSendProcessStatus;
|
||||
memset(lpCurrentProcessStatus, 0, sizeof(ServerManage::ProcessStatus));
|
||||
|
||||
lpCurrentProcessStatus->m_dwRunID = runExtraInfo.m_RunInfo.m_dwRunID;
|
||||
lpCurrentProcessStatus->m_dwStatusFlags = 0;
|
||||
lpCurrentProcessStatus->m_dwCurrentTime = timeGetTime();
|
||||
lpCurrentProcessStatus->m_dwCustomStatus = runExtraInfo.m_dwCustomStatus;
|
||||
lpCurrentProcessStatus->m_dwLastSetWindowHandleTime = runExtraInfo.m_dwLastSetWindowHandleTime;
|
||||
|
||||
if(0 != runExtraInfo.m_hProcess)
|
||||
{
|
||||
GetProcessTimes(runExtraInfo.m_hProcess,
|
||||
&lpCurrentProcessStatus->m_CreationTIme,
|
||||
&lpCurrentProcessStatus->m_ExitTime,
|
||||
&lpCurrentProcessStatus->m_KernelTime,
|
||||
&lpCurrentProcessStatus->m_UserTime);
|
||||
|
||||
GetProcessMemoryInfo(runExtraInfo.m_hProcess,
|
||||
&lpCurrentProcessStatus->m_ProcessMemoryCounters,
|
||||
sizeof(PROCESS_MEMORY_COUNTERS));
|
||||
|
||||
if(!GetExitCodeProcess(runExtraInfo.m_hProcess, &dwExitCode))
|
||||
{
|
||||
ERRLOG3(g_Log, "GetExitCodeProcess failed(%d) : RunID(%u), Path(%s)",
|
||||
dwErrorCode, runExtraInfo.m_RunInfo.m_dwRunID,
|
||||
runExtraInfo.m_RunInfo.m_szPath);
|
||||
}
|
||||
else if(dwExitCode != STILL_ACTIVE)
|
||||
{
|
||||
DETLOG4(g_Log, "Close process handle : HANDLE(0x%p), PID(0x%08x), RunID(%u), Path(%s)",
|
||||
runExtraInfo.m_hProcess, runExtraInfo.m_dwProcessID,
|
||||
runExtraInfo.m_RunInfo.m_dwRunID, runExtraInfo.m_RunInfo.m_szPath);
|
||||
|
||||
CloseHandle(runExtraInfo.m_hProcess);
|
||||
runExtraInfo.m_hProcess = 0;
|
||||
runExtraInfo.m_dwProcessID = 0;
|
||||
runExtraInfo.m_hWnd = 0;
|
||||
runExtraInfo.m_dwLastSetWindowHandleTime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpCurrentProcessStatus->m_dwStatusFlags =
|
||||
ServerManage::PROCESS_RUNNING;
|
||||
}
|
||||
}
|
||||
|
||||
++usSendProcessStatus;
|
||||
|
||||
if(usSendProcessStatus == MAX_PROCESS_STATUS_SEND_ONCE)
|
||||
{
|
||||
ServerManage::SendManagePacket(GetSession(), ServerManage::CMD::ProcessStatus,
|
||||
0, 0, 0, 0, sizeof(ServerManage::ProcessStatus) * usSendProcessStatus, 0, procesStatus, 0);
|
||||
|
||||
usSendProcessStatus = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 < usSendProcessStatus)
|
||||
{
|
||||
ServerManage::SendManagePacket(GetSession(), ServerManage::CMD::ProcessStatus,
|
||||
0, 0, 0, 0, sizeof(ServerManage::ProcessStatus) * usSendProcessStatus, 0, procesStatus, 0);
|
||||
|
||||
usSendProcessStatus = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CManageClientDispatch::SetAppData(unsigned long dwRunID, HWND hWnd,
|
||||
unsigned long dwPID, unsigned long dwCustomStatus)
|
||||
{
|
||||
RunTable::iterator pos = m_RunTable.find(dwRunID);
|
||||
RunTable::iterator end = m_RunTable.end();
|
||||
|
||||
if(pos != end)
|
||||
{
|
||||
RunExtraInfo& runExtraInfo = pos->second;
|
||||
|
||||
runExtraInfo.m_dwProcessID = dwPID;
|
||||
runExtraInfo.m_hWnd = hWnd;
|
||||
runExtraInfo.m_dwCustomStatus = dwCustomStatus;
|
||||
runExtraInfo.m_dwLastSetWindowHandleTime = timeGetTime();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CManageClientDispatch::GetRunIDFromString(const char* szAppName, const char* szCommandLine,
|
||||
unsigned long& dwRunID_Out)
|
||||
{
|
||||
char szProcessName[MAX_PATH];
|
||||
char szProcessSnapName[MAX_PATH];
|
||||
|
||||
_snprintf(szProcessSnapName, MAX_PATH - 1, "%s", szAppName);
|
||||
szProcessSnapName[MAX_PATH - 1] = 0;
|
||||
_strupr(szProcessSnapName);
|
||||
|
||||
char szCommandLineData[MAX_PATH * 2];
|
||||
_snprintf(szCommandLineData, MAX_PATH * 2 - 1, "%s", szCommandLine);
|
||||
szCommandLineData[MAX_PATH * 2 - 1] = 0;
|
||||
|
||||
RunExtraInfo::CommandSet commandSet;
|
||||
|
||||
char* szData = 0;
|
||||
|
||||
if('\"' == szCommandLineData[0])
|
||||
{
|
||||
szData = strtok(szCommandLineData, "\"");
|
||||
szData = strtok(0, "\"");
|
||||
|
||||
if(0 != szData)
|
||||
{
|
||||
// 파일명을 분리한 Argument를 받아서 처리..
|
||||
char szRealCommandLine[MAX_PATH];
|
||||
_snprintf(szRealCommandLine, MAX_PATH - 1, "%s", szData);
|
||||
szRealCommandLine[MAX_PATH - 1] = 0;
|
||||
|
||||
szData = strtok(szRealCommandLine, " \t\r\n");
|
||||
while(0 != szData)
|
||||
{
|
||||
commandSet.insert(szData);
|
||||
szData = strtok(0, " \t\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
szData = strtok(szCommandLineData, " \t\r\n");
|
||||
|
||||
// 첫번째 Argument는 파일명이므로 무시.
|
||||
szData = strtok(0, " \t\r\n");
|
||||
while(0 != szData)
|
||||
{
|
||||
commandSet.insert(szData);
|
||||
szData = strtok(0, " \t\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
RunTable::iterator pos = m_RunTable.begin();
|
||||
RunTable::iterator end = m_RunTable.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
RunExtraInfo& runExtraInfo = pos->second;
|
||||
|
||||
_snprintf(szProcessName, MAX_PATH - 1, "%s", runExtraInfo.m_RunInfo.m_szPath);
|
||||
szProcessName[MAX_PATH - 1] = 0;
|
||||
_strupr(szProcessName);
|
||||
|
||||
if(0 == strncmp(szProcessName, szProcessSnapName, MAX_PATH))
|
||||
{
|
||||
if((runExtraInfo.m_CommandSet.size() == commandSet.size()
|
||||
&& std::equal(runExtraInfo.m_CommandSet.begin(),
|
||||
runExtraInfo.m_CommandSet.end(), commandSet.begin())))
|
||||
{
|
||||
dwRunID_Out = runExtraInfo.m_RunInfo.m_dwRunID;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dwRunID_Out = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CManageClientDispatch::GetRunIDFromPID(unsigned long dwPID, unsigned long& dwRunID_Out)
|
||||
{
|
||||
RunTable::iterator pos = m_RunTable.begin();
|
||||
RunTable::iterator end = m_RunTable.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
RunExtraInfo& runExtraInfo = pos->second;
|
||||
|
||||
if(runExtraInfo.m_dwProcessID == dwPID)
|
||||
{
|
||||
dwRunID_Out = runExtraInfo.m_RunInfo.m_dwRunID;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
dwRunID_Out = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
HANDLE GetProcessHandle(const char* szProcessFullPathName, unsigned long* lpdwPID)
|
||||
{
|
||||
HANDLE hProcess = INVALID_HANDLE_VALUE;
|
||||
|
||||
if(0 == lpdwPID)
|
||||
{
|
||||
return hProcess;
|
||||
}
|
||||
|
||||
// Take a snapshot of all processes in the system.
|
||||
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
|
||||
if (hProcessSnap == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return hProcess;
|
||||
}
|
||||
|
||||
// Fill in the size of the structure before using it.
|
||||
PROCESSENTRY32 pe32 = {0};
|
||||
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||||
|
||||
// Walk the snapshot of the processes, and for each process,
|
||||
// display information.
|
||||
|
||||
char szProcessName[MAX_PATH];
|
||||
char szProcessSnapName[MAX_PATH];
|
||||
|
||||
_snprintf(szProcessName, MAX_PATH - 1, "%s", szProcessFullPathName);
|
||||
szProcessName[MAX_PATH - 1] = 0;
|
||||
|
||||
_strupr(szProcessName);
|
||||
|
||||
bool bFound = false;
|
||||
|
||||
if (Process32First(hProcessSnap, &pe32))
|
||||
{
|
||||
do
|
||||
{
|
||||
MODULEENTRY32 me32 = {0};
|
||||
|
||||
HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe32.th32ProcessID);
|
||||
if (hModuleSnap != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
me32.dwSize = sizeof(MODULEENTRY32);
|
||||
|
||||
if (Module32First(hModuleSnap, &me32))
|
||||
{
|
||||
do
|
||||
{
|
||||
_snprintf(szProcessSnapName, MAX_PATH - 1, "%s", me32.szExePath);
|
||||
szProcessSnapName[MAX_PATH - 1] = 0;
|
||||
|
||||
_strupr(szProcessSnapName);
|
||||
|
||||
if(0 == strcmp(szProcessName, szProcessSnapName))
|
||||
{
|
||||
// Get the actual priority class.
|
||||
hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
|
||||
if(INVALID_HANDLE_VALUE == hProcess)
|
||||
{
|
||||
ERRLOG2(g_Log, "Process open failed(%d) : %s",
|
||||
GetLastError(), me32.szExePath);
|
||||
}
|
||||
|
||||
*lpdwPID = pe32.th32ProcessID;
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (!bFound && Module32Next(hModuleSnap, &me32));
|
||||
}
|
||||
|
||||
CloseHandle (hModuleSnap);
|
||||
}
|
||||
}
|
||||
|
||||
while (!bFound && Process32Next(hProcessSnap, &pe32));
|
||||
}
|
||||
|
||||
CloseHandle(hProcessSnap);
|
||||
return hProcess;
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,90 @@
|
||||
#ifndef _GM_MANAGE_CLIENT_DISPATCH_H_
|
||||
#define _GM_MANAGE_CLIENT_DISPATCH_H_
|
||||
|
||||
#pragma warning(disable:4800)
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
#include <Network/Dispatch/RylServerDispatch.h>
|
||||
#include <Network/Dispatch/SingleDispatchStorage.h>
|
||||
#include <Network/Packet/ManagePacketCmd.h>
|
||||
|
||||
// CManageClientDispatch를 쓰는 클라이언트만 이 라이브러리를 링크함.
|
||||
#pragma comment(lib, "psapi.lib")
|
||||
|
||||
class CManageClientDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
struct RunExtraInfo
|
||||
{
|
||||
typedef std::set<std::string> CommandSet;
|
||||
|
||||
ServerManage::RunInfo m_RunInfo;
|
||||
HANDLE m_hProcess;
|
||||
HWND m_hWnd;
|
||||
unsigned long m_dwProcessID;
|
||||
unsigned long m_dwCustomStatus;
|
||||
unsigned long m_dwLastSetWindowHandleTime;
|
||||
|
||||
CommandSet m_CommandSet;
|
||||
|
||||
RunExtraInfo();
|
||||
RunExtraInfo(const ServerManage::RunInfo& runInfo,
|
||||
HANDLE hProcess, unsigned long dwProcessID);
|
||||
};
|
||||
|
||||
// Key - RunID
|
||||
typedef std::map<unsigned long, RunExtraInfo, std::less<unsigned long>,
|
||||
boost::pool_allocator<std::pair<unsigned long, RunExtraInfo> > > RunTable;
|
||||
|
||||
static CSingleDispatch& GetDispatchTable();
|
||||
|
||||
CManageClientDispatch(CSession& Session);
|
||||
virtual ~CManageClientDispatch();
|
||||
|
||||
void CheckProcessStatus();
|
||||
|
||||
bool DoPatchNow() const { return m_bDoPatchNow; }
|
||||
const TCHAR* GetTempPatchFileName() const { return m_szTempPatchFileName; }
|
||||
|
||||
bool SetAppData(unsigned long dwRunID, HWND hWnd,
|
||||
unsigned long dwPID, unsigned long dwCustomStatus);
|
||||
|
||||
bool GetRunIDFromPID(unsigned long dwPID, unsigned long& dwRunID_Out);
|
||||
|
||||
bool GetRunIDFromString(const char* szAppName,
|
||||
const char* szCommandLine, unsigned long& dwRunID_Out);
|
||||
|
||||
RunTable& GetRunTable() { return m_RunTable; }
|
||||
|
||||
private:
|
||||
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase);
|
||||
|
||||
bool ProcessUpdateRunList(const char* szData, unsigned short usDataLen, unsigned short usFlags);
|
||||
bool ProcessRunServer(unsigned long dwRunID);
|
||||
bool ProcessQuitServer(unsigned long dwRunID);
|
||||
bool ProcessTerminateServer(unsigned long dwRunID);
|
||||
bool ProcessExecuteConsoleCommand(ServerManage::ManageCommand* lpManageCmd);
|
||||
|
||||
bool ProcessRelayCommand(unsigned int nMessage, WPARAM wParam, LPARAM lParam,
|
||||
const char* szWindowName, const char* lpData, unsigned short usDataLen, unsigned char cFlag);
|
||||
|
||||
bool ProcessAutoPatch(const char* lpData, unsigned short usDataLen, unsigned short usFlag);
|
||||
|
||||
// Member variable;
|
||||
HANDLE m_hPatchFile; // 패치 파일 핸들.
|
||||
TCHAR m_szTempPatchFileName[MAX_PATH]; // 임시 패치 파일 이름.
|
||||
bool m_bDoPatchNow; // 패치 준비가 되었는지 여부를 알아옴.
|
||||
|
||||
|
||||
RunTable m_RunTable;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,231 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "ManageServerDispatch.h"
|
||||
#include "ManageToolServerDispatch.h"
|
||||
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Packet/ManagePacketCmd.h>
|
||||
#include <Network/Dispatch/SendManagePacket.h>
|
||||
#include <Network/Dispatch/MultiDispatchStorage.h>
|
||||
#include <UserManage/ToolUserManageTable.h>
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Setup/SetupClient.h>
|
||||
|
||||
#include <ServerManage/ManageClientManager.h>
|
||||
#include <UserManage/UserStatistics.h>
|
||||
|
||||
enum ManageServerConst
|
||||
{
|
||||
MANAGE_SERVER_DEFAULT_DISPATCH_NUM = 100
|
||||
};
|
||||
|
||||
CMultiDispatch& CManageServerDispatch::GetDispatchTable()
|
||||
{
|
||||
static CMultiDispatch multiDispatch;
|
||||
return multiDispatch;
|
||||
}
|
||||
|
||||
|
||||
CManageServerDispatch::CManageServerDispatch(CSession& Session)
|
||||
: CRylServerDispatch(Session, MANAGE_SERVER_DEFAULT_DISPATCH_NUM),
|
||||
m_bAuthorized(false)
|
||||
{
|
||||
memset(&m_UserInfo, 0, sizeof(ServerManage::UserInfo));
|
||||
|
||||
DETLOG1(g_Log, "this:0x%p/CManageServerDispatch Created", this);
|
||||
}
|
||||
|
||||
|
||||
CManageServerDispatch::~CManageServerDispatch()
|
||||
{
|
||||
DETLOG1(g_Log, "this:0x%p/CManageServerDispatch Destroyed", this);
|
||||
}
|
||||
|
||||
|
||||
void CManageServerDispatch::Connected()
|
||||
{
|
||||
// 접속 IP를 key로 잡아서 세팅한다.
|
||||
INET_Addr& remoteAddr = GetSession().GetRemoteAddr();
|
||||
|
||||
unsigned long dwDispatchID = remoteAddr.get_addr_in().sin_addr.S_un.S_addr;
|
||||
GetDispatchTable().SetDispatch(dwDispatchID, this);
|
||||
|
||||
// TODO : 서버 IP로 검색해서, RunInfo들을 전송한다.
|
||||
|
||||
CManageClientManager::RunTable runInfoTable;
|
||||
CManageClientManager::GetInstance().GetRunInfoFromIP(dwDispatchID, runInfoTable);
|
||||
|
||||
if(!CManageClientManager::SendRunInfo(GetSession(), runInfoTable))
|
||||
{
|
||||
ERRLOG3(g_Log, "SS:0x%p/DP:0x%p/IP:%15s/Send runInfo failed",
|
||||
&GetSession(), this, remoteAddr.get_addr_string());
|
||||
}
|
||||
|
||||
DETLOG2(g_Log, "this:0x%p/Key:%u/CManageServerDispatch Connected", this, dwDispatchID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CSendProcessData
|
||||
{
|
||||
public:
|
||||
|
||||
CSendProcessData(ServerManage::ProcessStatus* lpProcessData,
|
||||
unsigned short usProcessDataNum)
|
||||
: m_lpProcessData(lpProcessData), m_usProcessDataNum(usProcessDataNum)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool operator () (CManageToolServerDispatch& toolDispatch)
|
||||
{
|
||||
ServerManage::SendManagePacket(toolDispatch.GetSession(), ServerManage::CMD::ProcessStatus,
|
||||
0, 0, 0, 0, sizeof(ServerManage::ProcessStatus) * m_usProcessDataNum, 0, m_lpProcessData, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
ServerManage::ProcessStatus* m_lpProcessData;
|
||||
unsigned short m_usProcessDataNum;
|
||||
};
|
||||
|
||||
void CManageServerDispatch::Disconnected()
|
||||
{
|
||||
// 접속 IP를 key로 잡아서 세팅한다.
|
||||
INET_Addr& remoteAddr = GetSession().GetRemoteAddr();
|
||||
|
||||
unsigned long dwDispatchID = remoteAddr.get_addr_in().sin_addr.S_un.S_addr;
|
||||
GetDispatchTable().RemoveDispatch(dwDispatchID);
|
||||
|
||||
CManageClientManager::RunTable runInfoTable;
|
||||
CManageClientManager::GetInstance().GetRunInfoFromIP(dwDispatchID, runInfoTable);
|
||||
|
||||
CManageClientManager::RunTable::iterator pos = runInfoTable.begin();
|
||||
CManageClientManager::RunTable::iterator end = runInfoTable.end();
|
||||
|
||||
const int MAX_PROCESS_STATUS_SEND_ONCE =
|
||||
(PktMaxLen - sizeof(ServerManage::ManageCommand)) / sizeof(ServerManage::ProcessStatus);
|
||||
|
||||
ServerManage::ProcessStatus procesStatus[MAX_PROCESS_STATUS_SEND_ONCE];
|
||||
|
||||
unsigned short usSendProcessStatus = 0;
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
ServerManage::RunInfo& runInfo = pos->second;
|
||||
|
||||
// Default - Deactivated Process.
|
||||
ServerManage::ProcessStatus* lpCurrentProcessStatus = procesStatus + usSendProcessStatus;
|
||||
memset(lpCurrentProcessStatus, 0, sizeof(ServerManage::ProcessStatus));
|
||||
|
||||
lpCurrentProcessStatus->m_dwRunID = runInfo.m_dwRunID;
|
||||
++usSendProcessStatus;
|
||||
|
||||
if(usSendProcessStatus == MAX_PROCESS_STATUS_SEND_ONCE)
|
||||
{
|
||||
CToolUserManager::GetInstance().ProcessCurrentUser(
|
||||
CSendProcessData(procesStatus, usSendProcessStatus));
|
||||
|
||||
usSendProcessStatus = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 < usSendProcessStatus)
|
||||
{
|
||||
CToolUserManager::GetInstance().ProcessCurrentUser(
|
||||
CSendProcessData(procesStatus, usSendProcessStatus));
|
||||
|
||||
usSendProcessStatus = 0;
|
||||
}
|
||||
|
||||
DETLOG2(g_Log, "this:0x%p/Key:%u/CManageServerDispatch Disconnected", this, dwDispatchID);
|
||||
}
|
||||
|
||||
|
||||
bool CManageServerDispatch::DispatchPacket(PktBase* lpPktBase)
|
||||
{
|
||||
PktBase::LengthType nPacketLen = lpPktBase->GetLen();
|
||||
|
||||
bool bResult = false;
|
||||
|
||||
switch(lpPktBase->GetCmd())
|
||||
{
|
||||
case ServerManage::CMD::ProcessStatus:
|
||||
CUserStatistics::GetInstance().CheckClearUser(lpPktBase);
|
||||
RelayPacketToManageTools(lpPktBase);
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::RelayCommand:
|
||||
RelayPacketToManageTools(lpPktBase);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
{
|
||||
in_addr addr;
|
||||
addr.S_un.S_addr = m_UserInfo.dwIP;
|
||||
|
||||
ERRLOG4(g_Log, "ID:%s/Name:%s/IP:%s/Cmd:0x%02x/Undefined command.",
|
||||
m_UserInfo.szID, m_UserInfo.szFullName, inet_ntoa(addr),
|
||||
lpPktBase->GetCmd());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CManageServerDispatch::RelayPacketToManageTools(PktBase* lpPktBase)
|
||||
{
|
||||
unsigned char cError = 0;
|
||||
bool bDoNotRelay = false;
|
||||
|
||||
ServerManage::ManageCommand* lpManageCommand =
|
||||
reinterpret_cast<ServerManage::ManageCommand*>(lpPktBase);
|
||||
|
||||
if(!ServerManage::CheckManagePacketLength(lpPktBase))
|
||||
{
|
||||
cError = ServerManage::INVALID_MANAGE_PACKET_ERROR;
|
||||
}
|
||||
|
||||
if(sizeof(ServerManage::PktManagePacket) <= lpManageCommand->usDataLen)
|
||||
{
|
||||
ServerManage::PktManagePacket* lpPktManagePacket =
|
||||
reinterpret_cast<ServerManage::PktManagePacket*>(lpManageCommand + 1);
|
||||
|
||||
switch(lpPktManagePacket->m_dwSubCommand)
|
||||
{
|
||||
case ServerManage::CMD::SubCmd_ServerUserNum:
|
||||
{
|
||||
ServerManage::PktManageUserNum* lpPktManageUserNum =
|
||||
static_cast<ServerManage::PktManageUserNum*>(lpPktManagePacket);
|
||||
|
||||
/*
|
||||
DETLOG2(g_Log, "RunID:%d/PID:%d/Setting UserInfo",
|
||||
lpManageCommand->dwRunID, lpPktManageUserNum->m_dwPID);
|
||||
*/
|
||||
|
||||
CUserStatistics::GetInstance().SerializeIn(lpManageCommand->dwRunID,
|
||||
reinterpret_cast<ServerManage::UserNumPair*>(lpPktManageUserNum + 1),
|
||||
lpPktManageUserNum->m_dwUserInfoNum);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 == cError && !bDoNotRelay)
|
||||
{
|
||||
CToolUserManager::GetInstance().ProcessCurrentUser(
|
||||
ServerManage::CSendManagePacketToClient(*lpManageCommand,
|
||||
reinterpret_cast<char*>(lpManageCommand + 1)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return ServerManage::SendManagePacket(GetSession(),
|
||||
lpPktBase->GetCmd(), 0, 0, 0, 0, 0, 0, 0, cError);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef _GM_MANAGE_SERVER_DISPATCH_H_
|
||||
#define _GM_MANAGE_SERVER_DISPATCH_H_
|
||||
|
||||
#include <Network/Packet/ManagePacketCmd.h>
|
||||
#include <Network/Dispatch/RylServerDispatch.h>
|
||||
#include <Network/Dispatch/MultiDispatchStorage.h>
|
||||
|
||||
class CManageServerDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
static CMultiDispatch& GetDispatchTable();
|
||||
|
||||
CManageServerDispatch(CSession& Session);
|
||||
virtual ~CManageServerDispatch();
|
||||
|
||||
private:
|
||||
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase);
|
||||
|
||||
bool RelayPacketToManageTools(PktBase* lpPktBase);
|
||||
|
||||
ServerManage::UserInfo m_UserInfo;
|
||||
bool m_bAuthorized;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,320 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "ManageServerDispatch.h"
|
||||
#include "ManageToolServerDispatch.h"
|
||||
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Dispatch/SendManagePacket.h>
|
||||
#include <Network/Dispatch/MultiDispatchStorage.h>
|
||||
|
||||
#include <Network/Packet/ManagePacketCmd.h>
|
||||
#include <UserManage/ToolUserManageTable.h>
|
||||
#include <ServerManage/ManageClientManager.h>
|
||||
|
||||
#include <Setup/SetupClient.h>
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Network/Packet/WrapPacket.h>
|
||||
|
||||
#include <mmsystem.h>
|
||||
|
||||
enum ManageToolServerConst
|
||||
{
|
||||
MANAGE_TOOL_SERVER_DEFAULT_DISPATCH_NUM = 10
|
||||
};
|
||||
|
||||
|
||||
CManageToolServerDispatch::CManageToolServerDispatch(CSession& Session)
|
||||
: CRylServerDispatch(Session, MANAGE_TOOL_SERVER_DEFAULT_DISPATCH_NUM),
|
||||
m_bAuthorized(false), m_dwLastPingRecvTime(timeGetTime())
|
||||
{
|
||||
memset(&m_UserInfo, 0, sizeof(ServerManage::UserInfo));
|
||||
|
||||
DETLOG1(g_Log, "this:0x%p/CManageToolServerDispatch Created", this);
|
||||
}
|
||||
|
||||
|
||||
CManageToolServerDispatch::~CManageToolServerDispatch()
|
||||
{
|
||||
DETLOG1(g_Log, "this:0x%p/CManageToolServerDispatch Destroyed", this);
|
||||
}
|
||||
|
||||
void CManageToolServerDispatch::Connected()
|
||||
{
|
||||
// 인증 성공시 LoginTable에 삽입된다.
|
||||
DETLOG1(g_Log, "this:0x%p/CManageToolServerDispatch Connected", this);
|
||||
}
|
||||
|
||||
void CManageToolServerDispatch::Disconnected()
|
||||
{
|
||||
if(0 != m_UserInfo.szID[0])
|
||||
{
|
||||
CToolUserManager::GetInstance().Logout(m_UserInfo.szID);
|
||||
}
|
||||
|
||||
DETLOG1(g_Log, "this:0x%p/CManageToolServerDispatch Disconnected", this);
|
||||
}
|
||||
|
||||
|
||||
bool CManageToolServerDispatch::Dispatch()
|
||||
{
|
||||
unsigned long dwCurrentTime = timeGetTime();
|
||||
|
||||
// 2분 동안 핑을 못받으면 접속을 끊는다.
|
||||
if (1000 * 60 * 2 < dwCurrentTime - m_dwLastPingRecvTime)
|
||||
{
|
||||
INFLOG4(g_Log, "Disconnect by ping %s:%d / %u / %u ",
|
||||
GetRemoteAddr().get_addr_string(), GetRemoteAddr().get_port_in(),
|
||||
dwCurrentTime, m_dwLastPingRecvTime);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return CRylServerDispatch::Dispatch();
|
||||
}
|
||||
|
||||
bool CManageToolServerDispatch::DispatchPacket(PktBase* lpPktBase)
|
||||
{
|
||||
PktBase::LengthType nPacketLen = lpPktBase->GetLen();
|
||||
|
||||
bool bResult = true;
|
||||
const TCHAR* szErrorString = 0;
|
||||
|
||||
bool bSendInvalidUserPacketAck = false;
|
||||
bool bSendInvalidManagePacketAck = false;
|
||||
|
||||
if (ServerManage::CMD::Ping == lpPktBase->GetCmd())
|
||||
{
|
||||
m_dwLastPingRecvTime = timeGetTime();
|
||||
|
||||
PktBase pktBase;
|
||||
memset(&pktBase, 0, sizeof(PktBase));
|
||||
pktBase.SetServerInfo(m_dwLastPingRecvTime);
|
||||
|
||||
if (PacketWrap::WrapHeader(reinterpret_cast<char*>(&pktBase),
|
||||
sizeof(PktBase), ServerManage::CMD::Ping, pktBase.GetState(), pktBase.GetError()))
|
||||
{
|
||||
GetSendStream().PutBuffer(reinterpret_cast<char*>(&pktBase),
|
||||
sizeof(PktBase), ServerManage::CMD::Ping);
|
||||
}
|
||||
}
|
||||
else if(ServerManage::CMD::AuthUser == lpPktBase->GetCmd())
|
||||
{
|
||||
if(!AuthUser(lpPktBase))
|
||||
{
|
||||
szErrorString = "Authorize failed.";
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bAuthorized = true;
|
||||
|
||||
// 인증이 성공하면 RunInfo를 전송한다.
|
||||
if(!CManageClientManager::SendRunInfo(GetSession(),
|
||||
CManageClientManager::GetInstance().GetRunInfoTable()))
|
||||
{
|
||||
ERRLOG3(g_Log, "SS:0x%p/DP:0x%p/IP:%15s/Send runInfo failed",
|
||||
&GetSession(), this, GetSession().GetRemoteAddr().get_addr_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(m_bAuthorized)
|
||||
{
|
||||
switch(lpPktBase->GetCmd())
|
||||
{
|
||||
// 다음 커맨드들은, RunID가 속한 서버로 메시지를 Relay한다.
|
||||
// Relay하지 못한 경우는 실패를 돌려준다.
|
||||
case ServerManage::CMD::RunProcess:
|
||||
case ServerManage::CMD::QuitProcess:
|
||||
case ServerManage::CMD::ForceTerminate:
|
||||
case ServerManage::CMD::ProcessStatus:
|
||||
|
||||
case ServerManage::CMD::RelayCommand:
|
||||
case ServerManage::CMD::AutoPatch:
|
||||
case ServerManage::CMD::ChangeSetup:
|
||||
case ServerManage::CMD::ReloadSetup:
|
||||
|
||||
case ServerManage::CMD::ExecuteCommand:
|
||||
|
||||
if(CToolUserManager::GetInstance().IsManageUser(m_UserInfo) &&
|
||||
(m_UserInfo.usAdminLevel == CToolUserManager::MASTER
|
||||
|| m_UserInfo.usAdminLevel == CToolUserManager::GENERAL))
|
||||
|
||||
{
|
||||
bResult = RelayPacketToManageClient(lpPktBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
bSendInvalidManagePacketAck = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::AddUser:
|
||||
if(CToolUserManager::GetInstance().IsManageUser(m_UserInfo) &&
|
||||
m_UserInfo.usAdminLevel == CToolUserManager::MASTER)
|
||||
{
|
||||
bResult = AddUser(lpPktBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
bSendInvalidUserPacketAck = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::DelUser:
|
||||
if(CToolUserManager::GetInstance().IsManageUser(m_UserInfo) &&
|
||||
m_UserInfo.usAdminLevel == CToolUserManager::MASTER)
|
||||
{
|
||||
bResult = DelUser(lpPktBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
bSendInvalidUserPacketAck = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::ModUser:
|
||||
if(CToolUserManager::GetInstance().IsManageUser(m_UserInfo) &&
|
||||
m_UserInfo.usAdminLevel == CToolUserManager::MASTER)
|
||||
{
|
||||
bResult = ModUser(lpPktBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
bSendInvalidUserPacketAck = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::RequestPromote:
|
||||
if(m_UserInfo.usAdminLevel == CToolUserManager::MASTER ||
|
||||
m_UserInfo.usAdminLevel == CToolUserManager::GENERAL)
|
||||
{
|
||||
bResult = RequestPromote(lpPktBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
bSendInvalidUserPacketAck = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::RequestUserReaction:
|
||||
if(m_UserInfo.usAdminLevel == CToolUserManager::MASTER ||
|
||||
m_UserInfo.usAdminLevel == CToolUserManager::GENERAL)
|
||||
{
|
||||
bResult = ProcessUserReaction(lpPktBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
bSendInvalidUserPacketAck = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::UserList:
|
||||
if(m_UserInfo.usAdminLevel == CToolUserManager::MASTER)
|
||||
{
|
||||
bResult = UserList(lpPktBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
bSendInvalidUserPacketAck = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
szErrorString = "Unknown packet. Cannot process.";
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
szErrorString = "Unauthorized user send command. Cannot process.";
|
||||
}
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
szErrorString = "Packet process failed.";
|
||||
}
|
||||
|
||||
if(bSendInvalidManagePacketAck)
|
||||
{
|
||||
ServerManage::SendManagePacket(GetSession(), lpPktBase->GetCmd(),
|
||||
0, 0, 0, 0, 0, 0, 0, ServerManage::INVALID_MANAGE_RIGHTS);
|
||||
}
|
||||
|
||||
if(bSendInvalidUserPacketAck)
|
||||
{
|
||||
ServerManage::SendUserInfo(GetBufferFactory(), &GetSession(), 0, 0,
|
||||
lpPktBase->GetCmd(), ServerManage::INVALID_USERMANAGE_RIGHTS);
|
||||
}
|
||||
|
||||
if(0 != szErrorString)
|
||||
{
|
||||
in_addr addr;
|
||||
addr.S_un.S_addr = m_UserInfo.dwIP;
|
||||
|
||||
ERRLOG5(g_Log, "ID:%s/Name:%s/IP:%s/Cmd:0x%02x/%s",
|
||||
m_UserInfo.szID, m_UserInfo.szFullName, inet_ntoa(addr),
|
||||
lpPktBase->GetCmd(), szErrorString);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CManageToolServerDispatch::RelayPacketToManageClient(PktBase* lpPktBase)
|
||||
{
|
||||
unsigned char cError = 0;
|
||||
|
||||
ServerManage::ManageCommand* lpManageCommand =
|
||||
reinterpret_cast<ServerManage::ManageCommand*>(lpPktBase);
|
||||
|
||||
if(!ServerManage::CheckManagePacketLength(lpPktBase))
|
||||
{
|
||||
cError = ServerManage::INVALID_MANAGE_PACKET_ERROR;
|
||||
}
|
||||
|
||||
if(CManageClientManager::MAX_RUNID == lpManageCommand->dwRunID)
|
||||
{
|
||||
CManageServerDispatch::GetDispatchTable().Process(
|
||||
ServerManage::CSendManagePacketToClient(*lpManageCommand,
|
||||
reinterpret_cast<char*>(lpManageCommand + 1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerManage::RunInfo runInfo;
|
||||
|
||||
if(CManageClientManager::GetInstance().GetRunInfo(
|
||||
lpManageCommand->dwRunID, runInfo))
|
||||
{
|
||||
GET_MULTI_DISPATCH(lpManageServerDispatch,
|
||||
runInfo.m_dwServerIP,
|
||||
CManageServerDispatch,
|
||||
CManageServerDispatch::GetDispatchTable());
|
||||
|
||||
if(0 != lpManageServerDispatch)
|
||||
{
|
||||
DETLOG4(g_Log, "ID:%s/FullName:%s/Send Relay Packet(Cmd:%d), RunID:%u",
|
||||
m_UserInfo.szID, m_UserInfo.szFullName,
|
||||
lpManageCommand->GetCmd(), lpManageCommand->dwRunID);
|
||||
|
||||
if(!ServerManage::SendManagePacket(lpManageServerDispatch->GetSession(),
|
||||
lpManageCommand->GetCmd(), lpManageCommand->nMessage,
|
||||
lpManageCommand->wParam, lpManageCommand->lParam,
|
||||
lpManageCommand->dwRunID, lpManageCommand->usDataLen, lpManageCommand->usFlags,
|
||||
reinterpret_cast<char*>(lpManageCommand + 1), 0))
|
||||
{
|
||||
cError = ServerManage::SEND_MANAGE_COMMAND_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cError = ServerManage::CANNOT_FIND_CLIENT_DISPATCH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cError = ServerManage::UNKNOWN_RUN_INFO;
|
||||
}
|
||||
}
|
||||
|
||||
return ServerManage::SendManagePacket(GetSession(),
|
||||
lpPktBase->GetCmd(), 0, 0, 0, 0, 0, 0, 0, cError);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef _GM_MANAGE_TOOL_SERVER_DISPATCH_H_
|
||||
#define _GM_MANAGE_TOOL_SERVER_DISPATCH_H_
|
||||
|
||||
#include <Network/Packet/ManagePacketCmd.h>
|
||||
#include <Network/Dispatch/RylServerDispatch.h>
|
||||
|
||||
// forward decl.
|
||||
class CToolUserManager;
|
||||
|
||||
class CManageToolServerDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
CManageToolServerDispatch(CSession& Session);
|
||||
virtual ~CManageToolServerDispatch();
|
||||
|
||||
const ServerManage::UserInfo& GetUserInfo() const { return m_UserInfo; }
|
||||
|
||||
private:
|
||||
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
|
||||
virtual bool Dispatch();
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase);
|
||||
|
||||
bool RelayPacketToManageClient(PktBase* lpPktBase);
|
||||
|
||||
bool AuthUser(PktBase* lpPktBase);
|
||||
bool AddUser(PktBase* lpPktBase);
|
||||
bool DelUser(PktBase* lpPktBase);
|
||||
bool ModUser(PktBase* lpPktBase);
|
||||
|
||||
bool RequestPromote(PktBase* lpPktBase);
|
||||
bool ProcessUserReaction(PktBase* lpPktBase);
|
||||
|
||||
bool UserList(PktBase* lpPktBase);
|
||||
|
||||
ServerManage::UserInfo m_UserInfo;
|
||||
unsigned long m_dwLastPingRecvTime;
|
||||
bool m_bAuthorized;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,308 @@
|
||||
#include "stdafx.h"
|
||||
#include "ManageToolServerDispatch.h"
|
||||
|
||||
#include <tchar.h>
|
||||
#include <Log/ServerLog.h>
|
||||
#include <UserManage/ToolUserManageTable.h>
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Dispatch/SendManagePacket.h>
|
||||
|
||||
|
||||
bool CManageToolServerDispatch::AuthUser(PktBase* lpPktBase)
|
||||
{
|
||||
unsigned char cError = 0;
|
||||
|
||||
ServerManage::UserCommand* lpUserCommand =
|
||||
reinterpret_cast<ServerManage::UserCommand*>(lpPktBase);
|
||||
|
||||
ServerManage::UserInfo* lpUserInfo =
|
||||
reinterpret_cast<ServerManage::UserInfo*>(lpUserCommand + 1);
|
||||
|
||||
if(!ServerManage::CheckUserPacketLength(lpPktBase, 1))
|
||||
{
|
||||
cError = ServerManage::INVALID_USER_PACKET_ERROR;
|
||||
}
|
||||
|
||||
if(0 == cError)
|
||||
{
|
||||
m_UserInfo = *lpUserInfo;
|
||||
m_UserInfo.dwIP = GetSession().GetRemoteAddr().get_addr_in().sin_addr.S_un.S_addr;
|
||||
|
||||
// 인증 성공시 LoginTable에 삽입된다.
|
||||
cError = CToolUserManager::GetInstance().Authorize(*this, m_UserInfo);
|
||||
if (cError != ServerManage::NO_USER_COMMAND_ERROR)
|
||||
{
|
||||
ERRLOG2(g_Log, "ID:%s/IP:%s/Authorize failed",
|
||||
m_UserInfo.szID, GetSession().GetRemoteAddr().get_addr_string());
|
||||
}
|
||||
}
|
||||
|
||||
if(0 == cError)
|
||||
{
|
||||
DETLOG2(g_Log, "ID:%s/IP:%s/Authorize success",
|
||||
m_UserInfo.szID, GetSession().GetRemoteAddr().get_addr_string());
|
||||
|
||||
// 다른 유저들에게 로그인 정보를 보낸다.
|
||||
ServerManage::SendUserInfo(GetBufferFactory(), 0, &m_UserInfo, 1,
|
||||
ServerManage::CMD::UserLogin, 0);
|
||||
|
||||
// 현재 관리자 정보를 준다.
|
||||
ServerManage::SendUserInfo(GetBufferFactory(), 0,
|
||||
&CToolUserManager::GetInstance().GetManageUser(), 1,
|
||||
ServerManage::CMD::ManagerInfo, 0);
|
||||
|
||||
// 다른 유저들의 로그인 정보를 받는다.
|
||||
CToolUserManager::GetInstance().SendAllLoginUserInfo(GetSession());
|
||||
|
||||
#pragma todo("서버 Setup을 준다")
|
||||
}
|
||||
|
||||
ServerManage::SendUserInfo(GetBufferFactory(), &GetSession(), &m_UserInfo, 1,
|
||||
ServerManage::CMD::AuthUser, cError);
|
||||
|
||||
return (0 == cError);
|
||||
}
|
||||
|
||||
|
||||
bool CManageToolServerDispatch::AddUser(PktBase* lpPktBase)
|
||||
{
|
||||
unsigned char cError = 0;
|
||||
|
||||
ServerManage::UserCommand* lpUserCommand =
|
||||
reinterpret_cast<ServerManage::UserCommand*>(lpPktBase);
|
||||
|
||||
ServerManage::UserInfo* lpUserInfo =
|
||||
reinterpret_cast<ServerManage::UserInfo*>(lpUserCommand + 1);
|
||||
|
||||
if(!ServerManage::CheckUserPacketLength(lpPktBase, 1))
|
||||
{
|
||||
cError = ServerManage::INVALID_USER_PACKET_ERROR;
|
||||
}
|
||||
|
||||
if(0 == cError && !CToolUserManager::GetInstance().AddUser(*lpUserInfo))
|
||||
{
|
||||
ERRLOG3(g_Log, "ID:%s/IP:%s/Adduser failed (ID:%s)",
|
||||
m_UserInfo.szID, GetSession().GetRemoteAddr().get_addr_string(), lpUserInfo->szID);
|
||||
cError = ServerManage::ADD_USER_FAILED;
|
||||
}
|
||||
|
||||
DETLOG3(g_Log, "ID:%s/IP:%s/Adduser success",
|
||||
m_UserInfo.szID, GetSession().GetRemoteAddr().get_addr_string(), lpUserInfo->szID);
|
||||
|
||||
memset(lpUserInfo->szPassword, 0, ServerManage::UserInfo::PASS_LEN);
|
||||
|
||||
return ServerManage::SendUserInfo(GetBufferFactory(), &GetSession(), lpUserInfo, 1,
|
||||
ServerManage::CMD::AddUser, cError);
|
||||
}
|
||||
|
||||
|
||||
bool CManageToolServerDispatch::DelUser(PktBase* lpPktBase)
|
||||
{
|
||||
unsigned char cError = 0;
|
||||
|
||||
ServerManage::UserCommand* lpUserCommand =
|
||||
reinterpret_cast<ServerManage::UserCommand*>(lpPktBase);
|
||||
|
||||
ServerManage::UserInfo* lpUserInfo =
|
||||
reinterpret_cast<ServerManage::UserInfo*>(lpUserCommand + 1);
|
||||
|
||||
if(!ServerManage::CheckUserPacketLength(lpPktBase, 1))
|
||||
{
|
||||
cError = ServerManage::INVALID_USER_PACKET_ERROR;
|
||||
}
|
||||
|
||||
if(0 == cError && !CToolUserManager::GetInstance().DelUser(lpUserInfo->szID))
|
||||
{
|
||||
ERRLOG3(g_Log, "ID:%s/IP:%s/Delete user failed (ID:%s)",
|
||||
m_UserInfo.szID, GetSession().GetRemoteAddr().get_addr_string(), lpUserInfo->szID);
|
||||
cError = ServerManage::DELETE_USER_FAILED;
|
||||
}
|
||||
|
||||
DETLOG3(g_Log, "ID:%s/IP:%s/Delete user success",
|
||||
m_UserInfo.szID, GetSession().GetRemoteAddr().get_addr_string(), lpUserInfo->szID);
|
||||
|
||||
return ServerManage::SendUserInfo(GetBufferFactory(), &GetSession(), lpUserInfo, 1,
|
||||
ServerManage::CMD::DelUser, cError);
|
||||
}
|
||||
|
||||
|
||||
bool CManageToolServerDispatch::ModUser(PktBase* lpPktBase)
|
||||
{
|
||||
unsigned char cError = 0;
|
||||
|
||||
ServerManage::UserCommand* lpUserCommand =
|
||||
reinterpret_cast<ServerManage::UserCommand*>(lpPktBase);
|
||||
|
||||
ServerManage::UserInfo* lpUserInfo =
|
||||
reinterpret_cast<ServerManage::UserInfo*>(lpUserCommand + 1);
|
||||
|
||||
if(!ServerManage::CheckUserPacketLength(lpPktBase, 1))
|
||||
{
|
||||
cError = ServerManage::INVALID_USER_PACKET_ERROR;
|
||||
}
|
||||
|
||||
if(0 == cError && !CToolUserManager::GetInstance().ModifyUser(*lpUserInfo))
|
||||
{
|
||||
ERRLOG3(g_Log, "ID:%s/IP:%s/Modify user failed (ID:%s)",
|
||||
m_UserInfo.szID, GetSession().GetRemoteAddr().get_addr_string(), lpUserInfo->szID);
|
||||
cError = ServerManage::MODIFY_USER_FAILED;
|
||||
}
|
||||
|
||||
DETLOG3(g_Log, "ID:%s/IP:%s/Modify user success",
|
||||
m_UserInfo.szID, GetSession().GetRemoteAddr().get_addr_string(), lpUserInfo->szID);
|
||||
|
||||
memset(lpUserInfo->szPassword, 0, ServerManage::UserInfo::PASS_LEN);
|
||||
|
||||
return ServerManage::SendUserInfo(GetBufferFactory(), &GetSession(), lpUserInfo, 1,
|
||||
ServerManage::CMD::ModUser, cError);
|
||||
}
|
||||
|
||||
bool CManageToolServerDispatch::UserList(PktBase* lpPktBase)
|
||||
{
|
||||
unsigned char cError = 0;
|
||||
|
||||
ServerManage::UserCommand* lpUserCommand =
|
||||
reinterpret_cast<ServerManage::UserCommand*>(lpPktBase);
|
||||
|
||||
if(!ServerManage::CheckUserPacketLength(lpPktBase, 0))
|
||||
{
|
||||
cError = ServerManage::INVALID_USER_PACKET_ERROR;
|
||||
}
|
||||
|
||||
if(0 == cError && !CToolUserManager::GetInstance().SendAllUserInfo(GetSession()))
|
||||
{
|
||||
ERRLOG2(g_Log, "ID:%s/IP:%s/Send userlist failed",
|
||||
m_UserInfo.szID, GetSession().GetRemoteAddr().get_addr_string());
|
||||
|
||||
cError = ServerManage::SEND_USER_LIST_FAILED;
|
||||
}
|
||||
|
||||
DETLOG2(g_Log, "ID:%s/IP:%s/Send userlist success",
|
||||
m_UserInfo.szID, GetSession().GetRemoteAddr().get_addr_string());
|
||||
|
||||
return ServerManage::SendUserInfo(GetBufferFactory(), &GetSession(), 0, 0,
|
||||
ServerManage::CMD::UserList, cError);
|
||||
}
|
||||
|
||||
|
||||
bool CManageToolServerDispatch::RequestPromote(PktBase* lpPktBase)
|
||||
{
|
||||
unsigned char cError = 0;
|
||||
|
||||
ServerManage::UserCommand* lpUserCommand =
|
||||
reinterpret_cast<ServerManage::UserCommand*>(lpPktBase);
|
||||
|
||||
ServerManage::UserInfo* lpUserInfo =
|
||||
reinterpret_cast<ServerManage::UserInfo*>(lpUserCommand + 1);
|
||||
|
||||
if(!ServerManage::CheckUserPacketLength(lpPktBase, 1))
|
||||
{
|
||||
cError = ServerManage::INVALID_USER_PACKET_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if(0 == cError)
|
||||
{
|
||||
const ServerManage::UserInfo& masterUser = CToolUserManager::GetInstance().GetManageUser();
|
||||
|
||||
if(0 == masterUser.szID[0] || m_UserInfo.usAdminLevel == CToolUserManager::MASTER)
|
||||
{
|
||||
// 현재 Promote유저가 있는지 살핀다. 없거나, Master면 바로 Promote를 하고 Broadcast를 한다.
|
||||
CToolUserManager::GetInstance().Promote(m_UserInfo);
|
||||
|
||||
ServerManage::SendUserInfo(GetBufferFactory(), 0,
|
||||
&m_UserInfo, 1, ServerManage::CMD::ManagerInfo, 0);
|
||||
}
|
||||
else if(m_UserInfo.usAdminLevel == CToolUserManager::GENERAL)
|
||||
{
|
||||
// 현재 Promote유저가 있고, 내가 General레벨이면, 정중히 요청을 한다.
|
||||
CManageToolServerDispatch* lpToolUserDispatch =
|
||||
CToolUserManager::GetInstance().GetManageUserDispatch();
|
||||
|
||||
ServerManage::UserInfo userInfo = m_UserInfo;
|
||||
userInfo.usSubCommand = ServerManage::CMD::REQUEST_TAKEBACK_PROMOTE;
|
||||
|
||||
// 아직 연결되어 있으면 요청 패킷을 보냄.
|
||||
if(0 == lpToolUserDispatch
|
||||
|| !ServerManage::SendUserInfo(GetBufferFactory(),
|
||||
&lpToolUserDispatch->GetSession(), &userInfo, 1,
|
||||
ServerManage::CMD::RequestUserReaction, 0))
|
||||
{
|
||||
cError = ServerManage::PROMOTE_TAKEBACK_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cError = ServerManage::PROMOTE_USER_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 != cError)
|
||||
{
|
||||
ERRLOG3(g_Log, "ID:%s/IP:%s/Promote user failed (ID:%s)",
|
||||
m_UserInfo.szID, GetSession().GetRemoteAddr().get_addr_string(), lpUserInfo->szID);
|
||||
|
||||
ServerManage::SendUserInfo(GetBufferFactory(), &GetSession(), 0, 0,
|
||||
ServerManage::CMD::RequestPromote, cError);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CManageToolServerDispatch::ProcessUserReaction(PktBase* lpPktBase)
|
||||
{
|
||||
unsigned char cError = 0;
|
||||
|
||||
ServerManage::UserCommand* lpUserCommand =
|
||||
reinterpret_cast<ServerManage::UserCommand*>(lpPktBase);
|
||||
|
||||
ServerManage::UserInfo* lpUserInfo =
|
||||
reinterpret_cast<ServerManage::UserInfo*>(lpUserCommand + 1);
|
||||
|
||||
if(!ServerManage::CheckUserPacketLength(lpPktBase, 1))
|
||||
{
|
||||
cError = ServerManage::INVALID_USER_PACKET_ERROR;
|
||||
}
|
||||
|
||||
CManageToolServerDispatch* lpRequestDispatch = 0;
|
||||
|
||||
if(0 == cError)
|
||||
{
|
||||
switch(lpUserInfo->usSubCommand)
|
||||
{
|
||||
case ServerManage::CMD::ACK_TAKEBACK_PROMOTE:
|
||||
|
||||
// 처음 요청자를 찾아서 Promote 성공 패킷을 보낸다.
|
||||
lpRequestDispatch = CToolUserManager::GetInstance().GetUserDispatch(lpUserInfo->szID);
|
||||
if(0 != lpRequestDispatch)
|
||||
{
|
||||
ServerManage::UserInfo manager = lpRequestDispatch->GetUserInfo();
|
||||
|
||||
// Promote 처리.
|
||||
CToolUserManager::GetInstance().Promote(manager);
|
||||
|
||||
// 누가 Manager인지 만천하에 알린다.
|
||||
ServerManage::SendUserInfo(GetBufferFactory(), 0,
|
||||
&manager, 1, ServerManage::CMD::ManagerInfo, 0);
|
||||
|
||||
// 본인에게 Ack.
|
||||
ServerManage::SendUserInfo(GetBufferFactory(), &lpRequestDispatch->GetSession(),
|
||||
&manager, 1, ServerManage::CMD::RequestPromote, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case ServerManage::CMD::NAK_TAKEBACK_PROMOTE:
|
||||
// 처음 요청자를 찾아서 Promote 실패 패킷을 보낸다.
|
||||
lpRequestDispatch = CToolUserManager::GetInstance().GetUserDispatch(lpUserInfo->szID);
|
||||
if(0 != lpRequestDispatch)
|
||||
{
|
||||
ServerManage::SendUserInfo(GetBufferFactory(), &lpRequestDispatch->GetSession(),
|
||||
&m_UserInfo, 1, ServerManage::CMD::RequestPromote, ServerManage::REJECTED_PROMOTE_USER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "StatServerDispatch.h"
|
||||
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Packet/ManagePacketCmd.h>
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
enum StatServerConst
|
||||
{
|
||||
STAT_SERVER_DEFAULT_DISPATCH_NUM = 10
|
||||
};
|
||||
|
||||
|
||||
CStatServerDispatch::CStatServerDispatch(CSession& Session)
|
||||
: CRylServerDispatch(Session, STAT_SERVER_DEFAULT_DISPATCH_NUM)
|
||||
|
||||
{
|
||||
DETLOG1(g_Log, "this:0x%p/CStatServerDispatch Created", this);
|
||||
}
|
||||
|
||||
CStatServerDispatch::~CStatServerDispatch()
|
||||
{
|
||||
DETLOG1(g_Log, "this:0x%p/CStatServerDispatch Destroyed", this);
|
||||
}
|
||||
|
||||
CSingleDispatch& CStatServerDispatch::GetDispatch()
|
||||
{
|
||||
static CSingleDispatch statServerDispatch;
|
||||
return statServerDispatch;
|
||||
}
|
||||
|
||||
void CStatServerDispatch::Connected()
|
||||
{
|
||||
GetDispatch().SetDispatch(this);
|
||||
}
|
||||
|
||||
void CStatServerDispatch::Disconnected()
|
||||
{
|
||||
GetDispatch().RemoveDispatch(this);
|
||||
}
|
||||
|
||||
bool CStatServerDispatch::DispatchPacket(PktBase* lpPktBase)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef _STAT_SERVER_DISPATCH_H_
|
||||
#define _STAT_SERVER_DISPATCH_H_
|
||||
|
||||
#include <Network/Packet/ManagePacketCmd.h>
|
||||
#include <Network/Dispatch/RylServerDispatch.h>
|
||||
#include <Network/Dispatch/SingleDispatchStorage.h>
|
||||
|
||||
|
||||
class CStatServerDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
CStatServerDispatch(CSession& Session);
|
||||
virtual ~CStatServerDispatch();
|
||||
|
||||
static CSingleDispatch& GetDispatch();
|
||||
|
||||
private:
|
||||
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "stdafx.h"
|
||||
#include "StatServerMultiDispatch.h"
|
||||
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Dispatch/MultiDispatchStorage.h>
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Setup/SetupClient.h>
|
||||
|
||||
enum StatServerConst
|
||||
{
|
||||
STAT_SERVER_DEFAULT_DISPATCH_NUM = 10
|
||||
};
|
||||
|
||||
CMultiDispatch& CStatServerMultiDispatch::GetDispatchTable()
|
||||
{
|
||||
static CMultiDispatch multiDispatch;
|
||||
return multiDispatch;
|
||||
}
|
||||
|
||||
CStatServerMultiDispatch::CStatServerMultiDispatch(CSession& Session)
|
||||
: CRylServerDispatch(Session, STAT_SERVER_DEFAULT_DISPATCH_NUM)
|
||||
{
|
||||
DETLOG1(g_Log, "this:0x%p/CStatServerMultiDispatch Created", this);
|
||||
}
|
||||
|
||||
CStatServerMultiDispatch::~CStatServerMultiDispatch()
|
||||
{
|
||||
DETLOG1(g_Log, "this:0x%p/CStatServerMultiDispatch Destroyed", this);
|
||||
}
|
||||
|
||||
void CStatServerMultiDispatch::Connected()
|
||||
{
|
||||
// 접속 IP를 key로 잡아서 세팅한다.
|
||||
INET_Addr& remoteAddr = GetSession().GetRemoteAddr();
|
||||
|
||||
unsigned long dwDispatchID = remoteAddr.get_addr_in().sin_addr.S_un.S_addr;
|
||||
GetDispatchTable().SetDispatch(dwDispatchID, this);
|
||||
|
||||
DETLOG2(g_Log, "this:0x%p/Key:%u/CStatServerMultiDispatch Connected", this, dwDispatchID);
|
||||
}
|
||||
|
||||
void CStatServerMultiDispatch::Disconnected()
|
||||
{
|
||||
// 접속 IP를 key로 잡아서 삭제한다.
|
||||
INET_Addr& remoteAddr = GetSession().GetRemoteAddr();
|
||||
|
||||
unsigned long dwDispatchID = remoteAddr.get_addr_in().sin_addr.S_un.S_addr;
|
||||
GetDispatchTable().RemoveDispatch(dwDispatchID);
|
||||
|
||||
DETLOG2(g_Log, "this:0x%p/Key:%u/CStatServerMultiDispatch Disconnected", this, dwDispatchID);
|
||||
}
|
||||
|
||||
|
||||
bool CStatServerMultiDispatch::DispatchPacket(PktBase* lpPktBase)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef _STAT_SERVER_MULTI_DISPATCH_H_
|
||||
#define _STAT_SERVER_MULTI_DISPATCH_H_
|
||||
|
||||
#include <Network/Packet/ManagePacketCmd.h>
|
||||
#include <Network/Dispatch/RylServerDispatch.h>
|
||||
#include <Network/Dispatch/MultiDispatchStorage.h>
|
||||
|
||||
class CStatServerMultiDispatch : public CRylServerDispatch
|
||||
{
|
||||
public:
|
||||
|
||||
static CMultiDispatch& GetDispatchTable();
|
||||
|
||||
CStatServerMultiDispatch(CSession& Session);
|
||||
virtual ~CStatServerMultiDispatch();
|
||||
|
||||
private:
|
||||
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
|
||||
virtual bool DispatchPacket(PktBase* lpPktBase);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,208 @@
|
||||
#include "stdafx.h"
|
||||
#include "SendManagePacket.h"
|
||||
|
||||
#include <tchar.h>
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Dispatch/Dispatch.h>
|
||||
#include <Network/Packet/WrapPacket.h>
|
||||
#include <Network/Packet/ManagePacketCmd.h>
|
||||
#include <Stream/Buffer/Buffer.h>
|
||||
#include <Stream/Buffer/BufferFactory.h>
|
||||
#include <Utility/Compress/MiniLZO/MiniLZOWrapper.h>
|
||||
|
||||
#include <UserManage/ToolUserManageTable.h>
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
|
||||
/*!
|
||||
\brief 관리 패킷 전송
|
||||
\param Session 세션
|
||||
\param cCmd 커맨드
|
||||
\param nMessage 윈도우 메시지 번호
|
||||
\param wParam WPARAM
|
||||
\param lParam LPARAM
|
||||
\param dwRunID RunID
|
||||
\param usDataLen 데이터 길이
|
||||
\param usFlags 추가 데이터 플래그
|
||||
\param lpData 보낼 데이터
|
||||
\param cError 에러 커맨드
|
||||
\return 패킷 전송 성공 여부
|
||||
*/
|
||||
bool ServerManage::SendManagePacket(CSession& Session,
|
||||
unsigned char cCmd,
|
||||
unsigned int nMessage,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
unsigned long dwRunID,
|
||||
unsigned short usDataLen,
|
||||
unsigned short usFlags,
|
||||
const void* lpData,
|
||||
unsigned char cError)
|
||||
{
|
||||
CBuffer* lpBuffer = CREATE_BUFFER(Session.GetPolicy().GetBufferFactory(),
|
||||
(sizeof(ManageCommand) + usDataLen));
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
ManageCommand* lpManageCommand = reinterpret_cast<ManageCommand*>(lpBuffer->wr_ptr());
|
||||
|
||||
lpManageCommand->nMessage = nMessage; // 메시지 번호
|
||||
lpManageCommand->wParam = wParam; // 파라미터1
|
||||
lpManageCommand->lParam = lParam; // 파라미터2
|
||||
|
||||
lpManageCommand->dwRunID = dwRunID; // 메세지 받을 곳의 IP
|
||||
lpManageCommand->usDataLen = (0 != lpData) ? usDataLen : 0; // 추가 데이터 길이
|
||||
lpManageCommand->usFlags = usFlags; // 기타 커맨드 (내용에 따라서 다름)
|
||||
|
||||
if(0 != lpData)
|
||||
{
|
||||
memcpy(reinterpret_cast<char*>(lpManageCommand + 1), lpData, usDataLen);
|
||||
}
|
||||
|
||||
if(PacketWrap::WrapCrypt(lpBuffer, sizeof(ManageCommand) + usDataLen, cCmd, 0, cError)
|
||||
&& Session.SendPending(lpBuffer))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
SAFE_RELEASE_BUFFER(lpBuffer);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief 관리 패킷 전송
|
||||
\param bufferFactory BufferFactory
|
||||
\param lpTarget 세션. 0이면 Broadcast
|
||||
\param lpUserInfo 유저 정보 (내부적으로 패스워드만 제거하고 보낸다)
|
||||
\param cUserInfoNum 유저 정보 개수
|
||||
\param cCommand 커맨드.
|
||||
\param cError 에러.
|
||||
\return 패킷 전송 성공 여부
|
||||
*/
|
||||
bool ServerManage::SendUserInfo(CBufferFactory& bufferFactory,
|
||||
CSession* lpTarget,
|
||||
const ServerManage::UserInfo* lpUserInfo,
|
||||
unsigned char cUserInfoNum,
|
||||
unsigned char cCommand,
|
||||
unsigned char cError)
|
||||
{
|
||||
// 다른 유저들에게 자신이 추가되었다는 메시지를 던진다.
|
||||
CBuffer* lpBuffer = CREATE_BUFFER(bufferFactory,
|
||||
sizeof(ServerManage::UserCommand) + sizeof(ServerManage::UserInfo) * cUserInfoNum);
|
||||
|
||||
CBuffer* lpCompressedBuffer = CREATE_BUFFER(bufferFactory,
|
||||
CMiniLZO::GetLeastCompressBuffer(sizeof(ServerManage::UserCommand) + sizeof(ServerManage::UserInfo) * cUserInfoNum));
|
||||
|
||||
if(0 != lpBuffer && 0 != lpCompressedBuffer)
|
||||
{
|
||||
ServerManage::UserCommand* lpUserCommand = reinterpret_cast<ServerManage::UserCommand*>(lpBuffer->wr_ptr());
|
||||
ServerManage::UserInfo* lpFirstUserInfo = reinterpret_cast<ServerManage::UserInfo*>(lpUserCommand + 1);
|
||||
ServerManage::UserInfo* lpLastUserInfo = lpFirstUserInfo + cUserInfoNum;
|
||||
|
||||
lpUserCommand->cUserInfoNum = cUserInfoNum;
|
||||
std::copy(lpUserInfo, lpUserInfo + cUserInfoNum, lpFirstUserInfo);
|
||||
|
||||
for(ServerManage::UserInfo* lpTempUserInfo = lpFirstUserInfo;
|
||||
lpTempUserInfo != lpLastUserInfo; ++lpTempUserInfo)
|
||||
{
|
||||
memset(lpTempUserInfo->szPassword, 0, sizeof(ServerManage::UserInfo::PASS_LEN) * sizeof(TCHAR));
|
||||
}
|
||||
|
||||
if(PacketWrap::WrapCompress(lpCompressedBuffer, lpBuffer->rd_ptr(),
|
||||
sizeof(ServerManage::UserCommand) + sizeof(ServerManage::UserInfo) * cUserInfoNum,
|
||||
cCommand, 0, cError))
|
||||
{
|
||||
if(lpTarget)
|
||||
{
|
||||
if(lpTarget->SendPending(lpCompressedBuffer))
|
||||
{
|
||||
SAFE_RELEASE_BUFFER(lpBuffer);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CToolUserManager::GetInstance().SendToAllLoginUser(
|
||||
lpCompressedBuffer->rd_ptr(), lpCompressedBuffer->length(), lpUserCommand->GetCmd());
|
||||
|
||||
SAFE_RELEASE_BUFFER(lpCompressedBuffer);
|
||||
SAFE_RELEASE_BUFFER(lpBuffer);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_RELEASE_BUFFER(lpCompressedBuffer);
|
||||
SAFE_RELEASE_BUFFER(lpBuffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ServerManage::CheckUserPacketLength(PktBase* lpPktBase, int nExpectUserInfoNum)
|
||||
{
|
||||
PktBase::LengthType nLength = lpPktBase->GetLen();
|
||||
|
||||
if(nLength < sizeof(ServerManage::UserCommand))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ServerManage::UserCommand* lpUserCommand = reinterpret_cast<ServerManage::UserCommand*>(lpPktBase);
|
||||
ServerManage::UserInfo* lpUserInfo = reinterpret_cast<ServerManage::UserInfo*>(lpUserCommand + 1);
|
||||
|
||||
if(0 < nExpectUserInfoNum)
|
||||
{
|
||||
if(nExpectUserInfoNum != lpUserCommand->cUserInfoNum ||
|
||||
nLength != sizeof(ServerManage::UserCommand) + sizeof(ServerManage::UserInfo) * nExpectUserInfoNum)
|
||||
{
|
||||
ERRLOG2(g_Log, "Invalid packet size : userinfo num : %d, packet size : %d",
|
||||
lpUserCommand->cUserInfoNum, nLength);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(nLength != sizeof(ServerManage::UserCommand))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ServerManage::CheckManagePacketLength(PktBase* lpPktBase)
|
||||
{
|
||||
unsigned short usPacketLength = lpPktBase->GetLen();
|
||||
|
||||
ServerManage::ManageCommand* lpManageCommand =
|
||||
reinterpret_cast<ServerManage::ManageCommand*>(lpPktBase);
|
||||
|
||||
if(usPacketLength < sizeof(ServerManage::ManageCommand) ||
|
||||
(usPacketLength != lpManageCommand->usDataLen + sizeof(ServerManage::ManageCommand)))
|
||||
{
|
||||
ERRLOG2(g_Log, "Invalid packet size : DataLen : %d, Packet size : %d",
|
||||
lpManageCommand->usDataLen, lpPktBase->GetLen());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
ServerManage::CSendManagePacketToClient::CSendManagePacketToClient(ManageCommand& manageCommand,
|
||||
const char* lpData)
|
||||
: m_ManageCommand(manageCommand),
|
||||
m_lpData(lpData)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ServerManage::CSendManagePacketToClient::operator() (CPacketDispatch& dispatch)
|
||||
{
|
||||
return SendManagePacket(dispatch.GetSession(),
|
||||
m_ManageCommand.GetCmd(), m_ManageCommand.nMessage,
|
||||
m_ManageCommand.wParam, m_ManageCommand.lParam,
|
||||
m_ManageCommand.dwRunID, m_ManageCommand.usDataLen, m_ManageCommand.usFlags,
|
||||
m_lpData, static_cast<unsigned char>(m_ManageCommand.GetError()));
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef _SEND_MANAGE_PACKET_H_
|
||||
#define _SEND_MANAGE_PACKET_H_
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
// forward decl.
|
||||
struct PktBase;
|
||||
class CSession;
|
||||
class CBufferFactory;
|
||||
class CPacketDispatch;
|
||||
|
||||
|
||||
namespace ServerManage
|
||||
{
|
||||
// forward decl.
|
||||
struct ManageCommand;
|
||||
struct UserInfo;
|
||||
|
||||
bool CheckManagePacketLength(PktBase* lpPktBase);
|
||||
bool CheckUserPacketLength(PktBase* lpPktBase, int nExpectUserInfoNum = -1);
|
||||
|
||||
// 서버 관리 패킷을 보낸다.
|
||||
bool SendManagePacket(
|
||||
CSession& Session, // 세션
|
||||
unsigned char cCmd, // 커맨드
|
||||
unsigned int nMessage, // 윈도우 메시지 번호
|
||||
WPARAM wParam, // WPARAM
|
||||
LPARAM lParam, // LPARAM
|
||||
unsigned long dwRunID, // RunID
|
||||
unsigned short usDataLen, // 데이터 길이
|
||||
unsigned short usFlags, // 추가 데이터 플래그
|
||||
const void* lpData, // 보낼 데이터
|
||||
unsigned char cError); // 에러 커맨드
|
||||
|
||||
// 유저 정보 패킷을 보낸다.
|
||||
bool SendUserInfo(
|
||||
CBufferFactory& bufferFactory, // BufferFactory
|
||||
CSession* lpTarget, // 세션. 0이면 Broadcast
|
||||
const ServerManage::UserInfo* lpUserInfo, // 유저 정보 (내부적으로 패스워드만 제거하고 보낸다)
|
||||
unsigned char cUserInfoNum, // 유저 정보 개수
|
||||
unsigned char cCommand, // 커맨드.
|
||||
unsigned char cError); // 에러.
|
||||
|
||||
class CSendManagePacketToClient
|
||||
{
|
||||
public:
|
||||
|
||||
CSendManagePacketToClient(ManageCommand& manageCommand, const char* lpData);
|
||||
|
||||
bool operator() (CPacketDispatch& dispatch);
|
||||
bool operator() (unsigned long dwKeyType, CPacketDispatch& dispatch)
|
||||
{ return operator() (dispatch); }
|
||||
|
||||
private:
|
||||
|
||||
ManageCommand& m_ManageCommand;
|
||||
const char* m_lpData;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
29
Server/ManageTool/ManageLibrary/ReadMe.txt
Normal file
29
Server/ManageTool/ManageLibrary/ReadMe.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
========================================================================
|
||||
정적 라이브러리 : ServerManagerary 프로젝트 개요
|
||||
========================================================================
|
||||
|
||||
응용 프로그램 마법사에서 이 ServerManagerary 라이브러리 프로젝트를 만들었습니다.
|
||||
이 파일에는 ServerManagerary 응용 프로그램을 구성하는 각각의 파일에
|
||||
들어 있는 요약 설명이 포함되어 있습니다.
|
||||
|
||||
|
||||
ServerManagerary.vcproj
|
||||
응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다.
|
||||
해당 파일을 생성한 Visual C++의 버전 정보를 비롯하여
|
||||
응용 프로그램 마법사에서 선택한 플랫폼, 구성 및
|
||||
프로젝트 기능에 대한 정보가 들어 있습니다.
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
StdAfx.h 및 StdAfx.cpp는
|
||||
ServerManagerary.pch라는 이름의 PCH(미리 컴파일된 헤더) 파일과
|
||||
StdAfx.obj라는 이름의 미리 컴파일된 형식 파일을 빌드하는 데 사용됩니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
기타 참고:
|
||||
|
||||
응용 프로그램 마법사에서 사용하는 "TODO:" 주석은 사용자가 추가하거나 사용자 지정해야 하는
|
||||
소스 코드 부분을 나타냅니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,537 @@
|
||||
#include "stdafx.h"
|
||||
#include "ManageClientManager.h"
|
||||
|
||||
#include <DB/SQLite.h>
|
||||
#include <DB/ManageServerDB.h>
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
|
||||
CManageClientManager& CManageClientManager::GetInstance()
|
||||
{
|
||||
static CManageClientManager manageClientManager(CManageServerDB::GetInstance());
|
||||
return manageClientManager;
|
||||
}
|
||||
|
||||
|
||||
CManageClientManager::CManageClientManager(CManageServerDB& manageServerDB)
|
||||
: m_ManageServerDB(manageServerDB)
|
||||
{
|
||||
ReloadRunInfo();
|
||||
}
|
||||
|
||||
CManageClientManager::~CManageClientManager()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
// 서버 정보 관련
|
||||
bool CManageClientManager::Add(InfoType eInfoType,
|
||||
const ServerManage::RunInfo& runInfo,
|
||||
unsigned long& dwID_Out)
|
||||
{
|
||||
const int MAX_QUERY_LEN = 512;
|
||||
char szQuery[MAX_QUERY_LEN];
|
||||
int nQueryLen = -1;
|
||||
|
||||
switch(eInfoType)
|
||||
{
|
||||
case SERVER_INFO:
|
||||
nQueryLen = _snprintf(szQuery, MAX_QUERY_LEN - 1,
|
||||
"INSERT INTO TblServerInfo values(%d, '%s')",
|
||||
runInfo.m_dwServerIP, runInfo.m_szServerName);
|
||||
break;
|
||||
|
||||
case RUN_PATH_INFO:
|
||||
|
||||
nQueryLen = _snprintf(szQuery, MAX_QUERY_LEN - 1,
|
||||
"INSERT INTO TblRunPath values(NULL, '%s')", runInfo.m_szPath);
|
||||
break;
|
||||
|
||||
case OPTION_INFO:
|
||||
|
||||
nQueryLen = _snprintf(szQuery, MAX_QUERY_LEN - 1,
|
||||
"INSERT INTO TblRunOptions values(NULL, '%s')", runInfo.m_szOption);
|
||||
break;
|
||||
|
||||
case RUN_INFO:
|
||||
|
||||
nQueryLen = _snprintf(szQuery, MAX_QUERY_LEN - 1,
|
||||
"INSERT INTO TblRunInfo values(NULL, %d, %d, %d)",
|
||||
runInfo.m_dwPathID, runInfo.m_dwOptionID, runInfo.m_dwServerIP);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ERRLOG1(g_Log, "Unknown InfoType : %d", eInfoType);
|
||||
return false;
|
||||
};
|
||||
|
||||
szQuery[MAX_QUERY_LEN - 1] = 0;
|
||||
if(nQueryLen <= 0)
|
||||
{
|
||||
ERRLOG1(g_Log, "Make query failed : %s", szQuery);
|
||||
return false;
|
||||
}
|
||||
|
||||
CSQLite::Dataset executeQuery(m_ManageServerDB.GetSQLite(), szQuery);
|
||||
if(!executeQuery.Compile() || !executeQuery.Execute())
|
||||
{
|
||||
if(0 != executeQuery.GetLastError())
|
||||
{
|
||||
ERRLOG2(g_Log, "Add failed : error : %s(Query:%s)",
|
||||
executeQuery.GetLastError(), szQuery);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
dwID_Out = m_ManageServerDB.GetSQLite().GetLastInsertRowID();
|
||||
return ReloadRunInfo();
|
||||
}
|
||||
|
||||
bool CManageClientManager::Modify(InfoType eInfoType, const ServerManage::RunInfo& runInfo)
|
||||
{
|
||||
const int MAX_QUERY_LEN = 512;
|
||||
char szQuery[MAX_QUERY_LEN];
|
||||
int nQueryLen = -1;
|
||||
|
||||
switch(eInfoType)
|
||||
{
|
||||
case SERVER_INFO:
|
||||
nQueryLen = _snprintf(szQuery, MAX_QUERY_LEN - 1,
|
||||
"UPDATE TblServerInfo SET ServerName = '%s' WHERE IP = %d",
|
||||
runInfo.m_szServerName, runInfo.m_dwServerIP);
|
||||
break;
|
||||
|
||||
case RUN_PATH_INFO:
|
||||
nQueryLen = _snprintf(szQuery, MAX_QUERY_LEN - 1,
|
||||
"UPDATE TblRunPath SET RunPath = '%s' WHERE PathID = %d",
|
||||
runInfo.m_szPath, runInfo.m_dwPathID);
|
||||
break;
|
||||
|
||||
case OPTION_INFO:
|
||||
nQueryLen = _snprintf(szQuery, MAX_QUERY_LEN - 1,
|
||||
"UPDATE TblRunOptions SET RunOption = '%s' WHERE OptionID = %d",
|
||||
runInfo.m_szOption, runInfo.m_dwOptionID);
|
||||
break;
|
||||
|
||||
case RUN_INFO:
|
||||
|
||||
nQueryLen = _snprintf(szQuery, MAX_QUERY_LEN - 1,
|
||||
"UPDATE TblRunInfo SET PathID = %d, OptionID = %d, ServerIP = %d WHERE RunID = %d",
|
||||
runInfo.m_dwPathID, runInfo.m_dwOptionID, runInfo.m_dwServerIP, runInfo.m_dwRunID);
|
||||
break;
|
||||
|
||||
default:
|
||||
ERRLOG1(g_Log, "Unknown InfoType : %d", eInfoType);
|
||||
return false;
|
||||
};
|
||||
|
||||
szQuery[MAX_QUERY_LEN - 1] = 0;
|
||||
if(nQueryLen <= 0)
|
||||
{
|
||||
ERRLOG1(g_Log, "Make query failed : %s", szQuery);
|
||||
return false;
|
||||
}
|
||||
|
||||
CSQLite::Dataset executeQuery(m_ManageServerDB.GetSQLite(), szQuery);
|
||||
if(!executeQuery.Compile() || !executeQuery.Execute())
|
||||
{
|
||||
if(0 != executeQuery.GetLastError())
|
||||
{
|
||||
ERRLOG2(g_Log, "Modify failed : error : %s(Query:%s)",
|
||||
executeQuery.GetLastError(), szQuery);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return ReloadRunInfo();
|
||||
}
|
||||
|
||||
bool CManageClientManager::Remove(InfoType eInfoType, unsigned long dwID, bool bDeleteRelated)
|
||||
{
|
||||
const int MAX_QUERY_LEN = 512;
|
||||
char szQuery[MAX_QUERY_LEN];
|
||||
char szDeleteRelated[MAX_QUERY_LEN];
|
||||
|
||||
const char* szRelatedKey = 0;
|
||||
|
||||
int nQueryLen = -1;
|
||||
|
||||
switch(eInfoType)
|
||||
{
|
||||
case SERVER_INFO:
|
||||
nQueryLen = _snprintf(szQuery, MAX_QUERY_LEN - 1,
|
||||
"DELETE FROM TblServerInfo WHERE IP = %d", dwID);
|
||||
szRelatedKey = "ServerIP";
|
||||
break;
|
||||
|
||||
case RUN_PATH_INFO:
|
||||
nQueryLen = _snprintf(szQuery, MAX_QUERY_LEN - 1,
|
||||
"DELETE FROM TblRunPath WHERE PathID = %d;", dwID);
|
||||
szRelatedKey = "PathID";
|
||||
break;
|
||||
|
||||
case OPTION_INFO:
|
||||
nQueryLen = _snprintf(szQuery, MAX_QUERY_LEN - 1,
|
||||
"DELETE FROM TblRunOptions WHERE OptionID = %d;", dwID);
|
||||
szRelatedKey = "OptionID";
|
||||
break;
|
||||
|
||||
case RUN_INFO:
|
||||
|
||||
nQueryLen = _snprintf(szQuery, MAX_QUERY_LEN - 1,
|
||||
"DELETE FROM TblRunInfo WHERE RunID = %d", dwID);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ERRLOG1(g_Log, "Unknown InfoType : %d", eInfoType);
|
||||
return false;
|
||||
};
|
||||
|
||||
szQuery[MAX_QUERY_LEN - 1] = 0;
|
||||
if(nQueryLen <= 0)
|
||||
{
|
||||
ERRLOG1(g_Log, "Make query failed : %s", szQuery);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CSQLite::Dataset executeQuery(m_ManageServerDB.GetSQLite(), szQuery);
|
||||
if(!executeQuery.Compile() || !executeQuery.Execute())
|
||||
{
|
||||
if(0 != executeQuery.GetLastError())
|
||||
{
|
||||
ERRLOG2(g_Log, "Delete failed : error : %s(Query:%s)",
|
||||
executeQuery.GetLastError(), szQuery);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(bDeleteRelated && 0 != szRelatedKey)
|
||||
{
|
||||
nQueryLen = _snprintf(szDeleteRelated, MAX_QUERY_LEN - 1,
|
||||
"DELETE FROM TblRunInfo WHERE %s = %d;", szRelatedKey, dwID);
|
||||
|
||||
if(nQueryLen <= 0)
|
||||
{
|
||||
ERRLOG1(g_Log, "Make query failed : %s", szDeleteRelated);
|
||||
return false;
|
||||
}
|
||||
|
||||
CSQLite::Dataset deleteRelatedQuery(m_ManageServerDB.GetSQLite(), szDeleteRelated);
|
||||
if(!deleteRelatedQuery.Compile() || !deleteRelatedQuery.Execute())
|
||||
{
|
||||
if(0 != deleteRelatedQuery.GetLastError())
|
||||
{
|
||||
ERRLOG2(g_Log, "Delete related failed : error : %s(Query:%s)",
|
||||
deleteRelatedQuery.GetLastError(), szDeleteRelated);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ReloadRunInfo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int GetServerInfoCallback(void *callBackArg, int nColumnNum,
|
||||
char **szColumnValues, char **szColumnNames)
|
||||
{
|
||||
if(2 == nColumnNum)
|
||||
{
|
||||
CManageClientManager::RunTable& runTable =
|
||||
*reinterpret_cast<CManageClientManager::RunTable*>(callBackArg);
|
||||
|
||||
ServerManage::RunInfo runInfo;
|
||||
memset(&runInfo, 0, sizeof(ServerManage::RunInfo));
|
||||
|
||||
runInfo.m_dwServerIP = atol(szColumnValues[0]);
|
||||
_snprintf(runInfo.m_szServerName, ServerManage::RunInfo::MAX_SERVER_NAME - 1,
|
||||
"%s", szColumnValues[1]);
|
||||
|
||||
runInfo.m_szServerName[ServerManage::RunInfo::MAX_SERVER_NAME - 1] = 0;
|
||||
|
||||
if(!runTable.insert(CManageClientManager::RunTable::value_type(
|
||||
runInfo.m_dwServerIP, runInfo)).second)
|
||||
{
|
||||
ERRLOG1(g_Log, "Insert failed. Key : %d", runInfo.m_dwServerIP);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetPathInfoCallback(void *callBackArg, int nColumnNum,
|
||||
char **szColumnValues, char **szColumnNames)
|
||||
{
|
||||
if(2 == nColumnNum)
|
||||
{
|
||||
CManageClientManager::RunTable& runTable =
|
||||
*reinterpret_cast<CManageClientManager::RunTable*>(callBackArg);
|
||||
|
||||
ServerManage::RunInfo runInfo;
|
||||
memset(&runInfo, 0, sizeof(ServerManage::RunInfo));
|
||||
|
||||
runInfo.m_dwPathID = atol(szColumnValues[0]);
|
||||
|
||||
_snprintf(runInfo.m_szPath, ServerManage::RunInfo::MAX_PATH_LEN - 1,
|
||||
"%s", szColumnValues[1]);
|
||||
|
||||
runInfo.m_szPath[ServerManage::RunInfo::MAX_PATH_LEN - 1] = 0;
|
||||
|
||||
if(!runTable.insert(CManageClientManager::RunTable::value_type(
|
||||
runInfo.m_dwPathID, runInfo)).second)
|
||||
{
|
||||
ERRLOG1(g_Log, "Insert failed. Key : %d", runInfo.m_dwPathID);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetOptionInfoCallback(void *callBackArg, int nColumnNum,
|
||||
char **szColumnValues, char **szColumnNames)
|
||||
{
|
||||
if(2 == nColumnNum)
|
||||
{
|
||||
CManageClientManager::RunTable& runTable =
|
||||
*reinterpret_cast<CManageClientManager::RunTable*>(callBackArg);
|
||||
|
||||
ServerManage::RunInfo runInfo;
|
||||
memset(&runInfo, 0, sizeof(ServerManage::RunInfo));
|
||||
|
||||
runInfo.m_dwOptionID = atol(szColumnValues[0]);
|
||||
|
||||
_snprintf(runInfo.m_szOption, ServerManage::RunInfo::MAX_OPT_LEN - 1,
|
||||
"%s", szColumnValues[1]);
|
||||
|
||||
runInfo.m_szOption[ServerManage::RunInfo::MAX_OPT_LEN - 1] = 0;
|
||||
|
||||
if(!runTable.insert(CManageClientManager::RunTable::value_type(
|
||||
runInfo.m_dwOptionID, runInfo)).second)
|
||||
{
|
||||
ERRLOG1(g_Log, "Insert failed. Key : %d", runInfo.m_dwOptionID);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetRunInfoCallback(void *callBackArg, int nColumnNum,
|
||||
char **szColumnValues, char **szColumnNames)
|
||||
{
|
||||
if(4 == nColumnNum)
|
||||
{
|
||||
CManageClientManager::RunTable& runTable =
|
||||
*reinterpret_cast<CManageClientManager::RunTable*>(callBackArg);
|
||||
|
||||
ServerManage::RunInfo runInfo;
|
||||
memset(&runInfo, 0, sizeof(ServerManage::RunInfo));
|
||||
|
||||
runInfo.m_dwRunID = atol(szColumnValues[0]);
|
||||
runInfo.m_dwPathID = atol(szColumnValues[1]);
|
||||
runInfo.m_dwOptionID = atol(szColumnValues[2]);
|
||||
runInfo.m_dwServerIP = atol(szColumnValues[3]);
|
||||
|
||||
if(!runTable.insert(CManageClientManager::RunTable::value_type(
|
||||
runInfo.m_dwRunID, runInfo)).second)
|
||||
{
|
||||
ERRLOG1(g_Log, "Insert failed. Key : %d", runInfo.m_dwOptionID);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool CManageClientManager::Get(InfoType eInfoType, RunTable& runTable)
|
||||
{
|
||||
runTable.clear();
|
||||
|
||||
const char* szQuery = 0;
|
||||
CSQLite::QueryCallBack lpQueryCallBack = 0;
|
||||
|
||||
switch(eInfoType)
|
||||
{
|
||||
case SERVER_INFO:
|
||||
szQuery = "SELECT IP, ServerName FROM TblServerInfo";
|
||||
lpQueryCallBack = GetServerInfoCallback;
|
||||
break;
|
||||
|
||||
case RUN_PATH_INFO:
|
||||
szQuery = "SELECT PathID, RunPath FROM TblRunPath";
|
||||
lpQueryCallBack = GetPathInfoCallback;
|
||||
break;
|
||||
|
||||
case OPTION_INFO:
|
||||
szQuery = "SELECT OptionID, RunOption FROM TblRunOptions";
|
||||
lpQueryCallBack = GetOptionInfoCallback;
|
||||
break;
|
||||
|
||||
case RUN_INFO:
|
||||
szQuery = "SELECT RunID, PathID, OptionID, ServerIP FROM TblRunInfo";
|
||||
lpQueryCallBack = GetRunInfoCallback;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERRLOG1(g_Log, "Unknown InfoType : %d", eInfoType);
|
||||
return false;
|
||||
};
|
||||
|
||||
if(!m_ManageServerDB.GetSQLite().ExecuteQuery(szQuery, lpQueryCallBack, &runTable))
|
||||
{
|
||||
const char* szError = m_ManageServerDB.GetSQLite().GetLastError();
|
||||
if(0 != szError)
|
||||
{
|
||||
ERRLOG2(g_Log, "Query failed : refresh runinfo failed : %s(Query:%s)",
|
||||
szError, szQuery);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
// 실행 정보 얻어오기
|
||||
bool CManageClientManager::GetRunInfo(ServerManage::RunInfo* lpRunInfo_Out, size_t* nArrayNum_InOut)
|
||||
{
|
||||
size_t nRunTableSize = m_RunTable.size();
|
||||
|
||||
if(0 != lpRunInfo_Out && 0 != nArrayNum_InOut && nRunTableSize <= *nArrayNum_InOut)
|
||||
{
|
||||
RunTable::iterator pos = m_RunTable.begin();
|
||||
RunTable::iterator end = m_RunTable.end();
|
||||
|
||||
for(; pos != end; ++pos, ++lpRunInfo_Out)
|
||||
{
|
||||
*lpRunInfo_Out = pos->second;
|
||||
}
|
||||
|
||||
*nArrayNum_InOut = nRunTableSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CManageClientManager::GetRunInfo(unsigned long dwRunID, ServerManage::RunInfo& runInfo_Out)
|
||||
{
|
||||
RunTable::iterator pos = m_RunTable.find(dwRunID);
|
||||
if(pos != m_RunTable.end())
|
||||
{
|
||||
runInfo_Out = pos->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CManageClientManager::HasRunInfo(unsigned long dwRunID)
|
||||
{
|
||||
return m_RunTable.find(dwRunID) != m_RunTable.end();
|
||||
}
|
||||
|
||||
void CManageClientManager::GetRunInfoFromIP(unsigned long dwServerIP, RunTable& runTable)
|
||||
{
|
||||
RunTable::iterator pos = m_RunTable.begin();
|
||||
RunTable::iterator end = m_RunTable.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
RunTable::value_type& data = *pos;
|
||||
|
||||
if(data.second.m_dwServerIP == dwServerIP)
|
||||
{
|
||||
runTable.insert(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ReloadRunInfoCallback(void *callBackArg, int nColumnNum, char **szColumnValues, char **szColumnNames)
|
||||
{
|
||||
CManageClientManager::RunTable& runTable =
|
||||
*reinterpret_cast<CManageClientManager::RunTable*>(callBackArg);
|
||||
|
||||
if(7 == nColumnNum)
|
||||
{
|
||||
ServerManage::RunInfo runInfo;
|
||||
memset(&runInfo, 0, sizeof(ServerManage::RunInfo));
|
||||
|
||||
runInfo.m_dwRunID = atol(szColumnValues[0]);
|
||||
runInfo.m_dwServerIP = atol(szColumnValues[1]);
|
||||
runInfo.m_dwPathID = atol(szColumnValues[2]);
|
||||
runInfo.m_dwOptionID = atol(szColumnValues[3]);
|
||||
|
||||
_snprintf(runInfo.m_szServerName, ServerManage::RunInfo::MAX_SERVER_NAME - 1,
|
||||
"%s", szColumnValues[4]);
|
||||
|
||||
runInfo.m_szServerName[ServerManage::RunInfo::MAX_SERVER_NAME - 1] = 0;
|
||||
|
||||
_snprintf(runInfo.m_szPath, ServerManage::RunInfo::MAX_PATH_LEN - 1,
|
||||
"%s", szColumnValues[5]);
|
||||
|
||||
runInfo.m_szPath[ServerManage::RunInfo::MAX_PATH_LEN - 1] = 0;
|
||||
|
||||
_snprintf(runInfo.m_szOption, ServerManage::RunInfo::MAX_OPT_LEN - 1,
|
||||
"%s", szColumnValues[6]);
|
||||
|
||||
runInfo.m_szOption[ServerManage::RunInfo::MAX_OPT_LEN - 1] = 0;
|
||||
|
||||
if(!runTable.insert(CManageClientManager::RunTable::value_type(
|
||||
atol(szColumnValues[0]), runInfo)).second)
|
||||
{
|
||||
ERRLOG0(g_Log, "Reload failed");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool CManageClientManager::ReloadRunInfo()
|
||||
{
|
||||
m_RunTable.clear();
|
||||
|
||||
const char* szQuery = "SELECT TblRunInfo.RunID, TblRunInfo.ServerIP, TblRunInfo.PathID, "
|
||||
"TblRunInfo.OptionID, TblServerInfo.ServerName, TblRunPath.RunPath, TblRunOptions.RunOption "
|
||||
"FROM TblRunInfo "
|
||||
"LEFT OUTER JOIN TblRunPath ON TblRunInfo.PathID = TblRunPath.PathID "
|
||||
"LEFT OUTER JOIN TblRunOptions ON TblRunInfo.OptionID = TblRunOptions.OptionID "
|
||||
"LEFT OUTER JOIN TblServerInfo ON TblRunInfo.ServerIP = TblServerInfo.IP ";
|
||||
|
||||
if(!m_ManageServerDB.GetSQLite().ExecuteQuery(szQuery, ReloadRunInfoCallback, &m_RunTable))
|
||||
{
|
||||
const char* szError = m_ManageServerDB.GetSQLite().GetLastError();
|
||||
if(0 != szError)
|
||||
{
|
||||
ERRLOG2(g_Log, "Query failed : refresh runinfo failed : %s(Query:%s)",
|
||||
szError, szQuery);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
#ifndef _CUSTOM_MANAGE_CLIENT_MANAGER_H_
|
||||
#define _CUSTOM_MANAGE_CLIENT_MANAGER_H_
|
||||
|
||||
#pragma warning(disable:4800)
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <map>
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
#include <Network/Packet/ManagePacketCmd.h>
|
||||
|
||||
// forward decl.
|
||||
class CSession;
|
||||
class CManageServerDB;
|
||||
|
||||
class CManageClientManager
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::map<unsigned long, ServerManage::RunInfo, std::less<unsigned long>,
|
||||
boost::pool_allocator<std::pair<unsigned long, ServerManage::RunInfo> > > RunTable;
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_RUNID = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
enum InfoType
|
||||
{
|
||||
SERVER_INFO,
|
||||
RUN_PATH_INFO,
|
||||
OPTION_INFO,
|
||||
|
||||
RUN_INFO
|
||||
};
|
||||
|
||||
static CManageClientManager& GetInstance();
|
||||
|
||||
static bool SendRunInfo(CSession& Session, const RunTable& runTable);
|
||||
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
// 서버 정보 관련
|
||||
bool Add(InfoType eInfoType, const ServerManage::RunInfo& runInfo, unsigned long& dwID_Out);
|
||||
bool Modify(InfoType eInfoType, const ServerManage::RunInfo& runInfo);
|
||||
bool Remove(InfoType eInfoType, unsigned long dwID, bool bDeleteRelated);
|
||||
bool Get(InfoType eInfoType, RunTable& runTable);
|
||||
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
// 실행 정보 얻어오기
|
||||
bool GetRunInfo(ServerManage::RunInfo* lpRunInfo_Out, size_t* nArrayNum_InOut);
|
||||
bool GetRunInfo(unsigned long dwRunID, ServerManage::RunInfo& runInfo_Out);
|
||||
|
||||
bool HasRunInfo(unsigned long dwRunID);
|
||||
|
||||
void GetRunInfoFromIP(unsigned long dwServerIP, RunTable& runTable);
|
||||
const RunTable& GetRunInfoTable() const { return m_RunTable; }
|
||||
|
||||
size_t GetRunInfoNum() { return m_RunTable.size(); }
|
||||
|
||||
template<typename FnProcess>
|
||||
void EnumRunInfo(FnProcess fnProcess)
|
||||
{
|
||||
RunTable::const_iterator pos = m_RunTable.begin();
|
||||
RunTable::const_iterator end = m_RunTable.end();
|
||||
|
||||
for(;pos != end; ++pos)
|
||||
{
|
||||
fnProcess(pos->second);
|
||||
}
|
||||
}
|
||||
|
||||
bool ReloadRunInfo();
|
||||
|
||||
private:
|
||||
|
||||
CManageClientManager(CManageServerDB& manageServerDB);
|
||||
~CManageClientManager();
|
||||
|
||||
CManageServerDB& m_ManageServerDB;
|
||||
RunTable m_RunTable;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
#include "stdafx.h"
|
||||
#include "ManageClientManager.h"
|
||||
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Dispatch/SendManagePacket.h>
|
||||
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
bool CManageClientManager::SendRunInfo(CSession& Session, const RunTable& runTable)
|
||||
{
|
||||
if(!runTable.empty())
|
||||
{
|
||||
CManageClientManager::RunTable::const_iterator pos = runTable.begin();
|
||||
CManageClientManager::RunTable::const_iterator end = runTable.end();
|
||||
|
||||
const int MAX_RUN_INFO = (PktMaxLen - sizeof(ServerManage::ManageCommand)) / sizeof(ServerManage::RunInfo);
|
||||
ServerManage::RunInfo tempRunInfo[MAX_RUN_INFO];
|
||||
|
||||
if(!ServerManage::SendManagePacket(Session, ServerManage::CMD::UpdateRunList,
|
||||
0, 0, 0, 0, 0, ServerManage::SEND_RUNINFO_START, 0, 0))
|
||||
{
|
||||
ERRLOG1(g_Log, "SS:0x%p/UpdateRunList : SendRunInfoStart packet failed", &Session);
|
||||
return false;
|
||||
}
|
||||
|
||||
int nRunInfo = 0;
|
||||
|
||||
for(;pos != end; ++pos)
|
||||
{
|
||||
tempRunInfo[nRunInfo] = pos->second;
|
||||
|
||||
++nRunInfo;
|
||||
|
||||
if(nRunInfo == MAX_RUN_INFO)
|
||||
{
|
||||
if(!ServerManage::SendManagePacket(Session,
|
||||
ServerManage::CMD::UpdateRunList,
|
||||
0, 0, 0, 0, nRunInfo * sizeof(ServerManage::RunInfo),
|
||||
ServerManage::SEND_RUNINFO_NOW, tempRunInfo, 0))
|
||||
{
|
||||
ERRLOG1(g_Log, "SS:0x%p/UpdateRunList : SendRunInfoNow packet failed", &Session);
|
||||
return false;
|
||||
}
|
||||
|
||||
nRunInfo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 < nRunInfo)
|
||||
{
|
||||
if(!ServerManage::SendManagePacket(Session, ServerManage::CMD::UpdateRunList,
|
||||
0, 0, 0, 0, nRunInfo * sizeof(ServerManage::RunInfo),
|
||||
ServerManage::SEND_RUNINFO_NOW, tempRunInfo, 0))
|
||||
{
|
||||
ERRLOG1(g_Log, "SS:0x%p/UpdateRunList : SendRunInfoNow packet failed", &Session);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ServerManage::SendManagePacket(Session, ServerManage::CMD::UpdateRunList,
|
||||
0, 0, 0, 0, 0, ServerManage::SEND_RUNINFO_FINISH, 0, 0))
|
||||
{
|
||||
ERRLOG1(g_Log, "SS:0x%p/UpdateRunList : SendRunInfoFinish packet failed", &Session);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
219
Server/ManageTool/ManageLibrary/Setup/RylServerBindRunID.cpp
Normal file
219
Server/ManageTool/ManageLibrary/Setup/RylServerBindRunID.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
#include "stdafx.h"
|
||||
#include "RylServerBindRunID.h"
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
#include <ServerManage/ManageClientManager.h>
|
||||
|
||||
|
||||
CRylServerBindRunID& CRylServerBindRunID::GetInstance()
|
||||
{
|
||||
static CRylServerBindRunID bindRunID;
|
||||
return bindRunID;
|
||||
}
|
||||
|
||||
|
||||
CRylServerBindRunID::CRylServerBindRunID()
|
||||
{
|
||||
_sntprintf(m_szDefaultSetupFileName, MAX_PATH - 1, "%s",
|
||||
_T("./RylSetupBindServerID.ini"));
|
||||
|
||||
m_szDefaultSetupFileName[MAX_PATH - 1] = 0;
|
||||
|
||||
Load();
|
||||
}
|
||||
|
||||
CRylServerBindRunID::~CRylServerBindRunID()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool CRylServerBindRunID::SetID(unsigned long dwRunID, unsigned long dwServerID)
|
||||
{
|
||||
std::pair<BindIDTable::iterator, bool> runIDpair =
|
||||
m_RunID.insert(BindIDTable::value_type(dwRunID, dwServerID));
|
||||
|
||||
if(runIDpair.second)
|
||||
{
|
||||
std::pair<BindIDTable::iterator, bool> serverIDPair =
|
||||
m_ServerID.insert(BindIDTable::value_type(dwServerID, dwRunID));
|
||||
|
||||
if(serverIDPair.second)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
m_RunID.erase(runIDpair.first);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CRylServerBindRunID::RemoveFromRunID(unsigned long dwRunID)
|
||||
{
|
||||
BindIDTable::iterator pos_runID = m_RunID.find(dwRunID);
|
||||
|
||||
if(pos_runID != m_RunID.end())
|
||||
{
|
||||
unsigned long dwServerID = pos_runID->second;
|
||||
|
||||
BindIDTable::iterator pos_serverID = m_ServerID.find(dwServerID);
|
||||
|
||||
if(pos_serverID != m_ServerID.end())
|
||||
{
|
||||
m_RunID.erase(pos_runID);
|
||||
m_ServerID.erase(pos_serverID);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CRylServerBindRunID::RemoveFromServerID(unsigned long dwServerID)
|
||||
{
|
||||
BindIDTable::iterator pos_serverID = m_ServerID.find(dwServerID);
|
||||
|
||||
if(pos_serverID != m_ServerID.end())
|
||||
{
|
||||
unsigned long dwRunID = pos_serverID->second;
|
||||
|
||||
BindIDTable::iterator pos_runID = m_RunID.find(dwRunID);
|
||||
|
||||
if(pos_runID != m_RunID.end())
|
||||
{
|
||||
m_RunID.erase(pos_runID);
|
||||
m_ServerID.erase(pos_serverID);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CRylServerBindRunID::GetRunID(unsigned long dwServerID, unsigned long* lpdwRunID)
|
||||
{
|
||||
BindIDTable::iterator pos = m_ServerID.find(dwServerID);
|
||||
|
||||
if(0 != lpdwRunID && pos != m_ServerID.end())
|
||||
{
|
||||
*lpdwRunID = pos->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CRylServerBindRunID::GetServerID(unsigned long dwRunID, unsigned long* lpdwServerID)
|
||||
{
|
||||
BindIDTable::iterator pos = m_RunID.find(dwRunID);
|
||||
|
||||
if(0 != lpdwServerID && pos != m_RunID.end())
|
||||
{
|
||||
*lpdwServerID = pos->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CRylServerBindRunID::SetSetupFileName(const TCHAR* szSetupFileName)
|
||||
{
|
||||
if(0 != szSetupFileName)
|
||||
{
|
||||
_sntprintf(m_szDefaultSetupFileName, MAX_PATH - 1, "%s", szSetupFileName);
|
||||
m_szDefaultSetupFileName[MAX_PATH - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CRylServerBindRunID::Load()
|
||||
{
|
||||
HANDLE hFile = CreateFile(m_szDefaultSetupFileName,
|
||||
GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
||||
unsigned long dwWritten = 0;
|
||||
bool bResult = false;
|
||||
|
||||
if(INVALID_HANDLE_VALUE != hFile)
|
||||
{
|
||||
size_t nBindIDNum = 0;
|
||||
|
||||
m_RunID.clear();
|
||||
m_ServerID.clear();
|
||||
|
||||
if(ReadFile(hFile, &nBindIDNum, sizeof(size_t), &dwWritten, 0))
|
||||
{
|
||||
BindID bindID;
|
||||
|
||||
for(size_t nCount = 0; nCount < nBindIDNum; ++nCount)
|
||||
{
|
||||
if(ReadFile(hFile, &bindID, sizeof(BindID), &dwWritten, 0))
|
||||
{
|
||||
m_RunID.insert(bindID);
|
||||
std::swap(bindID.first, bindID.second);
|
||||
m_ServerID.insert(bindID);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(nCount == nBindIDNum)
|
||||
{
|
||||
bResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
};
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
bool CRylServerBindRunID::Save()
|
||||
{
|
||||
HANDLE hFile = CreateFile(m_szDefaultSetupFileName,
|
||||
GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
||||
unsigned long dwWritten = 0;
|
||||
bool bResult = false;
|
||||
|
||||
if(INVALID_HANDLE_VALUE != hFile)
|
||||
{
|
||||
size_t nBindIDNum = m_RunID.size();
|
||||
|
||||
if(WriteFile(hFile, &nBindIDNum, sizeof(size_t), &dwWritten, 0))
|
||||
{
|
||||
BindIDTable::iterator pos = m_RunID.begin();
|
||||
BindIDTable::iterator end = m_RunID.end();
|
||||
|
||||
BindID bindID;
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
bindID = *pos;
|
||||
|
||||
if(!WriteFile(hFile, &bindID, sizeof(BindID), &dwWritten, 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(pos == end)
|
||||
{
|
||||
bResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
};
|
||||
|
||||
return bResult;
|
||||
}
|
||||
61
Server/ManageTool/ManageLibrary/Setup/RylServerBindRunID.h
Normal file
61
Server/ManageTool/ManageLibrary/Setup/RylServerBindRunID.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef _RYL_SERVER_BIND_RUN_ID_
|
||||
#define _RYL_SERVER_BIND_RUN_ID_
|
||||
|
||||
#pragma warning(disable:4800)
|
||||
|
||||
#include <map>
|
||||
#include <new>
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
class CRylServerBindRunID
|
||||
{
|
||||
public:
|
||||
|
||||
static CRylServerBindRunID& GetInstance();
|
||||
|
||||
bool SetID(unsigned long dwRunID, unsigned long dwServerID);
|
||||
bool RemoveFromRunID(unsigned long dwRunID);
|
||||
bool RemoveFromServerID(unsigned long dwServerID);
|
||||
|
||||
bool GetRunID(unsigned long dwServerID, unsigned long* lpdwRunID);
|
||||
bool GetServerID(unsigned long dwRunID, unsigned long* lpdwServerID);
|
||||
|
||||
void SetSetupFileName(const TCHAR* szSetupFileName);
|
||||
|
||||
bool Save();
|
||||
bool Load();
|
||||
|
||||
template<typename FnProcess>
|
||||
void EnumID(FnProcess fnProcess)
|
||||
{
|
||||
BindIDTable::iterator pos = m_RunID.begin();
|
||||
BindIDTable::iterator end = m_RunID.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
// first : RunID, Second : ServerID
|
||||
fnProcess(pos->first, pos->second);
|
||||
}
|
||||
}
|
||||
|
||||
size_t GetPairNum() const { return m_RunID.size(); }
|
||||
|
||||
private:
|
||||
|
||||
typedef std::pair<unsigned long, unsigned long> BindID;
|
||||
|
||||
typedef std::map<unsigned long, unsigned long, std::less<unsigned long>,
|
||||
boost::fast_pool_allocator<std::pair<unsigned long, unsigned long> > > BindIDTable;
|
||||
|
||||
CRylServerBindRunID();
|
||||
~CRylServerBindRunID();
|
||||
|
||||
BindIDTable m_RunID; // key : RunID, value : ServerID
|
||||
BindIDTable m_ServerID; // key : ServerID, value : RunID
|
||||
|
||||
TCHAR m_szDefaultSetupFileName[MAX_PATH];
|
||||
};
|
||||
|
||||
#endif
|
||||
156
Server/ManageTool/ManageLibrary/Setup/RylServerGroupSetup.cpp
Normal file
156
Server/ManageTool/ManageLibrary/Setup/RylServerGroupSetup.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
#include "stdafx.h"
|
||||
#include "RylServerGroupSetup.h"
|
||||
|
||||
|
||||
// forward decl.
|
||||
void ReadRylServerStringValues(CRylServerGroupSetup::ServerStringMap& serverStringMap,
|
||||
const char* szReadSection, const char* szKey, const char* szFileName);
|
||||
|
||||
void WriteRylServerStringValues(CRylServerGroupSetup::ServerStringMap& serverStringMap,
|
||||
const char* szReadSection, const char* szKey, const char* szFileName);
|
||||
|
||||
CRylServerGroupSetup& CRylServerGroupSetup::GetInstance()
|
||||
{
|
||||
static CRylServerGroupSetup rylServerGroupSetup;
|
||||
return rylServerGroupSetup;
|
||||
}
|
||||
|
||||
|
||||
CRylServerGroupSetup::CRylServerGroupSetup()
|
||||
{
|
||||
SetSetupFileName("./RylSetupServerGroup.ini");
|
||||
Load();
|
||||
}
|
||||
|
||||
CRylServerGroupSetup::~CRylServerGroupSetup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char* CRylServerGroupSetup::GetSetupString(SetupType eSetupType, unsigned long dwKey)
|
||||
{
|
||||
ServerStringMap::iterator pos;
|
||||
ServerStringMap::iterator end;
|
||||
|
||||
switch(eSetupType)
|
||||
{
|
||||
case SERVER_GROUP: pos = m_ServerGroup.find(dwKey); end = m_ServerGroup.end(); break;
|
||||
case SERVER_TYPE: pos = m_ServerType.find(dwKey); end = m_ServerType.end(); break;
|
||||
case SERVER_ZONE: pos = m_ServerZone.find(dwKey); end = m_ServerZone.end(); break;
|
||||
case SERVER_CHANNEL: pos = m_ServerChannel.find(dwKey); end = m_ServerChannel.end(); break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (pos != end) ? pos->second.c_str() : 0;
|
||||
}
|
||||
|
||||
void CRylServerGroupSetup::Load(const char* szFileName)
|
||||
{
|
||||
m_ServerGroup.clear();
|
||||
m_ServerType.clear();
|
||||
m_ServerZone.clear();
|
||||
m_ServerChannel.clear();
|
||||
|
||||
ReadRylServerStringValues(m_ServerGroup, "SERVER_GROUP", "SERVER_GROUP", szFileName);
|
||||
ReadRylServerStringValues(m_ServerType, "SERVER_TYPE", "SERVER_TYPE", szFileName);
|
||||
ReadRylServerStringValues(m_ServerZone, "GAMESERVER", "GAME_ZONE", szFileName);
|
||||
ReadRylServerStringValues(m_ServerChannel, "GENERAL", "GAME_CHANNEL", szFileName);
|
||||
}
|
||||
|
||||
|
||||
void CRylServerGroupSetup::Save(const char* szFileName)
|
||||
{
|
||||
WriteRylServerStringValues(m_ServerGroup, "SERVER_GROUP", "SERVER_GROUP", szFileName);
|
||||
WriteRylServerStringValues(m_ServerType, "SERVER_TYPE", "SERVER_TYPE", szFileName);
|
||||
WriteRylServerStringValues(m_ServerZone, "GAMESERVER", "GAME_ZONE", szFileName);
|
||||
WriteRylServerStringValues(m_ServerChannel, "GENERAL", "GAME_CHANNEL", szFileName);
|
||||
}
|
||||
|
||||
|
||||
void CRylServerGroupSetup::SetSetupFileName(const char* szFileName)
|
||||
{
|
||||
if(0 != szFileName)
|
||||
{
|
||||
_snprintf(m_szSetupFileName, MAX_PATH - 1, "%s", szFileName);
|
||||
m_szSetupFileName[MAX_PATH - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long CRylServerGroupSetup::GetStringNum(SetupType eSetupType)
|
||||
{
|
||||
switch(eSetupType)
|
||||
{
|
||||
case SERVER_GROUP: return m_ServerGroup.size();
|
||||
case SERVER_TYPE: return m_ServerType.size();
|
||||
case SERVER_ZONE: return m_ServerZone.size();
|
||||
case SERVER_CHANNEL: return m_ServerChannel.size();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ReadRylServerStringValues(CRylServerGroupSetup::ServerStringMap& serverStringMap,
|
||||
const char* szReadSection, const char* szKey, const char* szFileName)
|
||||
{
|
||||
char szNumKey[MAX_PATH];
|
||||
char szStringKey[MAX_PATH];
|
||||
char szStringValue[MAX_PATH];
|
||||
|
||||
unsigned long dwKey = 0;
|
||||
const unsigned long dwInvalidKey = 0xFFFFFFFF;
|
||||
|
||||
_snprintf(szStringKey, MAX_PATH - 1, "%s_NUM", szKey);
|
||||
UINT nNum = GetPrivateProfileInt(szReadSection, szStringKey, 0, szFileName);
|
||||
|
||||
for(UINT nIndex = 0; nIndex < nNum; ++nIndex)
|
||||
{
|
||||
_snprintf(szNumKey, MAX_PATH - 1, "%s_KEY%d", szKey, nIndex);
|
||||
_snprintf(szStringKey, MAX_PATH - 1, "%s_STRING%d", szKey, nIndex);
|
||||
|
||||
dwKey = static_cast<unsigned long>(GetPrivateProfileInt(szReadSection,
|
||||
szNumKey, dwInvalidKey, szFileName));
|
||||
|
||||
GetPrivateProfileString(szReadSection, szStringKey, "",
|
||||
szStringValue, MAX_PATH, szFileName);
|
||||
|
||||
if(dwKey != dwInvalidKey && 0 != szStringValue[0])
|
||||
{
|
||||
serverStringMap.insert(CRylServerGroupSetup::ServerStringMap::value_type(dwKey, szStringValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WriteRylServerStringValues(CRylServerGroupSetup::ServerStringMap& serverStringMap,
|
||||
const char* szReadSection, const char* szKey, const char* szFileName)
|
||||
{
|
||||
char szNumKey[MAX_PATH];
|
||||
char szNumValue[MAX_PATH];
|
||||
|
||||
char szStringKey[MAX_PATH];
|
||||
char szStringValue[MAX_PATH];
|
||||
|
||||
CRylServerGroupSetup::ServerStringMap::iterator pos = serverStringMap.begin();
|
||||
CRylServerGroupSetup::ServerStringMap::iterator end = serverStringMap.end();
|
||||
|
||||
UINT nIndex = 0;
|
||||
for(;pos != end; ++pos, ++nIndex)
|
||||
{
|
||||
CRylServerGroupSetup::ServerStringMap::value_type& value = *pos;
|
||||
|
||||
_snprintf(szNumKey, MAX_PATH - 1, "%s_KEY%d", szKey, nIndex);
|
||||
_snprintf(szStringKey, MAX_PATH - 1, "%s_STRING%d", szKey, nIndex);
|
||||
|
||||
_snprintf(szNumValue, MAX_PATH - 1, "%d", value.first);
|
||||
|
||||
WritePrivateProfileString(szReadSection, szNumKey, szNumValue, szFileName);
|
||||
WritePrivateProfileString(szReadSection, szStringKey, value.second.c_str(), szFileName);
|
||||
|
||||
}
|
||||
|
||||
_snprintf(szStringKey, MAX_PATH - 1, "%s_NUM", szKey);
|
||||
_snprintf(szStringValue, MAX_PATH - 1, "%d", serverStringMap.size());
|
||||
WritePrivateProfileString(szReadSection, szStringKey, szStringValue, szFileName);
|
||||
}
|
||||
77
Server/ManageTool/ManageLibrary/Setup/RylServerGroupSetup.h
Normal file
77
Server/ManageTool/ManageLibrary/Setup/RylServerGroupSetup.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#ifndef _RYL_SERVER_GROUP_SETUP_H_
|
||||
#define _RYL_SERVER_GROUP_SETUP_H_
|
||||
|
||||
#pragma warning(disable:4800)
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
|
||||
class CRylServerGroupSetup
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::basic_string<char, std::char_traits<char>, boost::pool_allocator<char> >
|
||||
boost_string;
|
||||
|
||||
typedef std::map<unsigned long, boost_string, std::less<unsigned long>,
|
||||
boost::pool_allocator<std::pair<unsigned long, boost_string> > >
|
||||
ServerStringMap;
|
||||
|
||||
enum SetupType
|
||||
{
|
||||
SERVER_GROUP,
|
||||
SERVER_TYPE,
|
||||
SERVER_ZONE,
|
||||
SERVER_CHANNEL
|
||||
};
|
||||
|
||||
static CRylServerGroupSetup& GetInstance();
|
||||
|
||||
const char* GetSetupString(SetupType eSetupType, unsigned long dwKey);
|
||||
unsigned long GetStringNum(SetupType eSetupType);
|
||||
|
||||
void Load(const char* szFileName = GetInstance().GetSetupFileName());
|
||||
void Save(const char* szFileName = GetInstance().GetSetupFileName());
|
||||
|
||||
void SetSetupFileName(const char* szFileName);
|
||||
const char* GetSetupFileName() { return m_szSetupFileName; }
|
||||
|
||||
template<typename FnProcess>
|
||||
void EnumSetup(SetupType eSetupType, FnProcess fnProcess)
|
||||
{
|
||||
ServerStringMap::iterator pos;
|
||||
ServerStringMap::iterator end;
|
||||
|
||||
switch(eSetupType)
|
||||
{
|
||||
case SERVER_GROUP: pos = m_ServerGroup.begin(); end = m_ServerGroup.end(); break;
|
||||
case SERVER_TYPE: pos = m_ServerType.begin(); end = m_ServerType.end(); break;
|
||||
case SERVER_ZONE: pos = m_ServerZone.begin(); end = m_ServerZone.end(); break;
|
||||
case SERVER_CHANNEL: pos = m_ServerChannel.begin(); end = m_ServerChannel.end(); break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
ServerStringMap::value_type& value = *pos;
|
||||
fnProcess(value.first, value.second.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
CRylServerGroupSetup();
|
||||
~CRylServerGroupSetup();
|
||||
|
||||
ServerStringMap m_ServerGroup;
|
||||
ServerStringMap m_ServerType;
|
||||
ServerStringMap m_ServerZone;
|
||||
ServerStringMap m_ServerChannel;
|
||||
|
||||
char m_szSetupFileName[MAX_PATH];
|
||||
};
|
||||
|
||||
#endif
|
||||
95
Server/ManageTool/ManageLibrary/Setup/SetupClient.cpp
Normal file
95
Server/ManageTool/ManageLibrary/Setup/SetupClient.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include "stdafx.h"
|
||||
#include "SetupClient.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
ManageSetup::ClientSetup::ClientSetup()
|
||||
{
|
||||
SetSetupFileName("./ManageSetupClient.ini");
|
||||
Load();
|
||||
}
|
||||
|
||||
ManageSetup::ClientSetup::~ClientSetup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ManageSetup::ClientSetup& ManageSetup::ClientSetup::GetInstance()
|
||||
{
|
||||
static ClientSetup clientSetup;
|
||||
return clientSetup;
|
||||
}
|
||||
|
||||
void ManageSetup::ClientSetup::Load(const char* szSetupFileName)
|
||||
{
|
||||
char szIP[MAX_PATH];
|
||||
GetPrivateProfileString("ManageClient", "ManageServerIP", 0, szIP, MAX_PATH, szSetupFileName);
|
||||
|
||||
UINT nPort = GetPrivateProfileInt("ManageClient", "ManageServerPort",
|
||||
CServerSetup::ManageServerManageClientListen, szSetupFileName);
|
||||
|
||||
m_ManageServerAddr.set_addr(szIP, static_cast<unsigned short>(nPort));
|
||||
}
|
||||
|
||||
|
||||
void ManageSetup::ClientSetup::Save(const char* szSetupFileName)
|
||||
{
|
||||
char szIP[MAX_PATH];
|
||||
_snprintf(szIP, MAX_PATH - 1, "%s", m_ManageServerAddr.get_addr_string());
|
||||
szIP[MAX_PATH - 1] = 0;
|
||||
|
||||
char szPort[MAX_PATH];
|
||||
_snprintf(szPort, MAX_PATH - 1, "%d", m_ManageServerAddr.get_port_in());
|
||||
szPort[MAX_PATH - 1] = 0;
|
||||
|
||||
WritePrivateProfileString("ManageClient", "ManageServerIP", szIP, szSetupFileName);
|
||||
WritePrivateProfileString("ManageClient", "ManageServerPort", szPort, szSetupFileName);
|
||||
}
|
||||
|
||||
void ManageSetup::ClientSetup::SetSetupFileName(const char* szSetupFileName)
|
||||
{
|
||||
if(0 != szSetupFileName)
|
||||
{
|
||||
_snprintf(m_szSetupFileName, MAX_PATH, "%s", szSetupFileName);
|
||||
m_szSetupFileName[MAX_PATH - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ManageSetup::ClientSetup::SerializeIn(const char* szData_In, unsigned long dwDataLen_In)
|
||||
{
|
||||
if(dwDataLen_In == GetExpectedSerializedDataSize())
|
||||
{
|
||||
int nAddrSize = 0;
|
||||
|
||||
memcpy(&m_ManageServerAddr.get_addr(), szData_In, sizeof(sockaddr));
|
||||
memcpy(&nAddrSize, szData_In + sizeof(sockaddr), sizeof(int));
|
||||
|
||||
m_ManageServerAddr.set_size(nAddrSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ManageSetup::ClientSetup::SerializeOut(char* szData_InOut, unsigned long& dwDataLen_InOut)
|
||||
{
|
||||
if(GetExpectedSerializedDataSize() < dwDataLen_InOut)
|
||||
{
|
||||
int nAddrSize = m_ManageServerAddr.get_size();
|
||||
|
||||
memcpy(szData_InOut, &m_ManageServerAddr.get_addr(), sizeof(sockaddr));
|
||||
memcpy(szData_InOut + sizeof(sockaddr), &nAddrSize, sizeof(int));
|
||||
|
||||
dwDataLen_InOut = GetExpectedSerializedDataSize();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long ManageSetup::ClientSetup::GetExpectedSerializedDataSize()
|
||||
{
|
||||
return static_cast<unsigned long>(sizeof(sockaddr) + sizeof(int));
|
||||
}
|
||||
40
Server/ManageTool/ManageLibrary/Setup/SetupClient.h
Normal file
40
Server/ManageTool/ManageLibrary/Setup/SetupClient.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef _GM_NETWORK_MANAGE_SETUP_CLIENT_H_
|
||||
#define _GM_NETWORK_MANAGE_SETUP_CLIENT_H_
|
||||
|
||||
#include <Network/Address/INET_Addr.h>
|
||||
|
||||
namespace ManageSetup
|
||||
{
|
||||
|
||||
class ClientSetup
|
||||
{
|
||||
public:
|
||||
|
||||
static ClientSetup& GetInstance();
|
||||
|
||||
bool SerializeIn(const char* szData_In, unsigned long dwDataLen_In);
|
||||
bool SerializeOut(char* szData_InOut, unsigned long& dwDataLen_InOut);
|
||||
|
||||
unsigned long GetExpectedSerializedDataSize();
|
||||
|
||||
void Load(const char* szSetupFileName = ClientSetup::GetInstance().GetSetupFileName());
|
||||
void Save(const char* szSetupFileName = ClientSetup::GetInstance().GetSetupFileName());
|
||||
|
||||
const char* GetSetupFileName() { return m_szSetupFileName; }
|
||||
void SetSetupFileName(const char* szSetupFileName);
|
||||
|
||||
INET_Addr& GetManageServerAddr() { return m_ManageServerAddr; }
|
||||
|
||||
private:
|
||||
|
||||
ClientSetup();
|
||||
~ClientSetup();
|
||||
|
||||
INET_Addr m_ManageServerAddr;
|
||||
char m_szSetupFileName[MAX_PATH];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,543 @@
|
||||
#include "stdafx.h"
|
||||
#include "ToolUserManageTable.h"
|
||||
|
||||
#include <tchar.h>
|
||||
#include <Log/ServerLog.h>
|
||||
|
||||
#include <Stream/Buffer/Buffer.h>
|
||||
#include <Stream/Buffer/BufferFactory.h>
|
||||
|
||||
#include <Network/Session/Session.h>
|
||||
#include <Network/Dispatch/SendManagePacket.h>
|
||||
#include <Network/Dispatch/ManageServer/ManageToolServerDispatch.h>
|
||||
|
||||
#include <DB/SQLite.h>
|
||||
#include <DB/ManageServerDB.h>
|
||||
#include <Setup/RylServerGroupSetup.h>
|
||||
|
||||
|
||||
CToolUserManager& CToolUserManager::GetInstance()
|
||||
{
|
||||
static CToolUserManager toolUserManager(CManageServerDB::GetInstance());
|
||||
return toolUserManager;
|
||||
}
|
||||
|
||||
|
||||
inline void SetUserInfo(ServerManage::UserInfo& UserInfo_Out,
|
||||
const char* szID, const char* szPass,
|
||||
const char* szFullName, const char* szIP,
|
||||
const char* szAdminLevel)
|
||||
{
|
||||
_snprintf(UserInfo_Out.szID, ServerManage::UserInfo::ID_LEN - 1, "%s", szID);
|
||||
UserInfo_Out.szID[ServerManage::UserInfo::ID_LEN - 1] = 0;
|
||||
|
||||
_snprintf(UserInfo_Out.szPassword, ServerManage::UserInfo::PASS_LEN - 1, "%s", szPass);
|
||||
UserInfo_Out.szPassword[ServerManage::UserInfo::PASS_LEN - 1] = 0;
|
||||
|
||||
_snprintf(UserInfo_Out.szFullName, ServerManage::UserInfo::NAME_LEN - 1, "%s", szFullName);
|
||||
UserInfo_Out.szFullName[ServerManage::UserInfo::NAME_LEN - 1] = 0;
|
||||
|
||||
UserInfo_Out.dwIP = inet_addr(szIP);
|
||||
UserInfo_Out.usAdminLevel = atoi(szAdminLevel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CToolUserManager::ToolUser::ToolUser(CManageToolServerDispatch* lpDispatch,
|
||||
ServerManage::UserInfo& userInfo)
|
||||
: m_lpDispatch(lpDispatch), m_UserInfo(userInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CToolUserManager::ToolUser::ToolUser()
|
||||
: m_lpDispatch(0)
|
||||
{
|
||||
memset(&m_UserInfo, 0, sizeof(ServerManage::UserInfo));
|
||||
}
|
||||
|
||||
|
||||
enum ToolUserConst
|
||||
{
|
||||
TOOLUSER_MAX_QUERY = 1024
|
||||
};
|
||||
|
||||
|
||||
CToolUserManager::CToolUserManager(CManageServerDB& ManageServerDB)
|
||||
: m_ManageServerDB(ManageServerDB)
|
||||
{
|
||||
memset(&m_ManageUser, 0, sizeof(ServerManage::UserInfo));
|
||||
}
|
||||
|
||||
CToolUserManager::~CToolUserManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// UserManagement
|
||||
bool CToolUserManager::AddUser(const ServerManage::UserInfo& userInfo)
|
||||
{
|
||||
char szQuery[TOOLUSER_MAX_QUERY];
|
||||
|
||||
in_addr addr;
|
||||
addr.S_un.S_addr = userInfo.dwIP;
|
||||
|
||||
int nQueryLen = _snprintf(szQuery, TOOLUSER_MAX_QUERY - 1,
|
||||
"INSERT INTO TblManageToolUser values('%s', '%s', '%s', '%s', %d)",
|
||||
userInfo.szID, userInfo.szPassword, userInfo.szFullName,
|
||||
inet_ntoa(addr), userInfo.usAdminLevel);
|
||||
|
||||
szQuery[TOOLUSER_MAX_QUERY - 1] = 0;
|
||||
|
||||
if(0 < nQueryLen)
|
||||
{
|
||||
CSQLite::Dataset addUserQuery(m_ManageServerDB.GetSQLite(), szQuery);
|
||||
|
||||
if(addUserQuery.Compile() && addUserQuery.Execute())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ERRLOG2(g_Log, "AddUser failed - query failed : %s(Query:%s)",
|
||||
addUserQuery.GetLastError(), szQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG1(g_Log, "AddUser failed - make query failed : (Query:%s)", szQuery);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CToolUserManager::GetUserInfo(const char* szID_In,
|
||||
ServerManage::UserInfo& userInfo_Out)
|
||||
{
|
||||
char szQuery[TOOLUSER_MAX_QUERY];
|
||||
|
||||
int nQueryLen = _snprintf(szQuery, TOOLUSER_MAX_QUERY - 1,
|
||||
"SELECT ID, PASS, NAME, IP, LEVEL FROM TblManageToolUser WHERE ID = '%s'", szID_In);
|
||||
|
||||
szQuery[TOOLUSER_MAX_QUERY - 1] = 0;
|
||||
|
||||
if(0 < nQueryLen)
|
||||
{
|
||||
CSQLite::Dataset getUserQuery(m_ManageServerDB.GetSQLite(), szQuery);
|
||||
|
||||
int nColNum = 0;
|
||||
const char** pazValue = 0;
|
||||
const char** pazColumn = 0;
|
||||
|
||||
if(getUserQuery.Compile() &&
|
||||
getUserQuery.Execute(&nColNum, &pazValue, &pazColumn))
|
||||
{
|
||||
if(5 == nColNum && 0 != pazValue)
|
||||
{
|
||||
SetUserInfo(userInfo_Out, pazValue[0], pazValue[1],
|
||||
pazValue[2], pazValue[3], pazValue[4]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
ERRLOG2(g_Log, "Getuser failed - query error : %s(Query:%s)",
|
||||
getUserQuery.GetLastError(), szQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG1(g_Log, "Getuser failed - create query failed : (Query:%s)", szQuery);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CToolUserManager::DelUser(const char* szID)
|
||||
{
|
||||
char szQuery[TOOLUSER_MAX_QUERY];
|
||||
|
||||
int nQueryLen = _snprintf(szQuery, TOOLUSER_MAX_QUERY - 1,
|
||||
"DELETE FROM TblManageToolUser WHERE ID = '%s'", szID);
|
||||
|
||||
szQuery[TOOLUSER_MAX_QUERY - 1] = 0;
|
||||
|
||||
if(0 < nQueryLen)
|
||||
{
|
||||
CSQLite::Dataset delUserQuery(m_ManageServerDB.GetSQLite(), szQuery);
|
||||
|
||||
if(delUserQuery.Compile() && delUserQuery.Execute())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ERRLOG2(g_Log, "Deluser failed - query error : %s(Query:%s)",
|
||||
delUserQuery.GetLastError(), szQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG1(g_Log, "Deluser failed - create query error : %s", szQuery);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CToolUserManager::ModifyUser(const ServerManage::UserInfo& modified)
|
||||
{
|
||||
char szQuery[TOOLUSER_MAX_QUERY];
|
||||
|
||||
in_addr addr;
|
||||
addr.S_un.S_addr = modified.dwIP;
|
||||
|
||||
int nQueryLen = _snprintf(szQuery, TOOLUSER_MAX_QUERY - 1,
|
||||
"UPDATE TblManageToolUser SET PASS = '%s', NAME = '%s', IP = '%s', LEVEL = %d WHERE ID = '%s'",
|
||||
modified.szPassword, modified.szFullName, inet_ntoa(addr),
|
||||
modified.usAdminLevel, modified.szID);
|
||||
|
||||
szQuery[TOOLUSER_MAX_QUERY - 1] = 0;
|
||||
|
||||
if(0 < nQueryLen)
|
||||
{
|
||||
CSQLite::Dataset modUserQuery(m_ManageServerDB.GetSQLite(), szQuery);
|
||||
|
||||
if(modUserQuery.Compile() && modUserQuery.Execute())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ERRLOG2(g_Log, "Moduser failed - query error : %s(Query:%s)",
|
||||
modUserQuery.GetLastError(), szQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERRLOG1(g_Log, "Moduser failed - create query error : %s", szQuery);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CToolUserManager::SendAllUserInfo(CSession& Session)
|
||||
{
|
||||
const int MAX_USER_INFO = (PktMaxLen - sizeof(ServerManage::UserCommand)) / sizeof(ServerManage::UserInfo);
|
||||
ServerManage::UserInfo tempUserInfo[MAX_USER_INFO];
|
||||
|
||||
CBufferFactory& bufferFactory = Session.GetPolicy().GetBufferFactory();
|
||||
const char* szQuery = "SELECT ID, PASS, NAME, IP, LEVEL FROM TblManageToolUser";
|
||||
|
||||
CSQLite::Dataset getUserQuery(m_ManageServerDB.GetSQLite(), szQuery);
|
||||
|
||||
if(getUserQuery.Compile())
|
||||
{
|
||||
int nColNum = 0;
|
||||
const char** pazValue = 0;
|
||||
const char** pazColumn = 0;
|
||||
|
||||
int nRowCount = 0;
|
||||
|
||||
while(getUserQuery.Execute(&nColNum, &pazValue, &pazColumn))
|
||||
{
|
||||
if(5 == nColNum && 0 != pazValue)
|
||||
{
|
||||
SetUserInfo(tempUserInfo[nRowCount], pazValue[0],
|
||||
pazValue[1], pazValue[2], pazValue[3], pazValue[4]);
|
||||
|
||||
memset(tempUserInfo[nRowCount].szPassword, 0,
|
||||
ServerManage::UserInfo::PASS_LEN);
|
||||
|
||||
++nRowCount;
|
||||
}
|
||||
|
||||
if(nRowCount == MAX_USER_INFO)
|
||||
{
|
||||
ServerManage::SendUserInfo(bufferFactory, &Session, tempUserInfo,
|
||||
nRowCount, ServerManage::CMD::UserList, 0);
|
||||
|
||||
nRowCount = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(0 < nRowCount)
|
||||
{
|
||||
ServerManage::SendUserInfo(bufferFactory, &Session, tempUserInfo,
|
||||
nRowCount, ServerManage::CMD::UserList, 0);
|
||||
}
|
||||
|
||||
if(0 != getUserQuery.GetLastError())
|
||||
{
|
||||
ERRLOG2(g_Log, "Getuser failed - query error : %s(Query:%s)",
|
||||
getUserQuery.GetLastError(), szQuery);
|
||||
}
|
||||
}
|
||||
else if(0 != getUserQuery.GetLastError())
|
||||
{
|
||||
ERRLOG2(g_Log, "Getuser failed - compile query failed : %s(Query:%s)",
|
||||
getUserQuery.GetLastError(), szQuery);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CToolUserManager::GetUserInfo(UserList& userList_Out)
|
||||
{
|
||||
const unsigned char MAX_USER_INFO = 100;
|
||||
ServerManage::UserInfo tempUserInfo[MAX_USER_INFO];
|
||||
const char* szQuery = "SELECT ID, PASS, NAME, IP, LEVEL FROM TblManageToolUser";
|
||||
|
||||
CSQLite::Dataset getUserQuery(m_ManageServerDB.GetSQLite(), szQuery);
|
||||
|
||||
if(getUserQuery.Compile())
|
||||
{
|
||||
int nColNum = 0;
|
||||
const char** pazValue = 0;
|
||||
const char** pazColumn = 0;
|
||||
|
||||
int nRowCount = 0;
|
||||
|
||||
while(getUserQuery.Execute(&nColNum, &pazValue, &pazColumn))
|
||||
{
|
||||
if(5 == nColNum && 0 != pazValue)
|
||||
{
|
||||
SetUserInfo(tempUserInfo[nRowCount], pazValue[0],
|
||||
pazValue[1], pazValue[2], pazValue[3], pazValue[4]);
|
||||
|
||||
++nRowCount;
|
||||
}
|
||||
|
||||
if(nRowCount == MAX_USER_INFO)
|
||||
{
|
||||
userList_Out.insert(userList_Out.end(), tempUserInfo, tempUserInfo + nRowCount);
|
||||
nRowCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 < nRowCount)
|
||||
{
|
||||
userList_Out.insert(userList_Out.end(), tempUserInfo, tempUserInfo + nRowCount);
|
||||
}
|
||||
|
||||
if(0 != getUserQuery.GetLastError())
|
||||
{
|
||||
ERRLOG2(g_Log, "Getuser failed - query error : %s(Query:%s)",
|
||||
getUserQuery.GetLastError(), szQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(0 != getUserQuery.GetLastError())
|
||||
{
|
||||
ERRLOG2(g_Log, "Getuser failed - compile query failed : %s(Query:%s)",
|
||||
getUserQuery.GetLastError(), szQuery);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Login/Logout
|
||||
ServerManage::UserCommandError CToolUserManager::Authorize(CManageToolServerDispatch& dispatch,
|
||||
ServerManage::UserInfo& userInfo_inout)
|
||||
{
|
||||
ServerManage::UserInfo foundUserInfo;
|
||||
memset(&foundUserInfo, 0, sizeof(ServerManage::UserInfo));
|
||||
|
||||
ServerManage::UserCommandError eUserCommandErr = ServerManage::NO_USER_COMMAND_ERROR;
|
||||
|
||||
int iCheck =
|
||||
GetPrivateProfileInt("SETTING", "USER_IP_CHECK", 1, CRylServerGroupSetup::GetInstance().GetSetupFileName());
|
||||
|
||||
if(IsLogin(userInfo_inout.szID))
|
||||
{
|
||||
eUserCommandErr = ServerManage::ALREADY_LOGINED;
|
||||
}
|
||||
else if(!GetUserInfo(userInfo_inout.szID, foundUserInfo))
|
||||
{
|
||||
eUserCommandErr = ServerManage::CANNOT_AUTHORIZE_NOT_USER;
|
||||
}
|
||||
else if(0 != strncmp(foundUserInfo.szPassword, userInfo_inout.szPassword,
|
||||
ServerManage::UserInfo::PASS_LEN))
|
||||
{
|
||||
eUserCommandErr = ServerManage::CANNOT_AUTHORIZE_INVALID_PASSWORD;
|
||||
}
|
||||
else if((1 == iCheck) && (foundUserInfo.dwIP != userInfo_inout.dwIP))
|
||||
{
|
||||
eUserCommandErr = ServerManage::CANNOT_AUTHORIZE_INVALID_IPADDRESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ID, Password°¡ °°´Ù. ÀÎÁõ ¼º°ø.
|
||||
Logout(foundUserInfo.szID);
|
||||
|
||||
m_LoginUserList.push_back(ToolUser(&dispatch, foundUserInfo));
|
||||
userInfo_inout = foundUserInfo;
|
||||
}
|
||||
|
||||
return eUserCommandErr;
|
||||
}
|
||||
|
||||
|
||||
bool CToolUserManager::IsLogin(const char* szName)
|
||||
{
|
||||
CurrentUserList::iterator pos = m_LoginUserList.begin();
|
||||
CurrentUserList::iterator end = m_LoginUserList.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
ToolUser& toolUser = *pos;
|
||||
|
||||
if(0 == strncmp(toolUser.m_UserInfo.szID, szName, ServerManage::UserInfo::ID_LEN))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CToolUserManager::Logout(const char* szName)
|
||||
{
|
||||
CurrentUserList::iterator pos = m_LoginUserList.begin();
|
||||
CurrentUserList::iterator end = m_LoginUserList.end();
|
||||
|
||||
int nEraseCount = 0;
|
||||
|
||||
for(; pos != end;)
|
||||
{
|
||||
ToolUser& toolUser = *pos;
|
||||
|
||||
if(0 == strncmp(toolUser.m_UserInfo.szID, szName, ServerManage::UserInfo::ID_LEN))
|
||||
{
|
||||
// Logout info¸¦ ÁØ´Ù.
|
||||
ServerManage::SendUserInfo(toolUser.m_lpDispatch->GetBufferFactory(), 0,
|
||||
&toolUser.m_UserInfo, 1, ServerManage::CMD::UserLogout, 0);
|
||||
|
||||
if(IsManageUser(toolUser.m_UserInfo))
|
||||
{
|
||||
memset(&m_ManageUser, 0, sizeof(ServerManage::UserInfo));
|
||||
|
||||
ServerManage::SendUserInfo(toolUser.m_lpDispatch->GetBufferFactory(), 0,
|
||||
&m_ManageUser, 1, ServerManage::CMD::ManagerInfo, 0);
|
||||
}
|
||||
|
||||
pos = m_LoginUserList.erase(pos);
|
||||
++nEraseCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
return (0 < nEraseCount);
|
||||
}
|
||||
|
||||
|
||||
// Send packets to all users
|
||||
bool CToolUserManager::SendToAllLoginUser(const char* szBuffer, unsigned short usBufferSize, unsigned char cCmd_In)
|
||||
{
|
||||
CurrentUserList::iterator pos = m_LoginUserList.begin();
|
||||
CurrentUserList::iterator end = m_LoginUserList.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
ToolUser& toolUser = *pos;
|
||||
CManageToolServerDispatch* lpDispatch = toolUser.m_lpDispatch;
|
||||
|
||||
if(0 != lpDispatch)
|
||||
{
|
||||
lpDispatch->GetSendStream().PutBuffer(szBuffer, usBufferSize, cCmd_In);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CToolUserManager::SendAllLoginUserInfo(CSession& Session)
|
||||
{
|
||||
const unsigned char MAX_USER_INFO = 100;
|
||||
ServerManage::UserInfo tempUserInfo[MAX_USER_INFO];
|
||||
|
||||
CBufferFactory& bufferFactory = Session.GetPolicy().GetBufferFactory();
|
||||
|
||||
CurrentUserList::iterator pos = m_LoginUserList.begin();
|
||||
CurrentUserList::iterator end = m_LoginUserList.end();
|
||||
|
||||
unsigned char cSendNum = 0;
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
tempUserInfo[cSendNum] = pos->m_UserInfo;
|
||||
memset(tempUserInfo[cSendNum].szPassword, 0, ServerManage::UserInfo::PASS_LEN);
|
||||
|
||||
++cSendNum;
|
||||
|
||||
if(cSendNum == MAX_USER_INFO)
|
||||
{
|
||||
ServerManage::SendUserInfo(bufferFactory, &Session,
|
||||
tempUserInfo, cSendNum, ServerManage::CMD::UserLogin, 0);
|
||||
|
||||
cSendNum = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 < cSendNum)
|
||||
{
|
||||
ServerManage::SendUserInfo(bufferFactory, &Session,
|
||||
tempUserInfo, cSendNum, ServerManage::CMD::UserLogin, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
CManageToolServerDispatch* CToolUserManager::GetUserDispatch(unsigned long dwIP)
|
||||
{
|
||||
CurrentUserList::iterator pos = m_LoginUserList.begin();
|
||||
CurrentUserList::iterator end = m_LoginUserList.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
ToolUser& toolUser = *pos;
|
||||
|
||||
if(toolUser.m_UserInfo.dwIP == dwIP)
|
||||
{
|
||||
return toolUser.m_lpDispatch;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CManageToolServerDispatch* CToolUserManager::GetUserDispatch(const char* szID)
|
||||
{
|
||||
CurrentUserList::iterator pos = m_LoginUserList.begin();
|
||||
CurrentUserList::iterator end = m_LoginUserList.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
ToolUser& toolUser = *pos;
|
||||
|
||||
if(0 == strncmp(toolUser.m_UserInfo.szID, szID, ServerManage::UserInfo::ID_LEN))
|
||||
{
|
||||
return toolUser.m_lpDispatch;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool CToolUserManager::IsManageUser(const ServerManage::UserInfo& UserInfo)
|
||||
{
|
||||
if(0 == strncmp(m_ManageUser.szID, UserInfo.szID, ServerManage::UserInfo::ID_LEN))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user