Initial commit: ROW Client source code

Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-29 16:24:34 +09:00
commit e067522598
5135 changed files with 1745744 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
// AutoPatchPage.cpp : 구현 파일입니다.
//
#include "stdafx.h"
#include "PatchMaker.h"
#include "AutoPatchPage.h"
// CAutoPatchPage 대화 상자입니다.
IMPLEMENT_DYNAMIC(CAutoPatchPage, CPropertyPage)
CAutoPatchPage::CAutoPatchPage()
: CPropertyPage(CAutoPatchPage::IDD)
{
}
CAutoPatchPage::~CAutoPatchPage()
{
}
void CAutoPatchPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
DDX_Control(pDX, IDC_ED_AP_ERR_CONSOLE, m_edLogErr);
DDX_Control(pDX, IDC_ED_AP_CONSOLE, m_edLogProgress);
}
BEGIN_MESSAGE_MAP(CAutoPatchPage, CPropertyPage)
END_MESSAGE_MAP()
// CAutoPatchPage 메시지 처리기입니다.

View File

@@ -0,0 +1,26 @@
#pragma once
#include "LogEdit.h"
// CAutoPatchPage 대화 상자입니다.
class CAutoPatchPage : public CPropertyPage
{
DECLARE_DYNAMIC(CAutoPatchPage)
public:
CAutoPatchPage();
virtual ~CAutoPatchPage();
// 대화 상자 데이터입니다.
enum { IDD = IDD_AUTO_PATCH };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
DECLARE_MESSAGE_MAP()
private:
CLogEdit m_edLogProgress;
CLogEdit m_edLogErr;
};

View File

@@ -0,0 +1,31 @@
// ChecksumPage.cpp : 구현 파일입니다.
//
#include "stdafx.h"
#include "PatchMaker.h"
#include "ChecksumPage.h"
// CChecksumPage 대화 상자입니다.
IMPLEMENT_DYNAMIC(CChecksumPage, CPropertyPage)
CChecksumPage::CChecksumPage()
: CPropertyPage(CChecksumPage::IDD)
{
}
CChecksumPage::~CChecksumPage()
{
}
void CChecksumPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CChecksumPage, CPropertyPage)
END_MESSAGE_MAP()
// CChecksumPage 메시지 처리기입니다.

View File

@@ -0,0 +1,21 @@
#pragma once
// CChecksumPage 대화 상자입니다.
class CChecksumPage : public CPropertyPage
{
DECLARE_DYNAMIC(CChecksumPage)
public:
CChecksumPage();
virtual ~CChecksumPage();
// 대화 상자 데이터입니다.
enum { IDD = IDD_CHECKSUM };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
DECLARE_MESSAGE_MAP()
};

View File

@@ -0,0 +1,101 @@
// LogEdit.cpp : 구현 파일입니다.
//
#include "stdafx.h"
#include "LogEdit.h"
// CLogEdit
IMPLEMENT_DYNAMIC(CLogEdit, CEdit)
CLogEdit::CLogEdit()
{
}
CLogEdit::~CLogEdit()
{
}
BEGIN_MESSAGE_MAP(CLogEdit, CEdit)
ON_WM_CHAR()
ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()
// CLogEdit 메시지 처리기입니다.
void CLogEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
// CEdit::OnChar(nChar, nRepCnt, nFlags);
}
void CLogEdit::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CEdit::OnRButtonDown(nFlags, point);
}
void CLogEdit::AddLine(LPCTSTR szLine, int nIndex, bool bNewLine)
{
m_szTempLine.SetString(szLine);
if (bNewLine) { m_szTempLine.Append("\r\n"); }
if (OpenClipboard())
{
EmptyClipboard();
BOOL bAddedLine = FALSE;
int nLength = m_szTempLine.GetLength();
HANDLE hGlobalCopy = GlobalAlloc(GMEM_MOVEABLE, (nLength + 1) * sizeof(TCHAR));
if (0 != hGlobalCopy)
{
// Lock the handle and copy the text to the buffer.
LPTSTR lptstrCopy = reinterpret_cast<LPTSTR>(GlobalLock(hGlobalCopy));
memcpy(lptstrCopy, m_szTempLine.GetString(), nLength * sizeof(TCHAR));
lptstrCopy[nLength] = _T('\0');
GlobalUnlock(hGlobalCopy);
// Place the handle on the clipboard.
if(0 != SetClipboardData(CF_TEXT, hGlobalCopy))
{
bAddedLine = TRUE;
}
else
{
GlobalFree(hGlobalCopy);
}
}
CloseClipboard();
if (bAddedLine)
{
int nCharPos = 0;
int nLinePos = 0;
if (-1 == nIndex || -1 == (nCharPos = LineIndex(nIndex)))
{
// 맨 마지막 라인에 추가
nLinePos = GetLineCount();
nCharPos = GetWindowTextLength();
SetSel(nCharPos, nCharPos);
}
else
{
// 현재 라인에 추가
SetSel(nCharPos, nCharPos);
nLinePos = LineFromChar(nCharPos);
}
Paste();
LineScroll(nLinePos);
}
}
}

View File

@@ -0,0 +1,29 @@
#pragma once
// CLogEdit
class CLogEdit : public CEdit
{
DECLARE_DYNAMIC(CLogEdit)
public:
CLogEdit();
virtual ~CLogEdit();
protected:
DECLARE_MESSAGE_MAP()
public:
void AddLine(LPCTSTR szLine, int nIndex = -1, bool bNewLine = true);
void Clear() { SetWindowText(""); }
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
protected:
CString m_szTempLine;
};

View File

