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>
178 lines
4.6 KiB
C++
178 lines
4.6 KiB
C++
#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);
|
|
}
|