@@ -0,0 +1,768 @@
// ManualPatchPage.cpp : 구현 파일입니다.
//
#include "stdafx.h"
#include "PatchMaker.h"
#include "ManualPatchPage.h"
#include "UtilityFunc.h"
#include "PMSetting.h"
#include "PMSettingConstant.h"
#include "atlenc.h"
#include <process.h>
#include <ZipArchive.h>
#include ".\manualpatchpage.h"
// CManualPatchPage 대화 상자입니다.
IMPLEMENT_DYNAMIC(CManualPatchPage, CPropertyPage)
CManualPatchPage::CManualPatchPage(CPMSetting& pmSetting, DWORD dwPatchVersion)
: CPropertyPage(CManualPatchPage::IDD)
, m_szMPFolder(_T(""))
, m_szMPSFXFile(_T(""))
, m_szMPFileName(_T(""))
, m_dwMPMinver(0)
, m_dwMPMaxver(dwPatchVersion)
, m_szPatchType(_T(""))
, m_szFileProgress(_T("0/0"))
, m_pmSettingOption(pmSetting)
, m_hManualPatchThread(0)
{
m_ProgressData.m_bStopWorkerThread = FALSE;
m_ProgressData.m_nTotalFiles = 0;
m_ProgressData.m_nAddedFiles = 0;
m_ProgressData.m_dwTotalFileSize = 0LL;
m_ProgressData.m_dwCurrentFileSize = 0LL;
}
CManualPatchPage::~CManualPatchPage()
{
}
void CManualPatchPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
DDX_Text(pDX, IDC_ED_MP_MANUAL_PATCH_FILE, m_szMPFolder);
DDX_Text(pDX, IDC_ED_MP_MANUAL_SFX_FILE, m_szMPSFXFile);
DDX_Text(pDX, IDC_ED_MP_PATCH_FILE_NAME, m_szMPFileName);
DDX_Text(pDX, IDC_ED_MP_MIN_VER, m_dwMPMinver);
DDX_Text(pDX, IDC_ED_MP_CUR_VER, m_dwMPMaxver);
DDX_Text(pDX, IDC_ED_MP_PATCH_TYPE, m_szPatchType);
DDX_Control(pDX, IDC_ED_MP_CONSOLE, m_edProgressLog);
DDX_Control(pDX, IDC_PRG_MP, m_TotalProgressBar);
DDX_Control(pDX, IDC_ED_MP_ERR_CONSOLE, m_edErrLog);
DDX_Text(pDX, IDC_ST_MP_PRORGRESS, m_szFileProgress);
}
BEGIN_MESSAGE_MAP(CManualPatchPage, CPropertyPage)
ON_BN_CLICKED(ID_MP_CREATE, OnBnClickedMpCreate)
ON_BN_CLICKED(ID_MP_CANCEL, OnBnClickedMpCancel)
ON_BN_CLICKED(IDC_BTN_MP_SELECT_FILE, OnBnClickedBtnMpSelectFile)
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_CLEAR_LOG, OnBnClickedClearLog)
END_MESSAGE_MAP()
// CManualPatchPage 메시지 처리기입니다.
struct MPWorkerData
{
CManualPatchPage* m_lpPage;
CString m_szMPFolder;
CString m_szMPSFXFile;
CString m_szMPFileName;
CString m_szPatchType;
DWORD m_dwMPMaxver;
DWORD m_dwMPMinver;
};
void CManualPatchPage::UpdateManualPatchStatus(MPProgressData& progressData)
{
//! MANUAL_PATCH_LOCK
m_ProgressLock.Lock();
// 데이터를 갱신한다
progressData.m_bStopWorkerThread = m_ProgressData.m_bStopWorkerThread;
m_ProgressData.m_nTotalFiles = progressData.m_nTotalFiles;
m_ProgressData.m_nAddedFiles = progressData.m_nAddedFiles;
m_ProgressData.m_dwCurrentFileSize = progressData.m_dwCurrentFileSize;
m_ProgressData.m_dwTotalFileSize = progressData.m_dwTotalFileSize;
m_ProgressData.m_ProgressList.AddTail(&progressData.m_ProgressList);
m_ProgressData.m_ErrorList.AddTail(&progressData.m_ErrorList);
m_ProgressData.m_TotalProgressList.AddTail((&progressData.m_TotalProgressList));
//! MANUAL_PATCH_UNLOCK
m_ProgressLock.Unlock();
progressData.m_ProgressList.RemoveAll();
progressData.m_ErrorList.RemoveAll();
}
template<class FnProcess>
bool EnumerateAllLeafFiles(FnProcess fnProcess, LPCTSTR lpRootPath)
{
CString szTemp;
CList<CString> dirStack;
CFileFind fileFind;
szTemp.SetString(lpRootPath);
szTemp.Trim();
int nLength = szTemp.GetLength();
// 뒤에 \\*.* 혹은 *.*를 붙여 준다.
szTemp.Append(
(1 < nLength && _T('\\') != szTemp.GetString()[nLength - 1])
? _T("\\*.*") : _T("*.*"));
dirStack.AddTail(szTemp);
BOOL bWorking = FALSE;
while(!dirStack.IsEmpty())
{
szTemp.SetString(dirStack.RemoveTail());
if (bWorking = fileFind.FindFile(szTemp))
{
while(bWorking)
{
bWorking = fileFind.FindNextFile();
if (!fileFind.IsDots())
{
szTemp.SetString(fileFind.GetFilePath());
if (fileFind.IsDirectory())
{
// 폴더인 경우
szTemp.Append(_T("\\*.*"));
dirStack.AddTail(szTemp);
}
// vssver.scc는 포함 안 함
else if(0 != szTemp.CompareNoCase(_T("vssver.scc")) && !fnProcess(fileFind))
{
// 작업을 취소하였음
return false;
}
}
}
}
else
{
return false;
}
}
return true;
}
class CGetTotalFileNumAndSize
{
public:
CGetTotalFileNumAndSize(ULONGLONG& dwTotalFileSize, int& nTotalFileNum)
: m_dwTotalFileSize(dwTotalFileSize)
, m_nTotalFileNum(nTotalFileNum)
{
}
bool operator () (const CFileFind& fileFind)
{
m_dwTotalFileSize += fileFind.GetLength();
++m_nTotalFileNum;
return true;
}
private:
ULONGLONG& m_dwTotalFileSize;
int& m_nTotalFileNum;
};
class CCompressFiles
{
public:
CCompressFiles(
CManualPatchPage& mpPage,
MPProgressData& progressData,
CZipArchive& zipArchive,
CString& szErrorString)
: m_MPPage(mpPage)
, m_ProgressData(progressData)
, m_ZipArchive(zipArchive)
, m_szErrorString(szErrorString)
{
}
bool operator () (const CFileFind& fileFind)
{
// 파일을 압축해서 추가한다.
m_szFileName = fileFind.GetFilePath();
// 파일 속성을 기본 속성으로 바꿈
SetFileAttributes(m_szFileName, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE);
if (m_ZipArchive.AddNewFile(m_szFileName, Z_BEST_COMPRESSION, false))
{
// 데이터를 갱신한다.
ULONGLONG dwFileSize = fileFind.GetLength();
m_ProgressData.m_dwCurrentFileSize += dwFileSize;
++m_ProgressData.m_nAddedFiles;
PMUtil::SetCurrentTime(m_szErrorString);
m_szErrorString.AppendFormat(_T("파일 추가 : %s"), m_szFileName);
m_ProgressData.m_ProgressList.AddTail(m_szErrorString);
}
else
{
// 에러 로그를 남긴다.
DWORD dwError = GetLastError();
PMUtil::SetCurrentTime(m_szErrorString);
m_szErrorString.AppendFormat(_T("작업 실패 : %s : "), m_szFileName);
PMUtil::AppendErrorMessage(m_szErrorString, dwError);
m_ProgressData.m_ErrorList.AddTail(m_szErrorString);
}
// 데이터를 업데이트한다.
m_MPPage.UpdateManualPatchStatus(m_ProgressData);
return (FALSE == m_ProgressData.m_bStopWorkerThread);
}
private:
CManualPatchPage& m_MPPage;
MPProgressData& m_ProgressData;
CZipArchive& m_ZipArchive;
CString& m_szErrorString;
CString m_szFileName;
};
unsigned __stdcall CManualPatchPage::ManualPatchWorker(void* pArg)
{
MPWorkerData* lpWorkerData = reinterpret_cast<MPWorkerData*>(pArg);
CManualPatchPage* lpPage = lpWorkerData->m_lpPage;
// 데이터 정의
CZipArchive zipArchive;
CString szSFXFileName;
CString szZipFileName;
CString szErrorString;
const int MAX_ERROR_LEN = 256;
TCHAR szErrorMsg[MAX_ERROR_LEN];
MPProgressData progressData;
progressData.m_bStopWorkerThread = FALSE;
progressData.m_dwTotalFileSize = 0LL;
progressData.m_dwCurrentFileSize = 0LL;
progressData.m_nTotalFiles = 0;
progressData.m_nAddedFiles = 0;
szSFXFileName.SetString(lpWorkerData->m_szMPFileName);
szZipFileName.SetString(lpWorkerData->m_szMPFileName);
int nPos = szZipFileName.ReverseFind(_T('.'));
if (0 < nPos) { szZipFileName.Truncate(nPos); szZipFileName.Append(_T(".zip"), nPos); }
// 전체 파일 개수 및 파일 용량을 계산한다.
if (!EnumerateAllLeafFiles(CGetTotalFileNumAndSize(
progressData.m_dwTotalFileSize, progressData.m_nTotalFiles), lpWorkerData->m_szMPFolder))
{
DWORD dwError = GetLastError();
PMUtil::SetCurrentTime(szErrorString);
if (progressData.m_bStopWorkerThread)
{
szErrorString.AppendFormat(_T("작업 실패 : 작업을 취소하였습니다"));
}
else
{
szErrorString.AppendFormat(_T("작업 실패 : 압축할 파일을 찾을 수 없습니다 : "));
PMUtil::AppendErrorMessage(szErrorString, dwError);
}
progressData.m_ErrorList.AddTail(szErrorString);
progressData.m_TotalProgressList.AddTail(szErrorString);
}
else
{
TRY
{
bool bSucceededJob = false;
zipArchive.Open(szZipFileName, CZipArchive::zipCreate);
zipArchive.SetRootPath(lpWorkerData->m_szMPFolder);
// 파일을 추가/압축한다. 에러 로그는 내부에서 남긴다.
if (!EnumerateAllLeafFiles(
CCompressFiles(*lpPage, progressData, zipArchive, szErrorString),
lpWorkerData->m_szMPFolder))
{
DWORD dwError = GetLastError();
PMUtil::SetCurrentTime(szErrorString);
if (progressData.m_bStopWorkerThread)
{
szErrorString.AppendFormat(_T("작업 실패 : 작업을 취소하였습니다"));
}
else
{
szErrorString.AppendFormat(_T("작업 실패 : 압축할 파일을 찾을 수 없습니다 : "));
PMUtil::AppendErrorMessage(szErrorString, dwError);
}
progressData.m_ErrorList.AddTail(szErrorString);
progressData.m_TotalProgressList.AddTail(szErrorString);
}
else
{
/*
TODO : 필요한 데이터를 추리고, BASE64인코딩을 한 후 Comment에 쑤셔 박는다.
필요 데이터
1. 압축 전 용량 : 디스크 용량 체크
2. 최소버전 : 깔릴 위치에 클라이언트가 있다면, 최소버전을 체크한다.
3. 패치버전 : 깔릴 위치에 클라이언트가 있다면, 현재 버전을 체크해서 더 높은가 확인한다.
4. 기본으로 읽어올 레지스트리 위치
*/
CMemFile srcData;
srcData.Write(&progressData.m_dwTotalFileSize, sizeof(progressData.m_dwTotalFileSize));
// 패치 타입에 따라서 버전을 다시 세팅.
PMConst::AdjustVersionInfoByPatchType(lpWorkerData->m_szPatchType,
lpWorkerData->m_dwMPMinver, lpWorkerData->m_dwMPMaxver);
srcData.Write(&lpWorkerData->m_dwMPMinver, sizeof(lpWorkerData->m_dwMPMinver));
srcData.Write(&lpWorkerData->m_dwMPMaxver, sizeof(lpWorkerData->m_dwMPMaxver));
int nInstalledPathLen = 0;
int nValueNameLen = 0;
CString szInstalledPath, szValueName;
if (PMConst::GetRYLInstalledRegKey(
lpWorkerData->m_szPatchType, szInstalledPath, szValueName))
{
nInstalledPathLen = szInstalledPath.GetLength();
nValueNameLen = szValueName.GetLength();
srcData.Write(&nInstalledPathLen, sizeof(nInstalledPathLen));
srcData.Write(&nValueNameLen, sizeof(nValueNameLen));
srcData.Write(szInstalledPath.GetString(), nInstalledPathLen * sizeof(TCHAR));
srcData.Write(szValueName.GetString(), nValueNameLen * sizeof(TCHAR));
}
else
{
srcData.Write(&nInstalledPathLen, sizeof(nInstalledPathLen));
srcData.Write(&nValueNameLen, sizeof(nValueNameLen));
}
int nSrcLen = static_cast<int>(srcData.GetLength());
int nDstLen = Base64EncodeGetRequiredLength(nSrcLen);
LPSTR lpEncodedData = (LPSTR)malloc(sizeof(CHAR) * (nDstLen + 1));
if (0 != lpEncodedData)
{
BYTE* lpSrcData = srcData.Detach();
if (Base64Encode(lpSrcData, nSrcLen, lpEncodedData, &nDstLen))
{
lpEncodedData[nDstLen] = (CHAR)0;
bSucceededJob =
zipArchive.SetGlobalComment(lpEncodedData);
}
free(lpSrcData);
free(lpEncodedData);
}
}
zipArchive.Close();
if (!progressData.m_bStopWorkerThread)
{
PMUtil::SetCurrentTime(szErrorString);
szErrorString.AppendFormat(_T("수동패치 작업 : 압축을 완료하였습니다. SFX파일을 생성하는 중입니다.."));
progressData.m_ProgressList.AddTail(szErrorString);
lpPage->UpdateManualPatchStatus(progressData);
if (!bSucceededJob)
{
PMUtil::SetCurrentTime(szErrorString);
szErrorString.AppendFormat(_T("수동패치 작업 실패 : 수동패치 데이터를 Comment로 남기는 데 실패했습니다"));
progressData.m_ErrorList.AddTail(szErrorString);
}
else
{
// SFX헤더를 붙여서 파일을 하나 더 만든다.
CFile sfxFile, zipFile, resultFile;
PMUtil::SetCurrentTime(szErrorString);
if (!sfxFile.Open(lpWorkerData->m_szMPSFXFile,
CFile::modeRead | CFile::shareDenyWrite | CFile::typeBinary))
{
szErrorString.AppendFormat(_T("수동패치 작업 실패 : SFX파일 %s를 읽기 위해 여는 데 실패했습니다"),
lpWorkerData->m_szMPSFXFile);
}
else if(!zipFile.Open(szZipFileName,
CFile::modeRead | CFile::shareDenyWrite | CFile::typeBinary))
{
szErrorString.AppendFormat(
_T("수동패치 작업 실패 : ZIP파일 %s를 읽기 위해 여는 데 실패했습니다"), szZipFileName);
}
else if(!resultFile.Open(szSFXFileName,
CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite | CFile::typeBinary))
{
szErrorString.AppendFormat(
_T("수동패치 작업 실패 : 수동패치 파일 %s를 쓰기 위해 여는 데 실패했습니다"), szSFXFileName);
}
else
{
const int MAX_FILE_BUFFER = 8192;
char szTempBuffer[MAX_FILE_BUFFER];
UINT nReadBytes = 0;
UINT nCount = 0;
progressData.m_dwTotalFileSize =
sfxFile.GetLength() + zipFile.GetLength();
progressData.m_dwCurrentFileSize = 0;
lpPage->UpdateManualPatchStatus(progressData);
// 프로그리스 바를 확실히 갱신할 수 있도록 잠시 기다려 준다.
Sleep(300);
// 수동패치 파일에 SFX실행부 붙임
while(0 < (nReadBytes = sfxFile.Read(szTempBuffer, MAX_FILE_BUFFER)))
{
resultFile.Write(szTempBuffer, nReadBytes);
progressData.m_dwCurrentFileSize += nReadBytes;
if (0 == (++nCount % 10)) { lpPage->UpdateManualPatchStatus(progressData); }
}
// 수동패치 파일에 ZIP파일 붙임
while(0 < (nReadBytes = zipFile.Read(szTempBuffer, MAX_FILE_BUFFER)))
{
resultFile.Write(szTempBuffer, nReadBytes);
progressData.m_dwCurrentFileSize += nReadBytes;
if (0 == (++nCount % 10)) { lpPage->UpdateManualPatchStatus(progressData); }
}
szErrorString.Empty();
}
if (!szErrorString.IsEmpty())
{
progressData.m_ErrorList.AddTail(szErrorString);
lpPage->UpdateManualPatchStatus(progressData);
}
}
PMUtil::SetCurrentTime(szErrorString);
szErrorString.AppendFormat(_T("수동패치 작업 완료 : %d 개 파일 중 %d개를 완료하였습니다. 작업을 %s하였습니다"),
progressData.m_nTotalFiles, progressData.m_nAddedFiles,
bSucceededJob && progressData.m_nTotalFiles == progressData.m_nAddedFiles ? _T("성공") : _T("실패"));
progressData.m_ProgressList.AddTail(szErrorString);
progressData.m_TotalProgressList.AddTail(szErrorString);
}
}
CATCH_ALL(e)
{
e->GetErrorMessage(szErrorMsg, MAX_ERROR_LEN - 1);
szErrorMsg[MAX_ERROR_LEN - 1] = 0;
PMUtil::SetCurrentTime(szErrorString);
if (e->IsKindOf(RUNTIME_CLASS(CZipException)))
{
szErrorString.AppendFormat(
_T("작업 실패 : CZipArchive 라이브러리에서 에러가 발생했습니다. %s"), szErrorMsg);
}
else if (e->IsKindOf(RUNTIME_CLASS(CFileException)))
{
szErrorString.AppendFormat(
_T("작업 실패 : 파일 관련 작업에서 에러가 발생했습니다. %s"), szErrorMsg);
}
else
{
szErrorString.AppendFormat(
_T("작업 실패 : 알 수 없는 작업에서 에러가 발생했습니다. %s"), szErrorMsg);
}
progressData.m_ErrorList.AddTail(szErrorString);
progressData.m_TotalProgressList.AddTail(szErrorString);
e->Delete();
}
END_CATCH_ALL
}
// 데이터를 업데이트한다.
lpPage->UpdateManualPatchStatus(progressData);
delete lpWorkerData;
return 0;
}
void CManualPatchPage::OnBnClickedMpCreate()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
CFile file;
if (0 == m_szMPFileName.GetLength() ||
!file.Open(m_szMPFileName, CFile::modeCreate))
{
MessageBox(_T("수동패치 파일 이름이 없거나, 올바른 파일 이름이 아닙니다. 다시 입력해주세요"),
_T("올바르지 않은 파일 이름"), MB_OK | MB_ICONERROR);
}
else
{
file.Close();
DeleteFile(m_szMPFileName);
if (!theApp.IsManualPatchOperate())
{
MPWorkerData* lpWorkerData = new MPWorkerData;
if (lpWorkerData)
{
lpWorkerData->m_lpPage = this;
lpWorkerData->m_szMPFolder.SetString(m_szMPFolder);
lpWorkerData->m_szMPSFXFile.SetString(m_szMPSFXFile);
lpWorkerData->m_szMPFileName.SetString(m_szMPFileName);
lpWorkerData->m_szPatchType.SetString(m_szPatchType);
lpWorkerData->m_dwMPMaxver = m_dwMPMaxver;
lpWorkerData->m_dwMPMinver = m_dwMPMinver;
InitMPWorkerData();
unsigned int nThreadID = 0;
m_hManualPatchThread = reinterpret_cast<HANDLE>(
_beginthreadex(0, 0, ManualPatchWorker, lpWorkerData, 0, &nThreadID));
if (0 == m_hManualPatchThread)
{
MessageBox(_T("수동패치 스레드를 생성할 수 없습니다"),
_T("생성 에러"), MB_OK | MB_ICONERROR);
}
else
{
static UINT nManualPatchDlgItems[] =
{
ID_MP_CREATE,
IDC_ED_MP_PATCH_FILE_NAME,
IDC_BTN_MP_SELECT_FILE
};
PMUtil::EnableDlgItems(*this, nManualPatchDlgItems,
sizeof(nManualPatchDlgItems)/sizeof(UINT), false);
CWnd* lpWnd = GetDlgItem(ID_MP_CANCEL);
if (lpWnd) { lpWnd->EnableWindow(TRUE); }
// 프로그리스 바 출력을 위한 타이머를 돌린다.
SetTimer(PMConst::MP_PROGRESS_TIMER_ID,
PMConst::PROGRESS_TIMER_UPDATE_TIME, 0);
// 수동패치가 돌고 있다고 설정한다.
theApp.SetManualPatchOperate(true);
}
}
}
}
}
void CManualPatchPage::OnBnClickedMpCancel()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
if (theApp.IsManualPatchOperate())
{
// 이미 스레드가 작동하고 있다면, 스레드를 취소하도록 변수를 세팅한다.
StopWorker();
}
}
void CManualPatchPage::OnBnClickedBtnMpSelectFile()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
PMUtil::BrowseForNewFile(GetSafeHwnd(),
_T("수동패치 파일 이름을 선택해주세요"),
_T("Manual Patch File\0*.exe"), _T("exe"), m_szMPFileName);
UpdateData(FALSE);
}
BOOL CManualPatchPage::OnSetActive()
{
// TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
// 데이터를 셋업에서 읽어옵니다.
if (!theApp.IsManualPatchOperate())
{
// 스레드가 동작중이 아닌 경우에만 데이터를 갱신합니다.
m_pmSettingOption.GetSettingData(PMConst::PatchType, m_szPatchType);
m_pmSettingOption.GetSettingData(PMConst::MP_Folder, m_szMPFolder);
m_pmSettingOption.GetSettingData(PMConst::MP_SFXFile, m_szMPSFXFile);
CString szValue;
m_pmSettingOption.GetSettingData(PMConst::MP_MinVer, szValue);
m_dwMPMinver = atol(szValue);
UpdateData(FALSE);
}
return CPropertyPage::OnSetActive();
}
BOOL CManualPatchPage::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: 여기에 추가 초기화 작업을 추가합니다.
// Cancel버튼은 처음에는 Disable한다.
CWnd* lpWnd = GetDlgItem(ID_MP_CANCEL);
if (lpWnd) { lpWnd->EnableWindow(FALSE); }
m_edProgressLog.SetLimitText(UINT_MAX);
m_edErrLog.SetLimitText(UINT_MAX);
return TRUE; // return TRUE unless you set the focus to a control
// 예외: OCX 속성 페이지는 FALSE를 반환해야 합니다.
}
afx_msg void CManualPatchPage::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == PMConst::MP_PROGRESS_TIMER_ID)
{
int nLowerRange = 0;
int nUpperRange = 0;
int nCurrentPos = m_TotalProgressBar.GetPos();
m_TotalProgressBar.GetRange(nLowerRange, nUpperRange);
//! MANUAL_PATCH_LOCK
m_ProgressLock.Lock();
if (m_ProgressData.m_dwTotalFileSize != nUpperRange)
{
// 전체 Range가 변경되면 갱신한다 - 2.1기가 이상을 수동패치 할 일은 없다;;
m_TotalProgressBar.SetRange32(0,
static_cast<int>(m_ProgressData.m_dwTotalFileSize));
}
if (m_ProgressData.m_dwCurrentFileSize != nCurrentPos)
{
// 파일 위치가 변경되면 갱신한다.
m_TotalProgressBar.SetPos(
static_cast<int>(m_ProgressData.m_dwCurrentFileSize));
}
m_szFileProgress.Format(_T("%d/%d"),
m_ProgressData.m_nAddedFiles, m_ProgressData.m_nTotalFiles);
// 로그를 출력한다.
POSITION pos = m_ProgressData.m_ProgressList.GetHeadPosition();
while(0 != pos) { m_edProgressLog.AddLine(m_ProgressData.m_ProgressList.GetNext(pos)); }
pos = m_ProgressData.m_TotalProgressList.GetHeadPosition();
while(0 != pos) { theApp.AddTotalProgressLog(m_ProgressData.m_TotalProgressList.GetNext(pos)); }
pos = m_ProgressData.m_ErrorList.GetHeadPosition();
while(0 != pos) { m_edErrLog.AddLine(m_ProgressData.m_ErrorList.GetNext(pos)); }
m_ProgressData.m_ProgressList.RemoveAll();
m_ProgressData.m_TotalProgressList.RemoveAll();
m_ProgressData.m_ErrorList.RemoveAll();
//! MANUAL_PATCH_UNLOCK
m_ProgressLock.Unlock();
UpdateData(FALSE);
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hManualPatchThread, 0))
{
// 스레드가 종료되었다. 타이머를 제거하고, 다시 수동패치 옵션을 Enable한다.
StopWorker();
}
}
}
void CManualPatchPage::InitMPWorkerData()
{
m_hManualPatchThread = 0;
m_ProgressData.m_bStopWorkerThread = FALSE;
m_ProgressData.m_nTotalFiles = 0;
m_ProgressData.m_nAddedFiles = 0;
m_ProgressData.m_ProgressList.RemoveAll();
m_ProgressData.m_ErrorList.RemoveAll();
}
void CManualPatchPage::StopWorker()
{
if (0 != m_hManualPatchThread)
{
m_ProgressLock.Lock(); //! MANUAL_PATCH_LOCK
m_ProgressData.m_bStopWorkerThread = TRUE;
m_ProgressLock.Unlock(); //! MANUAL_PATCH_UNLOCK
WaitForSingleObject(m_hManualPatchThread, INFINITE);
CloseHandle(m_hManualPatchThread);
KillTimer(PMConst::MP_PROGRESS_TIMER_ID);
InitMPWorkerData();
static UINT nManualPatchDlgItems[] =
{
ID_MP_CREATE,
IDC_ED_MP_PATCH_FILE_NAME,
IDC_BTN_MP_SELECT_FILE
};
PMUtil::EnableDlgItems(*this, nManualPatchDlgItems,
sizeof(nManualPatchDlgItems)/sizeof(UINT), true);
CWnd* lpWnd = GetDlgItem(ID_MP_CANCEL);
if (lpWnd) { lpWnd->EnableWindow(FALSE); }
theApp.SetManualPatchOperate(false);
}
}
void CManualPatchPage::OnClose()
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
StopWorker();
CPropertyPage::OnClose();
}
void CManualPatchPage::OnBnClickedClearLog()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
m_edProgressLog.SetWindowText(_T(""));
m_edErrLog.SetWindowText(_T(""));
}

View File

@@ -0,0 +1,85 @@
#pragma once
#include "logedit.h"
#include "afxcmn.h"
#include "afxmt.h"
// CManualPatchPage 대화 상자입니다.
class CPMSetting;
struct MPProgressData
{
CList<CString> m_ProgressList;
CList<CString> m_ErrorList;
CList<CString> m_TotalProgressList;
ULONGLONG m_dwTotalFileSize;
ULONGLONG m_dwCurrentFileSize;
int m_nTotalFiles;
int m_nAddedFiles;
BOOL m_bStopWorkerThread;
};
class CManualPatchPage : public CPropertyPage
{
DECLARE_DYNAMIC(CManualPatchPage)
public:
CManualPatchPage(CPMSetting& pmSetting, DWORD dwPatchVersion);
virtual ~CManualPatchPage();
// 대화 상자 데이터입니다.
enum { IDD = IDD_MANUAL_PATCH };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
DECLARE_MESSAGE_MAP()
public:
// 패치 상태를 업데이트한다.
void UpdateManualPatchStatus(MPProgressData& progressData);
private:
// 패치 작업 스레드
static unsigned __stdcall ManualPatchWorker(void* pArg);
// 패치 작업 스레드 관련 함수
void InitMPWorkerData();
void StopWorker();
// 이벤트 처리 함수들
afx_msg void OnBnClickedMpCreate();
afx_msg void OnBnClickedMpCancel();
afx_msg void OnBnClickedBtnMpSelectFile();
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnBnClickedClearLog();
virtual BOOL OnInitDialog();
virtual BOOL OnSetActive();
afx_msg void OnClose();
CPMSetting& m_pmSettingOption;
CString m_szMPFolder;
CString m_szMPSFXFile;
CString m_szMPFileName;
CString m_szPatchType;
CLogEdit m_edProgressLog;
CLogEdit m_edErrLog;
DWORD m_dwMPMaxver;
DWORD m_dwMPMinver;
HANDLE m_hManualPatchThread;
CString m_szFileProgress;
CProgressCtrl m_TotalProgressBar;
// 크리티컬 섹션으로 보호되는 부분.
CCriticalSection m_ProgressLock;
MPProgressData m_ProgressData;
};

View File

@@ -0,0 +1,115 @@
// SettingOptionPage.cpp : 구현 파일입니다.
//
#include "stdafx.h"
#include "PMSetting.h"
CPMSetting::CPMSetting()
: m_szSetupFileName(_T(""))
{
}
CPMSetting::~CPMSetting()
{
m_SetupDataMap.RemoveAll();
}
bool CPMSetting::SaveSetting()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
CStdioFile setupFile;
if (setupFile.Open(m_szSetupFileName, CFile::modeWrite | CFile::typeText))
{
CString szLine;
CString szKey;
CString szValue;
for (POSITION pos = m_SetupDataMap.GetStartPosition(); pos != NULL; )
{
m_SetupDataMap.GetNextAssoc(pos, szKey, szValue);
szLine.Format("%s = %s\n", szKey, szValue);
setupFile.WriteString(szLine);
}
setupFile.Close();
return true;
}
return false;
}
bool CPMSetting::LoadSetting(LPCTSTR szSetupFileName)
{
m_SetupDataMap.RemoveAll();
m_szSetupFileName.SetString(szSetupFileName);
CStdioFile setupFile;
if (setupFile.Open(m_szSetupFileName,
CFile::modeCreate | CFile::modeNoTruncate | CFile::modeRead | CFile::shareDenyNone | CFile::typeText))
{
CString szLine;
CString szKey;
CString szValue;
LPCTSTR szSeps = _T("=\t\r\n");
while(setupFile.ReadString(szLine))
{
// 세팅을 한줄한줄 읽어서 넣는다.
int nTokenPos = 0;
if (0 != szLine.Compare(_T("")))
{
szKey = szLine.Tokenize(szSeps, nTokenPos);
if (0 < nTokenPos)
{
szValue = szLine.Tokenize(szSeps, nTokenPos);
if (0 != szKey.Compare(_T("")) && 0 != szValue.Compare(_T("")))
{
szKey.Trim();
szValue.Trim();
szKey.MakeUpper();
m_SetupDataMap.SetAt(szKey, szValue);
}
}
}
}
setupFile.Close();
return true;
}
return false;
}
bool CPMSetting::GetSettingData(LPCTSTR szKey, CString& szValue)
{
CString szKeyString(szKey);
szKeyString.MakeUpper();
return (TRUE == m_SetupDataMap.Lookup(szKeyString, szValue)) ? true : false;
}
void CPMSetting::SetSettingData(LPCTSTR szKey, LPCTSTR szValue)
{
CString szKeyString(szKey);
szKeyString.MakeUpper();
m_SetupDataMap.SetAt(szKeyString, szValue);
}
CPMSetting& CPMDefaultSetting::GetInstance()
{
static CPMSetting pmSetting;
return pmSetting;
}
LPCTSTR CPMDefaultSetting::GetDefaultSettingName()
{
return _T("PatchMaker.cfg");
}

View File

@@ -0,0 +1,38 @@
#pragma once
class CPMSetting
{
public:
CPMSetting();
virtual ~CPMSetting();
bool LoadSetting(LPCTSTR szSetupFileName);
bool LoadSetting() { return LoadSetting(GetSettingFileName()); }
bool SaveSetting();
LPCTSTR GetSettingFileName() const { return m_szSetupFileName.GetString(); }
bool GetSettingData(LPCTSTR szKey, CString& szValue);
void SetSettingData(LPCTSTR szKey, LPCTSTR szValue);
private:
CMapStringToString m_SetupDataMap;
CString m_szSetupFileName;
};
class CPMDefaultSetting : public CPMSetting
{
public:
static CPMSetting& GetInstance();
static LPCTSTR GetDefaultSettingName();
private:
CPMDefaultSetting() { }
virtual ~CPMDefaultSetting() { }
};

View File

@@ -0,0 +1,89 @@
#include "stdafx.h"
#include "resource.h"
namespace PMConst
{
// 패치 타입
LPCTSTR PatchType = _T("PATCH_TYPE");
CString PatchType_Part1;
CString PatchType_BattleLohan;
CString PatchType_Part2;
CString PatchType_Part2Test;
CString PatchType_Part2Malay;
// 자동패치
LPCTSTR AP_OldPkg = _T("AP_OLD_PKG");
LPCTSTR AP_NewClient = _T("AP_NEW_CLIENT");
LPCTSTR AP_NewPkg = _T("AP_NEW_PKG");
LPCTSTR AP_MaxPkg = _T("AP_MAX_PKG");
LPCTSTR AP_FTPAddr = _T("AP_FTP_ADDR");
LPCTSTR AP_FTPPort = _T("AP_FTP_PORT");
LPCTSTR AP_FTPPassive = _T("AP_IS_PASSIVE");
LPCTSTR AP_PkgPosType = _T("AP_PKG_POS_TYPE");
UINT AP_SETTING_ENABLE = RegisterWindowMessage(_T("AP_SETTING_ENABLE")); // 세팅을 바꿀 수 있게 하는 메시지 ID
UINT AP_SETTING_DISABLE = RegisterWindowMessage(_T("AP_SETTING_DISABLE")); // 세팅을 바꿀 수 없게 하는 메시지 ID
// 수동패치
LPCTSTR MP_Folder = _T("MP_FOLDER");
LPCTSTR MP_SFXFile = _T("MP_SFX_FILENAME");
LPCTSTR MP_MinVer = _T("MP_MINVER");
UINT MP_SETTING_ENABLE = RegisterWindowMessage(_T("MP_SETTING_ENABLE")); // 세팅을 바꿀 수 있게 하는 메시지 ID
UINT MP_SETTING_DISABLE = RegisterWindowMessage(_T("MP_SETTING_DISABLE")); // 세팅을 바꿀 수 없게 하는 메시지 ID
// 타이머 ID
UINT AP_PROGRESS_TIMER_ID = 1;
UINT MP_PROGRESS_TIMER_ID = 2;
// 프로그리스 바 갱신 시간
DWORD PROGRESS_TIMER_UPDATE_TIME = 200;
void InitializeStrings()
{
PatchType_Part1.LoadString(IDS_CB_PART1);
PatchType_BattleLohan.LoadString(IDS_CB_BATTLELOHAN_P1);
PatchType_Part2.LoadString(IDS_CB_PART2);
PatchType_Part2Test.LoadString(IDS_CB_PART2_TEST);
PatchType_Part2Malay.LoadString(IDS_CB_PART2_MALAY);
}
void AdjustVersionInfoByPatchType(LPCTSTR szPatchType, DWORD& dwMinver, DWORD dwMaxver)
{
if (0 == PatchType_Part1.CompareNoCase(szPatchType) ||
0 == PatchType_BattleLohan.CompareNoCase(szPatchType))
{
if (100 <= dwMinver) { dwMinver -= 100; }
if (100 <= dwMaxver) { dwMaxver -= 100; }
}
}
bool GetRYLInstalledRegKey(LPCTSTR szPatchType, CString& szInstalledRegKey, CString& szValueName)
{
static CString szFolderP1((LPCTSTR)IDS_FOLDER_P1);
static CString szFolderBattle((LPCTSTR)IDS_FOLDER_BATTLELOHAN);
static CString szFolderP2((LPCTSTR)IDS_FOLDER_P2);
static CString szFolderP2Test((LPCTSTR)IDS_FOLDER_P2_TEST);
szInstalledRegKey.Empty();
szInstalledRegKey.LoadString(IDS_INSTALLED_REGKEY);
if (0 == PatchType_Part1.CompareNoCase(szPatchType)) { szValueName.SetString(szFolderP1); }
else if (0 == PatchType_BattleLohan.CompareNoCase(szPatchType)) { szValueName.SetString(szFolderBattle); }
else if (0 == PatchType_Part2.CompareNoCase(szPatchType)) { szValueName.SetString(szFolderP2); }
else if (0 == PatchType_Part2Test.CompareNoCase(szPatchType)) { szValueName.SetString(szFolderP2Test); }
else if (0 == PatchType_Part2Malay.CompareNoCase(szPatchType))
{
szInstalledRegKey.LoadString(IDS_INSTALLED_REGKEY_MALAY);
szValueName.SetString(szFolderP2);
}
else
{
// 맞는 패치 타입이 없다.
return false;
}
return true;
}
}

View File

@@ -0,0 +1,51 @@
#pragma once
namespace PMConst
{
// 패치 타입
extern LPCTSTR PatchType;
extern CString PatchType_Part1;
extern CString PatchType_BattleLohan;
extern CString PatchType_Part2;
extern CString PatchType_Part2Test;
extern CString PatchType_Part2Malay;
// 자동패치 관련
extern LPCTSTR AP_OldPkg;
extern LPCTSTR AP_NewClient;
extern LPCTSTR AP_NewPkg;
extern LPCTSTR AP_MaxPkg;
extern LPCTSTR AP_FTPAddr;
extern LPCTSTR AP_FTPPort;
extern LPCTSTR AP_FTPPassive;
extern LPCTSTR AP_PkgPosType;
extern UINT AP_SETTING_ENABLE; // 세팅을 바꿀 수 있게 하는 메시지 ID
extern UINT AP_SETTING_DISABLE; // 세팅을 바꿀 수 없게 하는 메시지 ID
// 수동패치 관련
extern LPCTSTR MP_Folder;
extern LPCTSTR MP_SFXFile;
extern LPCTSTR MP_MinVer;
extern UINT MP_SETTING_ENABLE; // 세팅을 바꿀 수 있게 하는 메시지 ID
extern UINT MP_SETTING_DISABLE; // 세팅을 바꿀 수 없게 하는 메시지 ID
// 프로그리스 바 타이머 ID
extern UINT AP_PROGRESS_TIMER_ID;
extern UINT MP_PROGRESS_TIMER_ID;
// 프로그리스 바 갱신 시간
extern DWORD PROGRESS_TIMER_UPDATE_TIME;
// 문자열 데이터를 초기화한다.
void InitializeStrings();
// 패치 타입이 Part1 이면 버전을 100씩 빼 준다.
void AdjustVersionInfoByPatchType(LPCTSTR szPatchType, DWORD& dwMinver, DWORD dwMaxver);
// 패치 종류로부터 RYL이 설치된 레지스트리 키, 읽어올 값 이름을 얻어온다.
bool GetRYLInstalledRegKey(LPCTSTR szPatchType,
CString& szInstalledRegKey, CString& szValueName);
}

View File

@@ -0,0 +1,174 @@
// PatchMaker.cpp : 응용 프로그램에 대한 클래스 동작을 정의합니다.
//
#include "stdafx.h"
#include "PatchMaker.h"
#include "PatchMakerSheet.h"
#include "AutoPatchPage.h"
#include "ManualPatchPage.h"
#include "ChecksumPage.h"
#include "SettingOptionPage.h"
#include "SettingPatchInfo.h"
#include "UtilityFunc.h"
#include "PMSettingConstant.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CPatchMakerApp
BEGIN_MESSAGE_MAP(CPatchMakerApp, CWinApp)
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
// CPatchMakerApp 생성
CPatchMakerApp::CPatchMakerApp()
: m_bAutoPatchOperate(false)
, m_bManualPatchOperate(false)
, m_lpSettingPage(NULL)
{
// TODO: 여기에 생성 코드를 추가합니다.
// InitInstance에 모든 중요한 초기화 작업을 배치합니다.
}
// 유일한 CPatchMakerApp 개체입니다.
CPatchMakerApp theApp;
// CPatchMakerApp 초기화
BOOL CPatchMakerApp::InitInstance()
{
// 응용 프로그램 매니페스트가 ComCtl32.dll 버전 6 이상을 사용하여 비주얼 스타일을
// 사용하도록 지정하는 경우, Windows XP 상에서 반드시 InitCommonControls()가 필요합니다.
// InitCommonControls()를 사용하지 않으면 창을 만들 수 없습니다.
InitCommonControls();
CWinApp::InitInstance();
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
// 표준 초기화
// 이들 기능을 사용하지 않고 최종 실행 파일의 크기를 줄이려면
// 아래에서 필요 없는 특정 초기화 루틴을 제거해야 합니다.
// 해당 설정이 저장된 레지스트리 키를 변경하십시오.
// TODO: 이 문자열을 회사 또는 조직의 이름과 같은
// 적절한 내용으로 수정해야 합니다.
SetRegistryKey(_T("Gamasoft PatchMaker"));
PMConst::InitializeStrings();
CPMSetting& pmSetting = CPMDefaultSetting::GetInstance();
CString szFilePathName;
PMUtil::GetCurrentFolderName(szFilePathName);
szFilePathName.Append(CPMDefaultSetting::GetDefaultSettingName());
if (!pmSetting.LoadSetting(szFilePathName))
{
MessageBox(NULL, _T("기본 설정 파일을 만들거나 읽어올 수 없습니다"),
_T("설정 파일 오류"), MB_OK | MB_ICONWARNING);
}
else
{
CSettingPatchInfo patchInfo;
CPMSetting pmLocalSetting;
bool bFailed = false;
while (!bFailed)
{
if (IDOK == patchInfo.DoModal() && patchInfo.CheckPatchInfo())
{
// 설정 파일의 전체 이름 경로를 알아낸다.
CString szSetupFileName;
PMUtil::GetCurrentFolderName(szSetupFileName);
szSetupFileName.Append(patchInfo.GetSetupFileName());
if (pmLocalSetting.LoadSetting(szSetupFileName))
{
CString szMinver((LPCTSTR)IDS_MIN_VER);
CString szMaxver((LPCTSTR)IDS_MAX_VER);
CString szTitle;
szTitle.Format("PatchMaker v%s.%s : %s : %u", szMaxver, szMinver,
patchInfo.GetSetupName(), patchInfo.GetPatchVersion());
CPatchMakerSheet sheet(szTitle.GetString());
CAutoPatchPage autoPatchPage;
CManualPatchPage manualPatchPage(pmLocalSetting, patchInfo.GetPatchVersion());
CChecksumPage checksumPage;
CSettingOptionPage settingOptPage(pmLocalSetting, sheet);
sheet.AddPage(&autoPatchPage);
sheet.AddPage(&manualPatchPage);
sheet.AddPage(&checksumPage);
sheet.AddPage(&settingOptPage); // 이 페이지는 제일 마지막으로..
m_pMainWnd = &sheet;
m_lpSettingPage = &settingOptPage;
sheet.DoModal();
}
else
{
MessageBox(NULL, _T("셋업 파일을 불러오기 위해서 여는 데 실패했습니다"),
_T("파일 열기 오류"), MB_OK | MB_ICONEXCLAMATION);
bFailed = true;
}
}
else
{
bFailed = true;
}
}
}
// 대화 상자가 닫혔으므로 응용 프로그램의 메시지 펌프를 시작하지 않고
// 응용 프로그램을 끝낼 수 있도록 FALSE를 반환합니다.
CoUninitialize();
return FALSE;
}
void CPatchMakerApp::SetAutoPatchOperate(bool bOperate)
{
if (0 != m_lpSettingPage && (m_bAutoPatchOperate ^ bOperate))
{
// 두 상태가 서로 반대 상태인 경우에만(exclusive OR) 작업을 한다.
m_lpSettingPage->SendMessage(
bOperate ? PMConst::AP_SETTING_DISABLE : PMConst::AP_SETTING_ENABLE, 0, 0);
m_bAutoPatchOperate = bOperate;
}
}
void CPatchMakerApp::SetManualPatchOperate(bool bOperate)
{
if (0 != m_lpSettingPage && (m_bManualPatchOperate ^ bOperate))
{
// 두 상태가 서로 반대 상태인 경우에만(exclusive OR) 작업을 한다.
m_lpSettingPage->SendMessage(
bOperate ? PMConst::MP_SETTING_DISABLE : PMConst::MP_SETTING_ENABLE, 0, 0);
m_bManualPatchOperate = bOperate;
}
}
void CPatchMakerApp::AddTotalProgressLog(LPCTSTR szProgress)
{
if (0 != m_pMainWnd && 0 != szProgress &&
m_pMainWnd->IsKindOf(RUNTIME_CLASS(CPatchMakerSheet)))
{
CPatchMakerSheet* lpSheet = static_cast<CPatchMakerSheet*>(m_pMainWnd);
lpSheet->GetLogEdit().AddLine(szProgress);
}
}

View File

@@ -0,0 +1,48 @@
// PatchMaker.h : PROJECT_NAME 응용 프로그램에 대한 주 헤더 파일입니다.
//
#pragma once
#ifndef __AFXWIN_H__
#error PCH에서 이 파일을 포함하기 전에 'stdafx.h'를 포함하십시오.
#endif
#include "resource.h" // 주 기호
// CPatchMakerApp:
// 이 클래스의 구현에 대해서는 PatchMaker.cpp을 참조하십시오.
//
class CPatchMakerApp : public CWinApp
{
public:
CPatchMakerApp();
// 재정의
public:
virtual BOOL InitInstance();
// 구현
DECLARE_MESSAGE_MAP()
public:
void SetAutoPatchOperate(bool bOperate);
void SetManualPatchOperate(bool bOperate);
bool IsAutoPatchOperate() const { return m_bAutoPatchOperate; }
bool IsManualPatchOperate() const { return m_bManualPatchOperate; }
void AddTotalProgressLog(LPCTSTR szProgress);
private:
CWnd* m_lpSettingPage;
bool m_bAutoPatchOperate;
bool m_bManualPatchOperate;
};
extern CPatchMakerApp theApp;

View File

@@ -0,0 +1,359 @@
// 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\\PatchMaker.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\\PatchMaker.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOGEX 0, 0, 235, 55
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "PatchMaker 정보"
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
LTEXT "PatchMaker Version v0.2",IDC_STATIC,40,10,119,8,
SS_NOPREFIX
LTEXT "Copyright (C) 2008 Youxiland",IDC_STATIC,40,25,119,8
DEFPUSHBUTTON "확인",IDOK,178,7,50,16,WS_GROUP
END
IDD_PATCH_INFO DIALOGEX 0, 0, 287, 49
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "패치 기본 설정"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
COMBOBOX IDC_CB_SEL_OPTION,72,8,207,159,CBS_DROPDOWNLIST |
CBS_SORT | WS_TABSTOP
EDITTEXT IDC_ED_PATCHVER,106,27,61,14,ES_AUTOHSCROLL
DEFPUSHBUTTON "확인",IDOK,175,27,50,14
PUSHBUTTON "취소",IDCANCEL,229,27,50,14
LTEXT "설정 파일 선택 :",IDC_STATIC,11,11,58,8
LTEXT "패치를 생성할 버전 입력 :",IDC_STATIC,11,29,92,8
END
IDD_SINGLE_INPUT DIALOGEX 0, 0, 336, 31
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
EDITTEXT IDC_INPUT_SINGLE_LINE,84,10,178,14,ES_AUTOHSCROLL
DEFPUSHBUTTON "확인",IDOK,265,10,32,14
PUSHBUTTON "취소",IDCANCEL,300,10,32,14
CTEXT "입력하세요",IDC_INPUT_SINGLE_QUESTION,7,12,74,8
END
IDD_SETTING_OPTION DIALOGEX 0, 0, 515, 274
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CHILD | WS_CAPTION |
WS_SYSMENU | WS_GROUP
CAPTION "패치 설정"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "패치 타입 : ",IDC_STATIC,15,10,42,8
COMBOBOX IDC_CB_OPT_PATCH_TYPE,58,7,98,157,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "자동 패치 설정",IDC_STATIC,7,26,501,86
LTEXT "구버전 패키지 위치 :",IDC_STATIC,29,40,74,8
EDITTEXT IDC_ED_OPT_OLD_PKG,103,36,375,14,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_BTN_OPT_OLD_PKG,481,36,19,14
LTEXT "신버전 클라이언트 위치 :",IDC_STATIC,13,56,90,8
EDITTEXT IDC_ED_OPT_NEW_CLIENT,103,52,375,14,ES_AUTOHSCROLL |
ES_READONLY
PUSHBUTTON "...",IDC_BTN_OPT_NEW_CLIENT,481,52,19,14
LTEXT "신버전 패키지 저장위치 :",IDC_STATIC,13,71,90,8
EDITTEXT IDC_ED_OPT_NEW_PKG,103,68,375,14,ES_AUTOHSCROLL |
ES_READONLY
PUSHBUTTON "...",IDC_BTN_OPT_NEW_PKG,481,68,19,14
LTEXT "패키지 최대크기 :",IDC_STATIC,14,92,64,8
EDITTEXT IDC_ED_OPT_MAX_PKG,79,89,69,14,ES_AUTOHSCROLL,
WS_EX_RIGHT
LTEXT "구버전 패키지 파일 위치 :",IDC_STATIC,178,92,92,8
COMBOBOX IDC_CB_OPT_OLD_PKG_POS,271,90,86,107,CBS_DROPDOWNLIST |
CBS_SORT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "FTP 설정",IDC_STATIC,7,116,171,64,WS_GROUP
CTEXT "접속할 주소 :",IDC_STATIC,14,132,48,8,NOT WS_GROUP
EDITTEXT IDC_ED_OPT_FTP_ADDR,64,130,107,14,ES_AUTOHSCROLL
CTEXT "접속 포트 :",IDC_STATIC,19,148,43,8,NOT WS_GROUP
EDITTEXT IDC_ED_OPT_FTP_PORT,64,146,107,14,ES_AUTOHSCROLL
CONTROL "Passive 모드로 접속",IDC_CK_OPT_FTP_PASSIVE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,46,164,84,10
GROUPBOX "수동 패치 설정",IDC_STATIC,7,186,501,63
LTEXT "수동패치 파일 폴더 :",IDC_STATIC,26,200,74,8
EDITTEXT IDC_ED_OPT_MANUAL_PATCH_FILE,104,197,375,14,
ES_AUTOHSCROLL | ES_READONLY
PUSHBUTTON "...",IDC_BTN_OPT_MANUAL_PATCH_FILE,482,197,19,14
LTEXT "수동패치 SFX파일 위치 :",IDC_STATIC,13,216,86,8
EDITTEXT IDC_ED_OPT_MANUAL_SFX_FILE,104,213,375,14,ES_AUTOHSCROLL |
ES_READONLY
PUSHBUTTON "...",IDC_BTN_OPT_MANUAL_SFX_FILE,482,213,19,14
LTEXT "수동패치 최소버전 :",IDC_STATIC,27,232,72,8
EDITTEXT IDC_ED_OPT_MANUAL_MIN_VER,104,229,55,14,ES_AUTOHSCROLL
PUSHBUTTON "저장하기",ID_SAVE_SETUP,392,253,56,14
PUSHBUTTON "다시 불러오기",ID_LOAD_SETUP,452,253,56,14
LTEXT "KB",IDC_STATIC,152,92,9,8
END
IDD_AUTO_PATCH DIALOGEX 0, 0, 510, 415
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CHILD | WS_CAPTION |
WS_SYSMENU | WS_GROUP
CAPTION "자동패치"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
EDITTEXT IDC_ED_AP_ERR_CONSOLE,16,348,478,48,ES_MULTILINE |
ES_AUTOHSCROLL | WS_VSCROLL
EDITTEXT IDC_ED_AP_FTP_ADDR,60,20,107,14,ES_AUTOHSCROLL
EDITTEXT IDC_ED_AP_FTP_PORT,60,36,107,14,ES_AUTOHSCROLL
EDITTEXT IDC_ED_AP_FTP_ID,209,21,69,14,ES_AUTOHSCROLL
EDITTEXT IDC_ED_AP_FTP_PW,209,37,69,14,ES_PASSWORD |
ES_AUTOHSCROLL
CONTROL "Passive 모드로 접속",IDC_CK_AP_FTP_PASSIVE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,43,55,84,10
EDITTEXT IDC_ED_AP_CONSOLE,16,183,478,117,ES_MULTILINE |
ES_AUTOHSCROLL | WS_VSCROLL
EDITTEXT IDC_ED_AP_OLD_PKG,99,90,375,14,ES_AUTOHSCROLL |
ES_READONLY
EDITTEXT IDC_ED_AP_NEW_CLIENT,99,106,375,14,ES_AUTOHSCROLL |
ES_READONLY
EDITTEXT IDC_ED_AP_NEW_PKG,99,122,375,14,ES_AUTOHSCROLL
PUSHBUTTON "작업 시작",IDOK,322,47,71,28
PUSHBUTTON "취소",IDCANCEL,400,47,71,28
CONTROL "",IDC_PRG_AP,"msctls_progress32",0x1,16,314,478,14
RTEXT "ID :",IDC_STATIC,192,24,15,8
RTEXT "Password : ",IDC_STATIC,171,39,36,8
LTEXT "패치 타입 : ",IDC_STATIC,325,15,42,8
GROUPBOX "자동 패치 설정",IDC_STATIC,7,79,496,86
LTEXT "구버전 패키지 위치",IDC_STATIC,11,93,69,8
LTEXT "신버전 클라이언트 위치",IDC_STATIC,11,109,85,8
LTEXT "신버전 패키지 저장위치",IDC_STATIC,11,124,85,8
PUSHBUTTON "...",IDC_BTN_OPT_NEW_PKG2,478,122,19,14
LTEXT "패키지 최대크기 :",IDC_STATIC,15,146,64,8
EDITTEXT IDC_ED_AP_MAX_PKG,81,143,73,14,ES_AUTOHSCROLL |
ES_READONLY
LTEXT "구버전 패키지 파일 위치 :",IDC_STATIC,178,146,92,8
EDITTEXT IDC_ED_AP_PATCH_TYPE,366,12,99,14,ES_AUTOHSCROLL |
ES_READONLY
GROUPBOX "진행 상황",IDC_STATIC,7,170,496,236
RTEXT "0/0",IDC_ST_AP_PRORGRESS,298,303,193,8
LTEXT "에러 로그",IDC_STATIC,20,337,35,8
GROUPBOX "FTP 설정",IDC_STATIC,7,7,276,65,WS_GROUP
CTEXT "접속할 주소 :",IDC_STATIC,11,23,48,8,NOT WS_GROUP
CTEXT "접속 포트 :",IDC_STATIC,19,39,40,8,NOT WS_GROUP
EDITTEXT IDC_ED_AP_OLD_PKG_POS,274,143,75,14,ES_AUTOHSCROLL |
ES_READONLY
LTEXT "패치 버전 :",IDC_STATIC,325,32,40,8
EDITTEXT IDC_ED_AP_PATCH_VER,366,29,99,14,ES_AUTOHSCROLL |
ES_READONLY
END
IDD_MANUAL_PATCH DIALOGEX 0, 0, 510, 399
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CHILD | WS_CAPTION |
WS_SYSMENU | WS_GROUP
CAPTION "수동 패치"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "수동패치 생성",ID_MP_CREATE,347,70,73,25
PUSHBUTTON "취소",ID_MP_CANCEL,424,70,73,25
GROUPBOX "수동 패치 설정",IDC_STATIC,7,7,496,95
LTEXT "수동패치 파일 폴더 :",IDC_STATIC,23,21,74,8
EDITTEXT IDC_ED_MP_MANUAL_PATCH_FILE,99,18,375,14,ES_AUTOHSCROLL |
ES_READONLY
LTEXT "수동패치 SFX파일 위치 :",IDC_STATIC,11,37,86,8
EDITTEXT IDC_ED_MP_MANUAL_SFX_FILE,99,34,375,14,ES_AUTOHSCROLL |
ES_READONLY
LTEXT "수동패치 최소버전 :",IDC_STATIC,25,69,72,8
EDITTEXT IDC_ED_MP_MIN_VER,99,66,81,14,ES_AUTOHSCROLL |
ES_READONLY
EDITTEXT IDC_ED_MP_CUR_VER,99,82,81,14,ES_AUTOHSCROLL |
ES_READONLY
LTEXT "수동패치 현재버전 :",IDC_STATIC,25,85,72,8
LTEXT "수동패치 파일 이름 :",IDC_STATIC,23,53,74,8
EDITTEXT IDC_ED_MP_PATCH_FILE_NAME,99,50,375,14,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_BTN_MP_SELECT_FILE,477,50,19,14
EDITTEXT IDC_ED_MP_ERR_CONSOLE,16,289,478,76,ES_MULTILINE |
ES_AUTOHSCROLL | WS_VSCROLL
EDITTEXT IDC_ED_MP_CONSOLE,15,124,478,117,ES_MULTILINE |
ES_AUTOHSCROLL | WS_VSCROLL
CONTROL "",IDC_PRG_MP,"msctls_progress32",0x1,16,255,478,14
GROUPBOX "진행 상황",IDC_STATIC,7,115,496,276
RTEXT "0/0",IDC_ST_MP_PRORGRESS,298,244,193,8
LTEXT "에러 로그",IDC_STATIC,19,275,35,8
LTEXT "패치 타입 :",IDC_STATIC,192,76,40,8
EDITTEXT IDC_ED_MP_PATCH_TYPE,234,73,81,14,ES_AUTOHSCROLL |
ES_READONLY
PUSHBUTTON "로그 초기화",IDC_CLEAR_LOG,444,371,50,14
END
IDD_CHECKSUM DIALOGEX 0, 0, 462, 61
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CHILD | WS_CAPTION |
WS_SYSMENU | WS_GROUP
CAPTION "체크섬 계산"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "계산",IDOK,266,28,91,26
PUSHBUTTON "닫기",IDCANCEL,364,28,91,26
LTEXT "패키지 위치 :",IDC_STATIC,7,9,48,8
EDITTEXT IDC_ED_CK_PKG_POS,57,7,375,14,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_BTN_CK_PKG_POS,436,7,19,14
LTEXT "패키지 버전 :",IDC_STATIC,7,26,48,8
EDITTEXT IDC_ED_CK_PKG_VER,57,23,94,14,ES_AUTOHSCROLL |
ES_READONLY
LTEXT "체크섬 :",IDC_STATIC,25,41,30,8
EDITTEXT IDC_ED_CK_CHECKSUM,57,40,94,14,ES_AUTOHSCROLL |
ES_READONLY
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 228
TOPMARGIN, 7
BOTTOMMARGIN, 48
END
IDD_PATCH_INFO, DIALOG
BEGIN
LEFTMARGIN, 11
RIGHTMARGIN, 279
TOPMARGIN, 8
BOTTOMMARGIN, 41
END
IDD_MANUAL_PATCH, DIALOG
BEGIN
BOTTOMMARGIN, 391
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_ABOUTBOX "PatchMaker 정보(&A)..."
IDS_MIN_VER "1"
IDS_MAX_VER "0"
IDS_CB_PART1 "Part1"
IDS_CB_BATTLELOHAN_P1 "BattleLohan(Part1)"
IDS_CB_PART2 "ROW"
IDS_CB_PART2_TEST "Part2 Test"
IDS_CB_PART2_MALAY "Part2 Malaysia"
IDS_CB_FTP "FTP"
END
STRINGTABLE
BEGIN
IDS_CB_LOCAL "LOCAL"
IDS_INSTALLED_REGKEY "SOFTWARE\\ROW\\MP-Client"
IDS_FOLDER_P1 "Folder"
IDS_FOLDER_BATTLELOHAN "BGFolder"
IDS_FOLDER_P2 "Folder"
IDS_FOLDER_P2_TEST "TestFolder"
IDS_INSTALLED_REGKEY_MALAY "SOFTWARE\\ROW\\MP-Client"
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\PatchMaker.rc2" // Microsoft Visual C++에서 편집되지 않은 리소스
#include "afxres.rc" // 표준 구성 요소
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,261 @@
<?xml version="1.0" encoding="ks_c_5601-1987"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="PatchMaker"
ProjectGUID="{AEFD2B3A-9649-4084-8E23-EE50A59ABDA7}"
SccProjectName=""
SccLocalPath=""
Keyword="MFCProj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
UseOfMFC="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../ZipArchive/Include"
PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="../ZipArchive/Lib/ZipArchive_MFCDLL_d.lib"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
SubSystem="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="FALSE"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1042"
AdditionalIncludeDirectories="$(IntDir)"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
UseOfMFC="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../ZipArchive/Include"
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
MinimalRebuild="FALSE"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="../ZipArchive/Lib/ZipArchive_MFCDLL.lib"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="FALSE"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1042"
AdditionalIncludeDirectories="$(IntDir)"/>
<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=".\AutoPatchPage.cpp">
</File>
<File
RelativePath=".\ChecksumPage.cpp">
</File>
<File
RelativePath=".\LogEdit.cpp">
</File>
<File
RelativePath=".\ManualPatchPage.cpp">
</File>
<File
RelativePath=".\PatchMaker.cpp">
</File>
<File
RelativePath=".\PatchMakerSheet.cpp">
</File>
<File
RelativePath=".\PMSetting.cpp">
</File>
<File
RelativePath=".\PMSettingConstant.cpp">
</File>
<File
RelativePath=".\SettingOptionPage.cpp">
</File>
<File
RelativePath=".\SettingPatchInfo.cpp">
</File>
<File
RelativePath=".\SingleInputDlg.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=".\UtilityFunc.cpp">
</File>
</Filter>
<Filter
Name="헤더 파일"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\AutoPatchPage.h">
</File>
<File
RelativePath=".\ChecksumPage.h">
</File>
<File
RelativePath=".\LogEdit.h">
</File>
<File
RelativePath=".\ManualPatchPage.h">
</File>
<File
RelativePath=".\PatchMaker.h">
</File>
<File
RelativePath=".\PatchMakerSheet.h">
</File>
<File
RelativePath=".\PMSetting.h">
</File>
<File
RelativePath=".\PMSettingConstant.h">
</File>
<File
RelativePath=".\Resource.h">
</File>
<File
RelativePath=".\SettingOptionPage.h">
</File>
<File
RelativePath=".\SettingPatchInfo.h">
</File>
<File
RelativePath=".\SingleInputDlg.h">
</File>
<File
RelativePath=".\stdafx.h">
</File>
<File
RelativePath=".\UtilityFunc.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=".\res\CC3.ico">
</File>
<File
RelativePath=".\res\PatchMaker.ico">
</File>
<File
RelativePath=".\PatchMaker.rc">
</File>
<File
RelativePath=".\res\PatchMaker.rc2">
</File>
</Filter>
<File
RelativePath=".\res\PatchMaker.manifest">
</File>
<File
RelativePath=".\ReadMe.txt">
</File>
</Files>
<Globals>
<Global
Name="RESOURCE_FILE"
Value="PatchMaker.rc"/>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Template|Win32">
<Configuration>Template</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{AEFD2B3A-9649-4084-8E23-EE50A59ABDA7}</ProjectGuid>
<SccProjectName />
<SccLocalPath />
<Keyword>MFCProj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>Dynamic</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>Dynamic</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Template|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../ZipArchive/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>../ZipArchive/Lib/ZipArchive_MFCDLL_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>false</MkTypLibCompatible>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0412</Culture>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>../ZipArchive/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>../ZipArchive/Lib/ZipArchive_MFCDLL.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>false</MkTypLibCompatible>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0412</Culture>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="AutoPatchPage.cpp" />
<ClCompile Include="ChecksumPage.cpp" />
<ClCompile Include="LogEdit.cpp" />
<ClCompile Include="ManualPatchPage.cpp" />
<ClCompile Include="PatchMaker.cpp" />
<ClCompile Include="PatchMakerSheet.cpp" />
<ClCompile Include="PMSetting.cpp" />
<ClCompile Include="PMSettingConstant.cpp" />
<ClCompile Include="SettingOptionPage.cpp" />
<ClCompile Include="SettingPatchInfo.cpp" />
<ClCompile Include="SingleInputDlg.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="UtilityFunc.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AutoPatchPage.h" />
<ClInclude Include="ChecksumPage.h" />
<ClInclude Include="LogEdit.h" />
<ClInclude Include="ManualPatchPage.h" />
<ClInclude Include="PatchMaker.h" />
<ClInclude Include="PatchMakerSheet.h" />
<ClInclude Include="PMSetting.h" />
<ClInclude Include="PMSettingConstant.h" />
<ClInclude Include="Resource.h" />
<ClInclude Include="SettingOptionPage.h" />
<ClInclude Include="SettingPatchInfo.h" />
<ClInclude Include="SingleInputDlg.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="UtilityFunc.h" />
</ItemGroup>
<ItemGroup>
<None Include="res\CC3.ico" />
<None Include="res\PatchMaker.ico" />
<None Include="res\PatchMaker.rc2" />
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="PatchMaker.rc" />
</ItemGroup>
<ItemGroup>
<Manifest Include="res\PatchMaker.manifest" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties RESOURCE_FILE="PatchMaker.rc" />
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@@ -0,0 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="소스 파일">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="헤더 파일">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="리소스 파일">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="AutoPatchPage.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="ChecksumPage.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="LogEdit.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="ManualPatchPage.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="PatchMaker.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="PatchMakerSheet.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="PMSetting.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="PMSettingConstant.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="SettingOptionPage.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="SettingPatchInfo.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="SingleInputDlg.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="UtilityFunc.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="AutoPatchPage.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="ChecksumPage.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="LogEdit.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="ManualPatchPage.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="PatchMaker.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="PatchMakerSheet.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="PMSetting.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="PMSettingConstant.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="Resource.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="SettingOptionPage.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="SettingPatchInfo.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="SingleInputDlg.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="UtilityFunc.h">
<Filter>헤더 파일</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="res\CC3.ico">
<Filter>리소스 파일</Filter>
</None>
<None Include="res\PatchMaker.ico">
<Filter>리소스 파일</Filter>
</None>
<None Include="res\PatchMaker.rc2">
<Filter>리소스 파일</Filter>
</None>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="PatchMaker.rc">
<Filter>리소스 파일</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Manifest Include="res\PatchMaker.manifest" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,109 @@
// PatchMakerSheet.cpp : 구현 파일입니다.
//
#include "stdafx.h"
#include "PatchMaker.h"
#include "PatchMakerSheet.h"
// PatchMakerSheet
IMPLEMENT_DYNAMIC(CPatchMakerSheet, CPropertySheet)
CPatchMakerSheet::CPatchMakerSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{
}
CPatchMakerSheet::CPatchMakerSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
}
CPatchMakerSheet::~CPatchMakerSheet()
{
}
BEGIN_MESSAGE_MAP(CPatchMakerSheet, CPropertySheet)
ON_WM_CREATE()
END_MESSAGE_MAP()
// PatchMakerSheet 메시지 처리기입니다.
BOOL CPatchMakerSheet::OnInitDialog()
{
BOOL bResult = CPropertySheet::OnInitDialog();
// TODO: 여기에 특수화된 코드를 추가합니다.
// 버튼을 제거합니다.
int ids[] = { IDOK, IDCANCEL, IDHELP, ID_APPLY_NOW };
CRect rcButton;
for (int i = 0; i < sizeof(ids)/sizeof(int); i++)
{
CWnd* lpWnd = GetDlgItem(ids[i]);
if (lpWnd)
{
lpWnd->GetWindowRect(&rcButton);
lpWnd->ShowWindow(FALSE);
}
}
int nEditWidthMargin = 20;
int nEditHeightMargin = 20;
int nEditHeight = 80;
CRect rect;
GetWindowRect(&rect);
rect.bottom += nEditHeight - rcButton.Height() + nEditHeightMargin / 2;
MoveWindow(rect);
GetClientRect (&rect);
// 에딧 컨트롤을 바닥에 붙인다.
int nX = rect.left + nEditWidthMargin / 2;
int nY = rect.bottom - nEditHeight - nEditHeightMargin / 2;
int nEditWidth = rect.Width() - nEditWidthMargin;
m_edLogMsg.CreateEx (WS_EX_CLIENTEDGE, _T("EDIT"), NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL,
nX, nY, nEditWidth, nEditHeight, m_hWnd, 0, 0 );
m_edLogMsg.SetFont(GetFont());
const int nMaxPageCount = GetPageCount();
for(int nIndex = 0; nIndex < nMaxPageCount; ++nIndex)
{
// 한번씩 Active를 해서, Page의 OnInitDialog를 호출하도록 한다.
SetActivePage(nIndex);
}
SetActivePage(0);
return bResult;
}
int CPatchMakerSheet::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CPropertySheet::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 여기에 특수화된 작성 코드를 추가합니다.
ModifyStyle(0, WS_MINIMIZEBOX);
return 0;
}
BOOL CPatchMakerSheet::OnCommand(WPARAM wParam, LPARAM lParam)
{
// TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
if (LOWORD(wParam) == IDOK)
{
// 엔터 눌러도 안먹게 함.
return TRUE;
}
return CPropertySheet::OnCommand(wParam, lParam);
}

View File

@@ -0,0 +1,38 @@
#pragma once
#include "LogEdit.h"
// forward decl.
class CAutoPatchPage;
class CManualPatchPage;
class CChecksumPage;
class CSettingOptionPage;
// PatchMakerSheet
class CPatchMakerSheet : public CPropertySheet
{
DECLARE_DYNAMIC(CPatchMakerSheet)
public:
CPatchMakerSheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
CPatchMakerSheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
virtual ~CPatchMakerSheet();
protected:
DECLARE_MESSAGE_MAP()
public:
CLogEdit& GetLogEdit() { return m_edLogMsg; }
virtual BOOL OnInitDialog();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
protected:
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
CLogEdit m_edLogMsg;
};

View File

@@ -0,0 +1,71 @@
================================================================================
MFC 라이브러리 : PatchMaker 프로젝트 개요
================================================================================
응용 프로그램 마법사를 사용하여 PatchMaker 응용 프로그램을 만듭니다. 이 응용
프로그램에서는 기본적인 MFC 사용 밥법과 응용 프로그램 작성 방법을 설명합니다.
이 파일에는 PatchMaker 응용 프로그램을 구성하는 각 파일에 대한 개요가 포함되어
있습니다.
PatchMaker.vcproj
응용 프로그램 마법사를 사용하여 생성된 VC++ 프로젝트의 주 프로젝트 파일입니다.
이 파일에는 파일을 생성한 Visual C++ 버전 정보 및 응용 프로그램 마법사에서 선택한 플랫폼,
구성, 프로젝트 기능 등의 정보가 포함됩니다.
PatchMaker.h
응용 프로그램의 주 헤더 파일입니다. 이 파일에는 다른 프로젝트에 관련된 Resource.h와 같은
특정 헤더가 포함되며 CPatchMakerApp 응용 프로그램 클래스가 선언됩니다.
PatchMaker.cpp
CPatchMakerApp 응용 프로그램 클래스를 포함하는 주 응용 프로그램의 소스 파일입니다.
PatchMaker.rc
프로그램에서 사용하는 모든 Microsoft Windows 리소스가 나열된 파일입니다.
이 파일에는 RES 하위 디렉터리에 저장된 아이콘, 비트맵 및 커서가 포함되며
Microsoft Visual C++에서 직접 이 파일을 편집할 수도 있습니다. 사용자의 프로젝트
리소스는 1042에 들어 있습니다.
res\PatchMaker.ico
응용 프로그램의 아이콘으로 사용되는 아이콘 파일입니다.
이 아이콘은 주 리소스 파일인 PatchMaker.rc에 포함됩니다.
res\PatchMaker.rc2
Microsoft Visual C++에서 편집할 수 없는 리소스가 포함된 파일입니다.
리소스 편집기에서 편집할 수 없는 모든 리소스는 이 파일에 포함되어 있습니다.
/////////////////////////////////////////////////////////////////////////////
응용 프로그램 마법사에서는 단일 대화 상자 클래스를 만듭니다.
PatchMakerDlg.h, PatchMakerDlg.cpp - 대화 상자
CPatchMakerDlg 클래스를 포함하는 파일입니다. 이 클래스에는 응용 프로그램의
주 대화 상자에 대한 동작이 정의됩니다. 대화 상자의 템플릿은 PatchMaker.rc에
있으며 Microsoft Visual C++에서 편집할 수 있습니다.
/////////////////////////////////////////////////////////////////////////////
기타 표준 파일
StdAfx.h, StdAfx.cpp
미리 컴파일된 헤더 파일(PCH) PatchMaker.pch 및 미리 컴파일된
형식 파일 StdAfx.obj를 빌드할 때 사용되는 파일입니다.
Resource.h
새로운 리소스 ID를 정의하는 표준 헤더 파일입니다.
Microsoft Visual C++에서 이 파일을 읽고 업데이트합니다.
/////////////////////////////////////////////////////////////////////////////
기타 정보
응용 프로그램 마법사에서는 "TODO:"를 사용하여 추가하거나 사용자 지정해야 하는
소스 코드를 나타냅니다.
응용 프로그램에서 공유 DLL에 MFC를 사용하고 응용 프로그램의 언어가 운영 체제의
언어와 다른 경우 Microsoft Visual C++ CD-ROM의 Win\System 디렉터리에 있는
해당 지역의 리소스인 MFC70XXX.DLL을 컴퓨터의 system 또는 system32 디렉터리에
복사한 다음 MFCLOC.DLL로 이름을 바꾸어야 합니다. "XXX"는 해당 언어를 나타내는
약어입니다. 예를 들어 MFC70DEU.DLL에는 독일어로 변환된 리소스가 포함됩니다.
이런 작업을 하지 않으면 응용 프로그램의 일부 UI 요소가 운영 체제의 언어로
남아 있게 됩니다.
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,446 @@
// SettingOptionPage.cpp : 구현 파일입니다.
//
#include "stdafx.h"
#include "PatchMaker.h"
#include "SettingOptionPage.h"
#include "UtilityFunc.h"
#include "PMSettingConstant.h"
#include ".\settingoptionpage.h"
// CSettingOptionPage 대화 상자입니다.
IMPLEMENT_DYNAMIC(CSettingOptionPage, CPropertyPage)
CSettingOptionPage::CSettingOptionPage(CPMSetting& pmSetting, CPropertySheet& ownerSheet)
: CPropertyPage(CSettingOptionPage::IDD)
, m_dwManualPatchMinVer(100)
, m_OwnerSheet(ownerSheet)
, m_pmSettingOption(pmSetting)
{
}
CSettingOptionPage::~CSettingOptionPage()
{
}
void CSettingOptionPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
DDX_Control(pDX, IDC_CB_OPT_PATCH_TYPE, m_cbPatchType);
DDX_Control(pDX, IDC_ED_OPT_OLD_PKG, m_edOldPkgPos);
DDX_Control(pDX, IDC_ED_OPT_NEW_CLIENT, m_edNewClientPos);
DDX_Control(pDX, IDC_ED_OPT_NEW_PKG, m_edNewPkgPos);
DDX_Control(pDX, IDC_ED_OPT_MAX_PKG, m_edMaxPkgSize);
DDX_Control(pDX, IDC_CB_OPT_OLD_PKG_POS, m_cbPkgPos);
DDX_Control(pDX, IDC_ED_OPT_FTP_ADDR, m_edFTPAddr);
DDX_Control(pDX, IDC_ED_OPT_FTP_PORT, m_edFTPPort);
DDX_Control(pDX, IDC_CK_OPT_FTP_PASSIVE, m_bFTPPassive);
DDX_Control(pDX, IDC_ED_OPT_MANUAL_PATCH_FILE, m_edManualPatchFolder);
DDX_Control(pDX, IDC_ED_OPT_MANUAL_SFX_FILE, m_edManualPatchSFXFile);
DDX_Control(pDX, IDC_ED_OPT_MANUAL_MIN_VER, m_edManualPatchMinVer);
DDX_Text(pDX, IDC_ED_OPT_MANUAL_MIN_VER, m_dwManualPatchMinVer);
DDV_MinMaxUInt(pDX, m_dwManualPatchMinVer, 100, 10000);
}
BEGIN_MESSAGE_MAP(CSettingOptionPage, CPropertyPage)
ON_BN_CLICKED(IDC_BTN_OPT_OLD_PKG, OnBnClickedBtnOptOldPkg)
ON_BN_CLICKED(IDC_BTN_OPT_NEW_CLIENT, OnBnClickedBtnOptNewClient)
ON_BN_CLICKED(IDC_BTN_OPT_NEW_PKG, OnBnClickedBtnOptNewPkg)
ON_BN_CLICKED(IDC_BTN_OPT_MANUAL_PATCH_FILE, OnBnClickedBtnOptManualPatchFile)
ON_BN_CLICKED(IDC_BTN_OPT_MANUAL_SFX_FILE, OnBnClickedBtnOptManualSfxFile)
ON_BN_CLICKED(ID_SAVE_SETUP, OnBnClickedSaveSetup)
ON_BN_CLICKED(ID_LOAD_SETUP, OnBnClickedLoadSetup)
ON_REGISTERED_MESSAGE(PMConst::AP_SETTING_ENABLE, OnEnableAutoPatchOption)
ON_REGISTERED_MESSAGE(PMConst::AP_SETTING_DISABLE, OnDisableAutoPatchOption)
ON_REGISTERED_MESSAGE(PMConst::MP_SETTING_ENABLE, OnEnableManualPatchOption)
ON_REGISTERED_MESSAGE(PMConst::MP_SETTING_DISABLE, OnDisableManualPatchOption)
ON_CBN_SELCHANGE(IDC_CB_OPT_OLD_PKG_POS, OnCbnSelchangeCbOptOldPkgPos)
ON_WM_DESTROY()
END_MESSAGE_MAP()
// CSettingOptionPage 메시지 처리기입니다.
inline int AddCBString(CComboBox& combo, CString& tempString, int nIndex, UINT nID)
{
tempString.LoadString(nID);
return combo.InsertString(nIndex, tempString);
}
BOOL CSettingOptionPage::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: 여기에 추가 초기화 작업을 추가합니다.
CString szTmp;
m_cbPatchType.InsertString(0, PMConst::PatchType_Part1);
m_cbPatchType.InsertString(1, PMConst::PatchType_BattleLohan);
m_cbPatchType.InsertString(2, PMConst::PatchType_Part2);
m_cbPatchType.InsertString(3, PMConst::PatchType_Part2Test);
m_cbPatchType.InsertString(4, PMConst::PatchType_Part2Malay);
AddCBString(m_cbPkgPos, szTmp, 0, IDS_CB_FTP);
AddCBString(m_cbPkgPos, szTmp, 1, IDS_CB_LOCAL);
OnCbnSelchangeCbOptOldPkgPos();
return TRUE; // return TRUE unless you set the focus to a control
// 예외: OCX 속성 페이지는 FALSE를 반환해야 합니다.
}
void CSettingOptionPage::OnBnClickedBtnOptOldPkg()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
PMUtil::BrowseForFolder(GetSafeHwnd(),
_T("예전 패키지가 있는 폴더를 선택해주세요"), m_edOldPkgPos);
}
void CSettingOptionPage::OnBnClickedBtnOptNewClient()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
PMUtil::BrowseForFolder(GetSafeHwnd(),
_T("깨끗한 클라이언트 파일이 있는 폴더를 선택해주세요"), m_edNewClientPos);
}
void CSettingOptionPage::OnBnClickedBtnOptNewPkg()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
PMUtil::BrowseForFolder(GetSafeHwnd(),
_T("새 패키지 파일이 저장될 루트 폴더를 선택해주세요"), m_edNewPkgPos);
}
void CSettingOptionPage::OnBnClickedBtnOptManualPatchFile()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
PMUtil::BrowseForFolder(GetSafeHwnd(),
_T("수동 패치 파일이 위치한 폴더를 선택해주세요"), m_edManualPatchFolder);
}
void CSettingOptionPage::OnBnClickedBtnOptManualSfxFile()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
CString szFileName;
if (PMUtil::BrowseForExisingFile(this->GetSafeHwnd(),
_T("수동 패치 SFX파일을 선택해주세요"), "SFX File\0*.exe", szFileName))
{
m_edManualPatchSFXFile.SetWindowText(szFileName);
}
}
void CSettingOptionPage::OnBnClickedSaveSetup()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateSetupData(TRUE);
if (!m_pmSettingOption.SaveSetting())
{
MessageBox(_T("셋업 파일을 저장하기 위해서 여는 데 실패했습니다"),
_T("파일 열기 오류"), MB_OK | MB_ICONEXCLAMATION);
}
}
void CSettingOptionPage::OnBnClickedLoadSetup()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
if (m_pmSettingOption.LoadSetting())
{
UpdateSetupData(FALSE);
OnCbnSelchangeCbOptOldPkgPos();
}
else
{
MessageBox(_T("셋업 파일을 불러오기 위해서 여는 데 실패했습니다"),
_T("파일 열기 오류"), MB_OK | MB_ICONEXCLAMATION);
}
}
void SetCBSel(CComboBox& cb, CString& szValue, int nDefaultSel = 0)
{
CString szCBValue;
int nMaxCount = cb.GetCount();
for (int nCount = 0; nCount < nMaxCount; ++nCount)
{
cb.GetLBText(nCount, szCBValue);
if (0 == szValue.CompareNoCase(szCBValue))
{
cb.SetCurSel(nCount);
break;
}
}
if (nCount == nMaxCount)
{
// 찾아봐서 맞는 문자열이 없으면 기본값으로 선택
cb.SetCurSel(nDefaultSel);
}
}
void CSettingOptionPage::UpdateSetupData(bool bSaveAndValidate)
{
CString szValue;
struct KeyValuePair
{
LPCTSTR m_szKey;
CEdit& m_edValue;
};
KeyValuePair keyValueData[] =
{
{ PMConst::AP_OldPkg, m_edOldPkgPos },
{ PMConst::AP_NewClient, m_edNewClientPos },
{ PMConst::AP_NewPkg, m_edNewPkgPos },
{ PMConst::AP_MaxPkg, m_edMaxPkgSize },
{ PMConst::AP_FTPAddr, m_edFTPAddr },
{ PMConst::AP_FTPPort, m_edFTPPort },
{ PMConst::MP_Folder, m_edManualPatchFolder },
{ PMConst::MP_SFXFile, m_edManualPatchSFXFile }
};
const int nMaxData = sizeof(keyValueData) / sizeof(KeyValuePair);
if (!bSaveAndValidate)
{
// 셋업 맵의 데이터를 컨트롤로 저장한다.
for (int nCount = 0; nCount < nMaxData; ++nCount)
{
m_pmSettingOption.GetSettingData(keyValueData[nCount].m_szKey, szValue);
keyValueData[nCount].m_edValue.SetWindowText(szValue);
}
m_pmSettingOption.GetSettingData(PMConst::PatchType, szValue);
SetCBSel(m_cbPatchType, szValue);
m_pmSettingOption.GetSettingData(PMConst::AP_PkgPosType, szValue);
SetCBSel(m_cbPkgPos, szValue);
m_pmSettingOption.GetSettingData(PMConst::AP_FTPPassive, szValue);
m_bFTPPassive.SetCheck(0 == szValue.CompareNoCase(_T("TRUE")) ? BST_CHECKED : BST_UNCHECKED);
m_pmSettingOption.GetSettingData(PMConst::MP_MinVer, szValue);
long nVersion = atol(szValue);
if (nVersion < 100) { nVersion = 100; }
m_dwManualPatchMinVer = nVersion;
// 컨트롤 데이터를 화면에 반영한다.
UpdateData(FALSE);
}
else
{
// 화면 데이터를 컨트롤에 읽어온다.
UpdateData(TRUE);
// 컨트롤의 데이터를 셋업 맵에 저장한다.
for (int nCount = 0; nCount < nMaxData; ++nCount)
{
keyValueData[nCount].m_edValue.GetWindowText(szValue);
m_pmSettingOption.SetSettingData(keyValueData[nCount].m_szKey, szValue);
}
int nCurSel = m_cbPatchType.GetCurSel();
if (CB_ERR != nCurSel)
{
m_cbPatchType.GetLBText(nCurSel, szValue);
m_pmSettingOption.SetSettingData(PMConst::PatchType, szValue);
}
nCurSel = m_cbPkgPos.GetCurSel();
if (CB_ERR != nCurSel)
{
m_cbPkgPos.GetLBText(nCurSel, szValue);
m_pmSettingOption.SetSettingData(PMConst::AP_PkgPosType, szValue);
}
m_pmSettingOption.SetSettingData(PMConst::AP_FTPPassive,
BST_CHECKED == m_bFTPPassive.GetCheck() ? _T("TRUE") : _T("FALSE"));
szValue.Format("%u", m_dwManualPatchMinVer);
m_pmSettingOption.SetSettingData(PMConst::MP_MinVer, szValue);
}
}
bool CSettingOptionPage::IsEmptyOption()
{
if (CB_ERR == m_cbPatchType.GetCurSel() ||
0 == m_edOldPkgPos.GetWindowTextLength() ||
0 == m_edNewClientPos.GetWindowTextLength() ||
0 == m_edNewPkgPos.GetWindowTextLength() ||
0 == m_edMaxPkgSize.GetWindowTextLength() ||
CB_ERR == m_cbPkgPos.GetCurSel() ||
0 == m_edManualPatchFolder.GetWindowTextLength() ||
0 == m_edManualPatchSFXFile.GetWindowTextLength() ||
m_dwManualPatchMinVer < 100 ||
10000 < m_dwManualPatchMinVer)
{
// 빈 항목이 있으면 실패!
return true;
}
CString szPkgPos, szFTPPos((LPCTSTR)IDS_CB_FTP);
m_cbPkgPos.GetLBText(m_cbPkgPos.GetCurSel(), szPkgPos);
if (0 == szPkgPos.CompareNoCase(szFTPPos) &&
(0 == m_edFTPAddr.GetWindowTextLength() ||
0 == m_edFTPPort.GetWindowTextLength()))
{
// FTP를 선택했는데, 주소나 Port가 없으면 실패!
return true;
}
return false;
}
BOOL CSettingOptionPage::OnKillActive()
{
// TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
if (this == m_OwnerSheet.GetActivePage())
{
// 페이지를 옮기면 자동으로 저장됨
SendMessage(WM_COMMAND, MAKEWPARAM(ID_SAVE_SETUP, BN_CLICKED));
if (IsEmptyOption())
{
MessageBox(_T("기록하지 않은 설정이 있습니다. 남은 설정을 모두 입력해 주십시오"),
_T("옵션 설정"), MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
}
return CPropertyPage::OnKillActive();
}
BOOL CSettingOptionPage::OnSetActive()
{
// TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
SendMessage(WM_COMMAND, MAKEWPARAM(ID_LOAD_SETUP, BN_CLICKED));
return CPropertyPage::OnSetActive();
}
afx_msg LRESULT CSettingOptionPage::OnEnableAutoPatchOption(WPARAM wParam, LPARAM lParam)
{
SetAutoPatchOption(true);
return 0;
}
afx_msg LRESULT CSettingOptionPage::OnDisableAutoPatchOption(WPARAM wParam, LPARAM lParam)
{
SetAutoPatchOption(false);
return 0;
}
afx_msg LRESULT CSettingOptionPage::OnEnableManualPatchOption(WPARAM wParam, LPARAM lParam)
{
SetManualPatchOption(true);
return 0;
}
afx_msg LRESULT CSettingOptionPage::OnDisableManualPatchOption(WPARAM wParam, LPARAM lParam)
{
SetManualPatchOption(false);
return 0;
}
void CSettingOptionPage::SetAutoPatchOption(bool bEnable)
{
UINT nDisableID[] =
{
IDC_BTN_OPT_OLD_PKG,
IDC_BTN_OPT_NEW_CLIENT,
IDC_BTN_OPT_NEW_PKG,
};
PMUtil::EnableDlgItems(*this, nDisableID,
sizeof(nDisableID)/sizeof(UINT), bEnable);
if (bEnable && !theApp.IsManualPatchOperate())
{
// 수동패치가 작동 안할때만 Enable
m_cbPatchType.EnableWindow(TRUE);
}
else
{
m_cbPatchType.EnableWindow(FALSE);
}
m_cbPkgPos.EnableWindow(bEnable);
m_bFTPPassive.EnableWindow(bEnable);
m_edOldPkgPos.SetReadOnly(!bEnable);
m_edMaxPkgSize.SetReadOnly(!bEnable);
m_edFTPAddr.SetReadOnly(!bEnable);
m_edFTPPort.SetReadOnly(!bEnable);
}
void CSettingOptionPage::SetManualPatchOption(bool bEnable)
{
UINT nDisableID[] =
{
IDC_BTN_OPT_MANUAL_PATCH_FILE,
IDC_BTN_OPT_MANUAL_SFX_FILE
};
PMUtil::EnableDlgItems(*this, nDisableID,
sizeof(nDisableID)/sizeof(UINT), bEnable);
if (bEnable && !theApp.IsAutoPatchOperate())
{
// 자동패치가 작동 안할때만 Enable
m_cbPatchType.EnableWindow(TRUE);
}
else
{
m_cbPatchType.EnableWindow(FALSE);
}
m_edManualPatchMinVer.SetReadOnly(!bEnable);
}
void CSettingOptionPage::OnCbnSelchangeCbOptOldPkgPos()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
BOOL bEnableFTP = FALSE;
int nCurSel = m_cbPkgPos.GetCurSel();
if (CB_ERR != nCurSel)
{
CString szFTP((LPCTSTR)IDS_CB_FTP);
CString szCurrentSel;
m_cbPkgPos.GetLBText(nCurSel, szCurrentSel);
if (0 == szCurrentSel.CompareNoCase(szFTP))
{
bEnableFTP = TRUE;
}
}
m_edFTPAddr.EnableWindow(bEnableFTP);
m_edFTPPort.EnableWindow(bEnableFTP);
m_bFTPPassive.EnableWindow(bEnableFTP);
m_edOldPkgPos.SetReadOnly(!bEnableFTP);
}
void CSettingOptionPage::OnDestroy()
{
SendMessage(WM_COMMAND, MAKEWPARAM(ID_SAVE_SETUP, BN_CLICKED));
CPropertyPage::OnDestroy();
}

View File

@@ -0,0 +1,80 @@
#pragma once
#include "afxwin.h"
#include "PMSetting.h"
// CSettingOptionPage 대화 상자입니다.
class CSettingOptionPage : public CPropertyPage
{
DECLARE_DYNAMIC(CSettingOptionPage)
public:
CSettingOptionPage(CPMSetting& pmSetting, CPropertySheet& ownerSheet);
virtual ~CSettingOptionPage();
// 대화 상자 데이터입니다.
enum { IDD = IDD_SETTING_OPTION };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
DECLARE_MESSAGE_MAP()
public:
CPMSetting& GetPMSetting() { return m_pmSettingOption; }
bool IsEmptyOption();
// bSaveAndValidate가 true면, 셋업 맵의 데이터를 컨트롤로 저장
// bSaveAndValidate가 false면, 컨트롤의 데이터를 셋업 맵으로 저장
void UpdateSetupData(bool bSaveAndValidate = true);
private:
virtual BOOL OnInitDialog();
virtual BOOL OnSetActive();
virtual BOOL OnKillActive();
afx_msg void OnBnClickedBtnOptOldPkg();
afx_msg void OnBnClickedBtnOptNewClient();
afx_msg void OnBnClickedBtnOptNewPkg();
afx_msg void OnBnClickedBtnOptManualPatchFile();
afx_msg void OnBnClickedBtnOptManualSfxFile();
afx_msg void OnBnClickedSaveSetup();
afx_msg void OnBnClickedLoadSetup();
afx_msg void OnCbnSelchangeCbOptOldPkgPos();
afx_msg LRESULT OnEnableAutoPatchOption(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnDisableAutoPatchOption(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnEnableManualPatchOption(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnDisableManualPatchOption(WPARAM wParam, LPARAM lParam);
void SetAutoPatchOption(bool bEnable);
void SetManualPatchOption(bool bEnable);
CComboBox m_cbPatchType;
CEdit m_edOldPkgPos;
CEdit m_edNewClientPos;
CEdit m_edNewPkgPos;
CEdit m_edMaxPkgSize;
CComboBox m_cbPkgPos;
CEdit m_edFTPAddr;
CEdit m_edFTPPort;
CButton m_bFTPPassive;
CEdit m_edManualPatchFolder;
CEdit m_edManualPatchSFXFile;
CEdit m_edManualPatchMinVer;
DWORD m_dwManualPatchMinVer;
CPMSetting& m_pmSettingOption;
CPropertySheet& m_OwnerSheet;
public:
afx_msg void OnDestroy();
};

View File

@@ -0,0 +1,179 @@
// SettingPatchInfo.cpp : 구현 파일입니다.
//
#include "stdafx.h"
#include "PatchMaker.h"
#include "SettingPatchInfo.h"
#include "SingleInputDlg.h"
#include "UtilityFunc.h"
#include "PMSetting.h"
// CSettingPatchInfo 대화 상자입니다.
IMPLEMENT_DYNAMIC(CSettingPatchInfo, CDialog)
CSettingPatchInfo::CSettingPatchInfo(CWnd* pParent /*=NULL*/)
: CDialog(CSettingPatchInfo::IDD, pParent)
, m_dwPatchVersion(100)
, m_bSelectedNewFile(false)
, m_szSetupFileName(_T(""))
, m_szSetupName(_T(""))
{
}
CSettingPatchInfo::~CSettingPatchInfo()
{
}
void CSettingPatchInfo::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_CB_SEL_OPTION, m_cbSettingOptFile);
DDX_Text(pDX, IDC_ED_PATCHVER, m_dwPatchVersion);
DDV_MinMaxUInt(pDX, m_dwPatchVersion, 100, 10000);
}
BEGIN_MESSAGE_MAP(CSettingPatchInfo, CDialog)
ON_CBN_SELCHANGE(IDC_CB_SEL_OPTION, OnCbnSelchangeCbSelOption)
END_MESSAGE_MAP()
// CSettingPatchInfo 메시지 처리기입니다.
// 버전명, 선택한 셋업 파일 이름 등이 유효한가 여부 리턴
bool CSettingPatchInfo::CheckPatchInfo()
{
return true;
}
BOOL CSettingPatchInfo::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: 여기에 추가 초기화 작업을 추가합니다.
m_cbSettingOptFile.InsertString(0, _T("< new >"));
m_cbSettingOptFile.SetCurSel(0);
CString szFilePathName;
PMUtil::GetCurrentFolderName(szFilePathName);
szFilePathName.AppendFormat(_T("*%s"), GetExtension());
// 실행 파일 위치에서, 설정 파일을 검색해서 화면에 뿌려준다.
CFileFind fileFind;
BOOL bWorking = fileFind.FindFile(szFilePathName);
for (int nIndex = 1; bWorking; ++nIndex)
{
bWorking = fileFind.FindNextFile();
m_cbSettingOptFile.InsertString(nIndex, fileFind.GetFileTitle());
}
fileFind.Close();
return TRUE; // return TRUE unless you set the focus to a control
// 예외: OCX 속성 페이지는 FALSE를 반환해야 합니다.
}
void CSettingPatchInfo::OnOK()
{
// TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
// 세팅된 데이터를 읽어옵니다.
UpdateData(TRUE);
int nSel = m_cbSettingOptFile.GetCurSel();
m_szSetupFileName.SetString("");
m_bSelectedNewFile = false;
if (0 == nSel)
{
// 파일 이름이, 가능한 파일 이름인지 확인한다.
CSingleInputDlg singleInput(
_T("새 패치 설정 파일 이름을 입력하세요"),
_T("패치 설정 파일 이름 : "));
CFile file;
TCHAR szTempPath[MAX_PATH];
GetTempPath(MAX_PATH - 1, szTempPath);
szTempPath[MAX_PATH - 1] = 0;
CString szFullPathName;
while(!m_bSelectedNewFile)
{
if (IDOK == singleInput.DoModal())
{
szFullPathName.Format("%s%s%s", szTempPath,
singleInput.GetSingleInput(), GetExtension());
if (file.Open(szFullPathName, CFile::modeCreate))
{
m_szSetupFileName.SetString(singleInput.GetSingleInput());
m_bSelectedNewFile = true;
file.Close();
DeleteFile(szFullPathName);
}
else
{
AfxMessageBox(_T("생성할 수 없는 파일 이름입니다.\n다시 입력해 주십시오"),
MB_OK | MB_ICONEXCLAMATION);
}
}
else
{
m_szSetupFileName.SetString("");
m_bSelectedNewFile = true;
}
}
}
else
{
m_cbSettingOptFile.GetLBText(nSel, m_szSetupFileName);
}
if (0 < m_szSetupFileName.GetLength())
{
// 파일 이름 저장
m_szSetupName.SetString(m_szSetupFileName.GetString());
m_szSetupFileName.Append(GetExtension());
// 버전 정보 저장
CString szKey;
CString szValue;
szKey.SetString(m_szSetupName);
szKey.Replace(_T("="), _T("_"));
szValue.Format(_T("%u"), m_dwPatchVersion);
CPMSetting& pmSetting = CPMDefaultSetting::GetInstance();
pmSetting.SetSettingData(szKey, szValue);
pmSetting.SaveSetting();
CDialog::OnOK();
}
}
void CSettingPatchInfo::OnCbnSelchangeCbSelOption()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
CString szKey;
CString szValue;
int nCurSel = m_cbSettingOptFile.GetCurSel();
if (CB_ERR != nCurSel)
{
m_cbSettingOptFile.GetLBText(nCurSel, szKey);
szKey.Replace(_T("="), _T("_"));
if (CPMDefaultSetting::GetInstance().GetSettingData(szKey, szValue))
{
m_dwPatchVersion = atol(szValue);
UpdateData(FALSE);
}
}
}

View File

@@ -0,0 +1,46 @@
#pragma once
#include "afxwin.h"
// CSettingPatchInfo 대화 상자입니다.
class CSettingPatchInfo : public CDialog
{
DECLARE_DYNAMIC(CSettingPatchInfo)
public:
CSettingPatchInfo(CWnd* pParent = NULL); // 표준 생성자입니다.
virtual ~CSettingPatchInfo();
// 대화 상자 데이터입니다.
enum { IDD = IDD_PATCH_INFO };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
DECLARE_MESSAGE_MAP()
public:
bool CheckPatchInfo(); // 버전명, 선택한 셋업 파일 이름 등이 유효한가 여부 리턴
const CString& GetSetupFileName() const { return m_szSetupFileName; }
const CString& GetSetupName() const { return m_szSetupName; }
LPCTSTR GetExtension() const { return _T(".ini"); }
DWORD GetPatchVersion() const { return m_dwPatchVersion; }
bool IsSelectedNewFile() const { return m_bSelectedNewFile; }
virtual BOOL OnInitDialog();
virtual void OnOK();
private:
CComboBox m_cbSettingOptFile;
CString m_szSetupFileName;
CString m_szSetupName;
DWORD m_dwPatchVersion;
bool m_bSelectedNewFile;
afx_msg void OnCbnSelchangeCbSelOption();
};

View File

@@ -0,0 +1,50 @@
// SingleInputDlg.cpp : 구현 파일입니다.
//
#include "stdafx.h"
#include "PatchMaker.h"
#include "SingleInputDlg.h"
#include ".\singleinputdlg.h"
// CSingleInputDlg 대화 상자입니다.
IMPLEMENT_DYNAMIC(CSingleInputDlg, CDialog)
CSingleInputDlg::CSingleInputDlg(const CString& szTitle,
const CString& szQuestion, CWnd* pParent /*=NULL*/)
: CDialog(CSingleInputDlg::IDD, pParent)
, m_szTitle(szTitle)
, m_szQuestion(szQuestion)
, m_szSingleInput(_T(""))
{
}
CSingleInputDlg::~CSingleInputDlg()
{
}
void CSingleInputDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_INPUT_SINGLE_QUESTION, m_szQuestion);
DDX_Text(pDX, IDC_INPUT_SINGLE_LINE, m_szSingleInput);
}
BEGIN_MESSAGE_MAP(CSingleInputDlg, CDialog)
END_MESSAGE_MAP()
// CSingleInputDlg 메시지 처리기입니다.
BOOL CSingleInputDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: 여기에 추가 초기화 작업을 추가합니다.
SetWindowText(m_szTitle);
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
// 예외: OCX 속성 페이지는 FALSE를 반환해야 합니다.
}

View File

@@ -0,0 +1,35 @@
#pragma once
// CSingleInputDlg 대화 상자입니다.
class CSingleInputDlg : public CDialog
{
DECLARE_DYNAMIC(CSingleInputDlg)
public:
CSingleInputDlg(const CString& szTitle,
const CString& szQuestion, CWnd* pParent = NULL); // 표준 생성자입니다.
virtual ~CSingleInputDlg();
// 대화 상자 데이터입니다.
enum { IDD = IDD_SINGLE_INPUT };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
DECLARE_MESSAGE_MAP()
public:
const CString& GetSingleInput() const { return m_szSingleInput; }
virtual BOOL OnInitDialog();
private:
CString m_szTitle;
CString m_szQuestion;
CString m_szSingleInput;
};

View File

@@ -0,0 +1,177 @@
#include "stdafx.h"
#include "UtilityFunc.h"
#include "ShellApi.h"
bool PMUtil::BrowseForFolder(HWND hWndOwner, const char* szTitle, CString& szFolderName)
{
BROWSEINFO brInfo;
memset(&brInfo, 0, sizeof(BROWSEINFO));
TCHAR szTemp[MAX_PATH * 2];
brInfo.hwndOwner = hWndOwner;
brInfo.pidlRoot = NULL;
brInfo.pszDisplayName = szTemp;
brInfo.lpszTitle = szTitle;
brInfo.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS;
LPITEMIDLIST lpItemIDList = SHBrowseForFolder(&brInfo);
if (NULL != lpItemIDList && SHGetPathFromIDList(lpItemIDList, szTemp))
{
szTemp[MAX_PATH * 2 - 1] = (TCHAR)0;
szFolderName.SetString(szTemp);
szFolderName.Trim();
// 경로 설정이므로, 맨 마지막 글자가 역슬래쉬로 끝나지 않을 경우, 역슬래쉬를 붙여 준다.
int nLength = szFolderName.GetLength();
if (1 < nLength && _T('\\') != szFolderName.GetString()[nLength - 1])
{
szFolderName.Append(_T("\\"));
}
return true;
}
return false;
}
bool PMUtil::BrowseForFolder(HWND hWndOwner, LPCTSTR szTitle, CEdit& edFolderName)
{
CString szFolderName;
if (BrowseForFolder(hWndOwner, szTitle, szFolderName) &&
!szFolderName.IsEmpty())
{
edFolderName.SetWindowText(szFolderName);
return true;
}
return false;
}
bool PMUtil::BrowseForExisingFile(HWND hWndOwner, const char* szTitle,
const char* szFilter, CString& szFilePathName)
{
TCHAR szTemp[MAX_PATH * 2];
memset(szTemp, 0, sizeof(TCHAR) * MAX_PATH * 2);
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWndOwner;
ofn.lpstrFilter = szFilter;
ofn.lpstrFile = szTemp;
ofn.nMaxFile = MAX_PATH * 2;
ofn.lpstrTitle = szTitle;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
if (GetOpenFileName(&ofn))
{
szFilePathName.SetString(szTemp);
return true;
}
return false;
}
bool PMUtil::BrowseForNewFile(HWND hWndOwner, const char* szTitle,
const char* szFilter, const char* szDefExt, CString& szFilePathName)
{
TCHAR szTemp[MAX_PATH * 2];
memset(szTemp, 0, sizeof(TCHAR) * MAX_PATH * 2);
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWndOwner;
ofn.lpstrFilter = szFilter;
ofn.lpstrDefExt = szFilter;
ofn.lpstrFile = szTemp;
ofn.nMaxFile = MAX_PATH * 2;
ofn.lpstrTitle = szTitle;
ofn.Flags = OFN_EXPLORER | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
if (GetSaveFileName(&ofn))
{
szFilePathName.SetString(szTemp);
return true;
}
return false;
}
void PMUtil::GetCurrentFolderName(CString& szCurrentFolderName)
{
TCHAR szFullPathName[MAX_PATH * 2];
GetModuleFileName(NULL, szFullPathName, MAX_PATH * 2 - 1);
szFullPathName[MAX_PATH * 2 - 1] = 0;
TCHAR szDrive[MAX_PATH];
TCHAR szDirectory[MAX_PATH];
_tsplitpath(szFullPathName, szDrive, szDirectory, 0, 0);
szCurrentFolderName.Format("%s%s", szDrive, szDirectory);
}
void PMUtil::EnableDlgItems(CWnd& wnd, UINT* nIDs, int nIDNum, bool bEnable)
{
if (0 != nIDs)
{
CWnd* lpWnd = 0;
for (int nCount = 0; nCount < nIDNum; ++nCount)
{
if (0 != (lpWnd = wnd.GetDlgItem(nIDs[nCount])))
{
lpWnd->EnableWindow(bEnable);
}
}
}
}
void PMUtil::SetCurrentDayTime(CString& szString)
{
szString.SetString(CTime::GetCurrentTime().Format(_T("[%Y-%m-%d %H:%M:%S]")));
}
void PMUtil::SetCurrentTime(CString& szString)
{
szString.SetString(CTime::GetCurrentTime().Format(_T("[%H:%M:%S]")));
}
void PMUtil::SetErrorMessage(LPTSTR lpStr, DWORD dwMaxLen, DWORD dwErrorCode)
{
// 메시지를 포매팅한다.
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0,
dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
lpStr, dwMaxLen - 1, 0);
lpStr[dwMaxLen - 1] = 0;
// 마지막 캐리지-리턴을 제거한다.
TCHAR* lpPtr = _tcsrchr(lpStr, _T('\r'));
if (0 != lpPtr) { *lpPtr = _T('\0'); }
}
void PMUtil::SetErrorMessage(CString& szString, DWORD dwErrorCode)
{
const DWORD MAX_BUFFER = 256;
TCHAR szErrorMsg[MAX_BUFFER];
SetErrorMessage(szErrorMsg, MAX_BUFFER, dwErrorCode);
szString.SetString(szErrorMsg);
}
void PMUtil::AppendErrorMessage(CString& szString, DWORD dwErrorCode)
{
const DWORD MAX_BUFFER = 256;
TCHAR szErrorMsg[MAX_BUFFER];
SetErrorMessage(szErrorMsg, MAX_BUFFER, dwErrorCode);
szString.Append(szErrorMsg);
}

View File

@@ -0,0 +1,32 @@
#pragma once
namespace PMUtil
{
// 폴더 브라우징
bool BrowseForFolder(HWND hWndOwner, LPCTSTR szTitle, CString& szFolderName);
bool BrowseForFolder(HWND hWndOwner, LPCTSTR szTitle, CEdit& edFolderName);
// 있는 파일 브라우징
bool BrowseForExisingFile(HWND hWndOwner, LPCTSTR szTitle,
LPCTSTR szFilter, CString& szFilePathName);
// 새 파일 브라우징
bool BrowseForNewFile(HWND hWndOwner, LPCTSTR szTitle,
LPCTSTR szFilter, LPCTSTR szDefExt, CString& szFilePathName);
// 현재 실행파일이 위치한 곳 폴더 가져오기
void GetCurrentFolderName(CString& szCurrentFolderName);
// 특정 윈도우의 차일드 컨트롤들을 전부 Enable하거나 Disable한다.
void EnableDlgItems(CWnd& wnd, UINT* nIDs, int nIDNum, bool bEnable);
// 현재 시간을 문자열에 세팅
void SetCurrentDayTime(CString& szString);
void SetCurrentTime(CString& szString);
// 메시지를 포매팅한다.
void SetErrorMessage(LPTSTR lpStr, DWORD dwMaxLen, DWORD dwErrorCode);
void SetErrorMessage(CString& szString, DWORD dwErrorCode);
void AppendErrorMessage(CString& szString, DWORD dwErrorCode);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="Microsoft.Windows.PatchMaker"
type="win32"
/>
<description>여기에 응용 프로그램 설명을 추가합니다.</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

View File

@@ -0,0 +1,13 @@
//
// PatchMaker.RC2 - resources Microsoft Visual C++에서 직접 편집하지 않는 리소스
//
#ifdef APSTUDIO_INVOKED
#error 이 파일은 Microsoft Visual C++에서 편집할 수 없습니다.
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// 여기에 수동으로 편집한 리소스를 추가합니다.
/////////////////////////////////////////////////////////////////////////////

101
Tools/PatchMaker/resource.h Normal file
View File

@@ -0,0 +1,101 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by PatchMaker.rc
//
#define IDM_ABOUTBOX 0x0010
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define IDD_PATCH_INFO 103
#define IDD_SINGLE_INPUT 104
#define IDS_MIN_VER 104
#define IDD_SETTING_OPTION 105
#define IDS_MAX_VER 105
#define IDD_AUTO_PATCH 106
#define IDS_CB_PART1 106
#define IDD_MANUAL_PATCH 107
#define IDS_CB_BATTLELOHAN_P1 107
#define IDD_CHECKSUM 108
#define IDS_CB_PART2 108
#define IDS_CB_PART2_TEST 109
#define IDS_CB_PART2_MALAY 110
#define IDS_CB_FTP 111
#define IDS_CB_LOCAL 112
#define IDS_INSTALLED_REGKEY 120
#define IDS_FOLDER_P1 121
#define IDS_FOLDER_BATTLELOHAN 122
#define IDS_FOLDER_P2 123
#define IDS_FOLDER_P2_TEST 124
#define IDS_FOLDER_P2_MALAY 125
#define IDS_INSTALLED_REGKEY_MALAY 125
#define IDR_MAINFRAME 128
#define ID_SAVE_SETUP 1000
#define IDC_CB_SEL_OPTION 1001
#define ID_LOAD_SETUP 1001
#define IDC_ED_PATCHVER 1002
#define ID_CREATE_MP 1002
#define ID_MP_CREATE 1002
#define IDC_EDIT1 1003
#define IDC_INPUT_SINGLE_LINE 1003
#define IDC_ED_OPT_FTP_ADDR 1003
#define IDC_ED_AP_CONSOLE 1003
#define IDC_ED_MP_CUR_VER 1003
#define IDC_INPUT_SINGLE_QUESTION 1004
#define IDC_ED_OPT_FTP_PORT 1004
#define IDC_ED_MP_CONSOLE 1004
#define IDC_ED_OPT_OLD_PKG 1005
#define ID_MP_CANCEL 1005
#define IDC_ED_OPT_NEW_CLIENT 1006
#define IDC_CLEAR_LOG 1006
#define IDC_ED_OPT_NEW_PKG 1007
#define IDC_ED_OPT_MAX_PKG 1008
#define IDC_ED_OPT_MANUAL_PATCH_FILE 1009
#define IDC_ED_OPT_MANUAL_SFX_FILE 1010
#define IDC_ED_AP_FTP_ADDR 1010
#define IDC_ED_OPT_MANUAL_MIN_VER 1011
#define IDC_ED_AP_OLD_PKG_POS 1011
#define IDC_ED_MP_PATCH_FILE_NAME 1012
#define IDC_CB_OPT_PATCH_TYPE 1013
#define IDC_CK_OPT_FTP_PASSIVE 1014
#define IDC_CB_OPT_OLD_PKG_POS 1015
#define IDC_BTN_OPT_OLD_PKG 1016
#define IDC_BTN_OPT_NEW_CLIENT 1017
#define IDC_PRG_AP 1017
#define IDC_BTN_OPT_NEW_PKG 1018
#define IDC_ED_AP_ERR_CONSOLE 1018
#define IDC_BTN_OPT_MANUAL_PATCH_FILE 1019
#define IDC_ED_AP_FTP_ID 1019
#define IDC_BTN_OPT_MANUAL_SFX_FILE 1020
#define IDC_ED_AP_FTP_PW 1020
#define IDC_BTN_MP_SELECT_FILE 1021
#define IDC_BTN_OPT_NEW_PKG2 1022
#define IDC_ED_AP_PATCH_TYPE 1023
#define IDC_ED_AP_FTP_PORT 1024
#define IDC_CK_AP_FTP_PASSIVE 1025
#define IDC_ED_AP_OLD_PKG 1026
#define IDC_ED_AP_NEW_CLIENT 1027
#define IDC_ED_AP_NEW_PKG 1028
#define IDC_ED_AP_MAX_PKG 1029
#define IDC_ST_AP_PRORGRESS 1030
#define IDC_ED_AP_PATCH_VER 1031
#define IDC_ED_MP_PATCH_TYPE 1031
#define IDC_ED_MP_MANUAL_PATCH_FILE 1032
#define IDC_ED_MP_MANUAL_SFX_FILE 1033
#define IDC_ED_MP_MIN_VER 1034
#define IDC_PRG_MP 1035
#define IDC_ST_MP_PRORGRESS 1036
#define IDC_ED_MP_ERR_CONSOLE 1037
#define IDC_ED_CK_PKG_POS 1038
#define IDC_BTN_CK_PKG_POS 1039
#define IDC_ED_CK_PKG_VER 1040
#define IDC_ED_CK_CHECKSUM 1041
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1007
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif

View File

@@ -0,0 +1,7 @@
// stdafx.cpp : 표준 포함 파일을 포함하는 소스 파일입니다.
// PatchMaker.pch는 미리 컴파일된 헤더가 됩니다.
// stdafx.obj는 미리 컴파일된 형식 정보를 포함합니다.
#include "stdafx.h"

43
Tools/PatchMaker/stdafx.h Normal file
View 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 <afxdtctl.h> // Internet Explorer 4 공용 컨트롤에 대한 MFC 지원
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // Windows 공용 컨트롤에 대한 MFC 지원
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxdlgs.h>
#include <afxdhtml.h>