Path::createFolder支持一次性创建多级目录;String不再允许隐式转换成const wchar_t* 类型

This commit is contained in:
Nomango 2018-05-24 14:33:16 +08:00
parent 6af90623fa
commit 868238e42b
11 changed files with 104 additions and 142 deletions

View File

@ -25,7 +25,8 @@ bool e2d::Game::init(const String& name, const String& mutexName)
if (!mutexName.isEmpty()) if (!mutexName.isEmpty())
{ {
// 创建进程互斥体 // 创建进程互斥体
HANDLE hMutex = ::CreateMutex(nullptr, TRUE, L"Easy2DApp-" + mutexName); String fullMutexName = L"Easy2DApp-" + mutexName;
HANDLE hMutex = ::CreateMutex(nullptr, TRUE, (LPCWSTR)fullMutexName);
if (hMutex == nullptr) if (hMutex == nullptr)
{ {
@ -114,15 +115,15 @@ bool e2d::Game::init(const String& name, const String& mutexName)
throw SystemException(L"初始化 XAudio2 失败"); throw SystemException(L"初始化 XAudio2 失败");
} }
// ±£´æÓÎÏ·Ãû³Æ
s_sGameName = name;
// 初始化路径 // 初始化路径
if (!Path::__init()) if (!Path::__init(name))
{ {
WARN("Path::__init failed!"); WARN("Path::__init failed!");
} }
// ±£´æÓÎÏ·Ãû³Æ
s_sGameName = name;
// 初始化成功 // 初始化成功
s_bInitialized = true; s_bInitialized = true;

View File

@ -194,7 +194,7 @@ void e2d::Renderer::__render()
IDWriteTextLayout * pTextLayout = nullptr; IDWriteTextLayout * pTextLayout = nullptr;
hr = s_pDWriteFactory->CreateTextLayout( hr = s_pDWriteFactory->CreateTextLayout(
s_sFpsText, (const WCHAR *)s_sFpsText,
(UINT32)s_sFpsText.getLength(), (UINT32)s_sFpsText.getLength(),
s_pTextFormat, s_pTextFormat,
0, 0,

View File

@ -177,7 +177,7 @@ void e2d::Window::setSize(int width, int height)
void e2d::Window::setTitle(const String& title) void e2d::Window::setTitle(const String& title)
{ {
// ÉèÖô°¿Ú±êÌâ // ÉèÖô°¿Ú±êÌâ
::SetWindowText(s_HWnd, title); ::SetWindowText(s_HWnd, (LPCWSTR)title);
} }
void e2d::Window::setIcon(int iconID) void e2d::Window::setIcon(int iconID)
@ -293,19 +293,19 @@ void e2d::Window::setTypewritingEnable(bool enable)
void e2d::Window::info(const String & text, const String & title) void e2d::Window::info(const String & text, const String & title)
{ {
::MessageBox(s_HWnd, text, title, MB_ICONINFORMATION | MB_OK); ::MessageBox(s_HWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONINFORMATION | MB_OK);
Game::reset(); Game::reset();
} }
void e2d::Window::warning(const String& title, const String& text) void e2d::Window::warning(const String& title, const String& text)
{ {
::MessageBox(s_HWnd, text, title, MB_ICONWARNING | MB_OK); ::MessageBox(s_HWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONWARNING | MB_OK);
Game::reset(); Game::reset();
} }
void e2d::Window::error(const String & text, const String & title) void e2d::Window::error(const String & text, const String & title)
{ {
::MessageBox(s_HWnd, text, title, MB_ICONERROR | MB_OK); ::MessageBox(s_HWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONERROR | MB_OK);
Game::reset(); Game::reset();
} }

View File

@ -170,7 +170,7 @@ bool e2d::Image::preload(const String& filePath)
// 创建解码器 // 创建解码器
hr = Renderer::getIWICImagingFactory()->CreateDecoderFromFilename( hr = Renderer::getIWICImagingFactory()->CreateDecoderFromFilename(
filePath, (LPCWSTR)filePath,
nullptr, nullptr,
GENERIC_READ, GENERIC_READ,
WICDecodeMetadataCacheOnLoad, WICDecodeMetadataCacheOnLoad,
@ -254,7 +254,7 @@ bool e2d::Image::preload(int resNameId, const String& resType)
DWORD imageFileSize = 0; DWORD imageFileSize = 0;
// 定位资源 // 定位资源
imageResHandle = ::FindResourceW(HINST_THISCOMPONENT, MAKEINTRESOURCE(resNameId), resType); imageResHandle = ::FindResourceW(HINST_THISCOMPONENT, MAKEINTRESOURCE(resNameId), (LPCWSTR)resType);
hr = imageResHandle ? S_OK : E_FAIL; hr = imageResHandle ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))

View File

@ -364,6 +364,11 @@ std::string e2d::String::getCString() const
return std::move(str); return std::move(str);
} }
wchar_t e2d::String::at(int index) const
{
return _str[size_t(index)];
}
int e2d::String::compare(const String & str) const int e2d::String::compare(const String & str) const
{ {
return _str.compare(str._str); return _str.compare(str._str);
@ -449,9 +454,9 @@ void e2d::String::replace(const String & from, const String & to)
return; return;
size_t start_pos = 0; size_t start_pos = 0;
while ((start_pos = _str.find(from, start_pos)) != std::string::npos) while ((start_pos = _str.find((const wchar_t *)from, start_pos)) != std::string::npos)
{ {
_str.replace(start_pos, from._str.length(), to); _str.replace(start_pos, from._str.length(), (const wchar_t *)to);
start_pos += to._str.length(); start_pos += to._str.length();
} }
} }

View File

@ -321,7 +321,7 @@ void e2d::Text::_createFormat()
SafeRelease(_textFormat); SafeRelease(_textFormat);
HRESULT hr = Renderer::getIDWriteFactory()->CreateTextFormat( HRESULT hr = Renderer::getIDWriteFactory()->CreateTextFormat(
_font.family, (const WCHAR *)_font.family,
nullptr, nullptr,
DWRITE_FONT_WEIGHT(_font.weight), DWRITE_FONT_WEIGHT(_font.weight),
_font.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, _font.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
@ -391,7 +391,7 @@ void e2d::Text::_createLayout()
if (_style.wrapping) if (_style.wrapping)
{ {
hr = Renderer::getIDWriteFactory()->CreateTextLayout( hr = Renderer::getIDWriteFactory()->CreateTextLayout(
_text, (const WCHAR *)_text,
length, length,
_textFormat, _textFormat,
float(_style.wrappingWidth), float(_style.wrappingWidth),
@ -409,7 +409,7 @@ void e2d::Text::_createLayout()
} }
else else
{ {
hr = Renderer::getIDWriteFactory()->CreateTextLayout(_text, length, _textFormat, 0, 0, &_textLayout); hr = Renderer::getIDWriteFactory()->CreateTextLayout((const WCHAR *)_text, length, _textFormat, 0, 0, &_textLayout);
// 为防止文本对齐问题,根据刚才创建的 layout 宽度重新创建它 // 为防止文本对齐问题,根据刚才创建的 layout 宽度重新创建它
if (_textLayout) if (_textLayout)
{ {
@ -420,7 +420,7 @@ void e2d::Text::_createLayout()
this->setSize(metrics.width, metrics.height); this->setSize(metrics.width, metrics.height);
// 重新创建 layout // 重新创建 layout
SafeRelease(_textLayout); SafeRelease(_textLayout);
hr = Renderer::getIDWriteFactory()->CreateTextLayout(_text, length, _textFormat, _width, 0, &_textLayout); hr = Renderer::getIDWriteFactory()->CreateTextLayout((const WCHAR *)_text, length, _textFormat, _width, 0, &_textLayout);
} }
} }

View File

@ -1,64 +1,48 @@
#include "..\e2dtool.h" #include "..\e2dtool.h"
static e2d::String s_sDataFileName = L"DefaultData.ini";
void e2d::Data::saveInt(const String& key, int value, const String& field) void e2d::Data::saveInt(const String& key, int value, const String& field)
{ {
::WritePrivateProfileString(field, key, String::parse(value), Data::getDataFilePath()); ::WritePrivateProfileString((LPCWSTR)field, (LPCWSTR)key, (LPCWSTR)String::parse(value), (LPCWSTR)Path::getDataSavePath());
} }
void e2d::Data::saveDouble(const String& key, double value, const String& field) void e2d::Data::saveDouble(const String& key, double value, const String& field)
{ {
::WritePrivateProfileString(field, key, String::parse(value), Data::getDataFilePath()); ::WritePrivateProfileString((LPCWSTR)field, (LPCWSTR)key, (LPCWSTR)String::parse(value), (LPCWSTR)Path::getDataSavePath());
} }
void e2d::Data::saveBool(const String& key, bool value, const String& field) void e2d::Data::saveBool(const String& key, bool value, const String& field)
{ {
const wchar_t* sValue = value ? L"1" : L"0"; ::WritePrivateProfileString((LPCWSTR)field, (LPCWSTR)key, (value ? L"1" : L"0"), (LPCWSTR)Path::getDataSavePath());
::WritePrivateProfileString(field, key, sValue, Data::getDataFilePath());
} }
void e2d::Data::saveString(const String& key, const String& value, const String& field) void e2d::Data::saveString(const String& key, const String& value, const String& field)
{ {
::WritePrivateProfileString(field, key, value, Data::getDataFilePath()); ::WritePrivateProfileString((LPCWSTR)field, (LPCWSTR)key, (LPCWSTR)value, (LPCWSTR)Path::getDataSavePath());
} }
int e2d::Data::getInt(const String& key, int defaultValue, const String& field) int e2d::Data::getInt(const String& key, int defaultValue, const String& field)
{ {
return ::GetPrivateProfileInt(field, key, defaultValue, Data::getDataFilePath()); return ::GetPrivateProfileInt((LPCWSTR)field, (LPCWSTR)key, defaultValue, (LPCWSTR)Path::getDataSavePath());
} }
double e2d::Data::getDouble(const String& key, double defaultValue, const String& field) double e2d::Data::getDouble(const String& key, double defaultValue, const String& field)
{ {
wchar_t temp[32] = { 0 }; wchar_t temp[32] = { 0 };
::GetPrivateProfileString(field, key, String::parse(defaultValue), temp, 31, Data::getDataFilePath()); ::GetPrivateProfileString((LPCWSTR)field, (LPCWSTR)key, (LPCWSTR)String::parse(defaultValue), temp, 31, (LPCWSTR)Path::getDataSavePath());
return std::stof(temp); return std::stof(temp);
} }
bool e2d::Data::getBool(const String& key, bool defaultValue, const String& field) bool e2d::Data::getBool(const String& key, bool defaultValue, const String& field)
{ {
int nDefaultValue = defaultValue ? 1 : 0; int nDefaultValue = defaultValue ? 1 : 0;
int nValue = ::GetPrivateProfileInt(field, key, nDefaultValue, Data::getDataFilePath()); int nValue = ::GetPrivateProfileInt((LPCWSTR)field, (LPCWSTR)key, nDefaultValue, (LPCWSTR)Path::getDataSavePath());
return nValue != 0; return nValue != 0;
} }
e2d::String e2d::Data::getString(const String& key, const String& defaultValue, const String& field) e2d::String e2d::Data::getString(const String& key, const String& defaultValue, const String& field)
{ {
wchar_t temp[256] = { 0 }; wchar_t temp[256] = { 0 };
::GetPrivateProfileString(field, key, defaultValue, temp, 255, Data::getDataFilePath()); ::GetPrivateProfileString((LPCWSTR)field, (LPCWSTR)key, (LPCWSTR)defaultValue, temp, 255, (LPCWSTR)Path::getDataSavePath());
return temp; return temp;
} }
void e2d::Data::setDataFileName(const String& fileName)
{
if (!fileName.isEmpty())
{
s_sDataFileName.clear();
s_sDataFileName << fileName << L".ini";
}
}
e2d::String e2d::Data::getDataFilePath()
{
return Path::getDefaultSavePath() + s_sDataFileName;
}

View File

@ -93,7 +93,7 @@ bool e2d::Music::open(const e2d::String& filePath)
// 定位 wave 文件 // 定位 wave 文件
wchar_t pFilePath[MAX_PATH]; wchar_t pFilePath[MAX_PATH];
if (!_findMediaFileCch(pFilePath, MAX_PATH, filePath)) if (!_findMediaFileCch(pFilePath, MAX_PATH, (const wchar_t *)filePath))
{ {
WARN("Failed to find media file: %s", pFilePath); WARN("Failed to find media file: %s", pFilePath);
return false; return false;
@ -162,7 +162,7 @@ bool e2d::Music::open(int resNameId, const e2d::String& resType)
return false; return false;
} }
if (nullptr == (hResInfo = FindResourceW(HINST_THISCOMPONENT, MAKEINTRESOURCE(resNameId), resType))) if (nullptr == (hResInfo = FindResourceW(HINST_THISCOMPONENT, MAKEINTRESOURCE(resNameId), (LPCWSTR)resType)))
return TraceError(L"FindResource"); return TraceError(L"FindResource");
if (nullptr == (hResData = LoadResource(HINST_THISCOMPONENT, hResInfo))) if (nullptr == (hResData = LoadResource(HINST_THISCOMPONENT, hResInfo)))

View File

@ -11,9 +11,9 @@ DEFINE_KNOWN_FOLDER(FOLDERID_LocalAppData, 0xF1B32785, 0x6FBA, 0x4FCF, 0x9D, 0x5
static e2d::String s_sLocalAppDataPath; static e2d::String s_sLocalAppDataPath;
static e2d::String s_sTempPath; static e2d::String s_sTempPath;
static e2d::String s_sDefaultSavePath; static e2d::String s_sDataSavePath;
bool e2d::Path::__init() bool e2d::Path::__init(const String& gameName)
{ {
// 获取 AppData\Local 文件夹的路径 // 获取 AppData\Local 文件夹的路径
typedef HRESULT(WINAPI* pFunSHGetKnownFolderPath)(const GUID& rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); typedef HRESULT(WINAPI* pFunSHGetKnownFolderPath)(const GUID& rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath);
@ -30,93 +30,47 @@ bool e2d::Path::__init()
} }
else else
{ {
WARN("Cannot get local AppData path!"); WARN("Get local AppData path failed!");
return false;
} }
// 获取游戏名称
String sGameName = Game::getName();
// 获取默认保存路径 // 获取数据的默认保存路径
bool bInitSavePath = false; s_sDataSavePath = s_sLocalAppDataPath + L"\\Easy2DGameData\\";
do if (!gameName.isEmpty())
{ {
String localAppPath = s_sLocalAppDataPath; s_sDataSavePath << gameName << L"\\";
if (localAppPath.isEmpty()) }
if (!Path::existsFolder(s_sDataSavePath))
{
if (!Path::createFolder(s_sDataSavePath))
{ {
s_sDataSavePath = L"";
break;
} }
else }
{ s_sDataSavePath << L"Data.ini";
s_sDefaultSavePath = localAppPath;
}
localAppPath << L"\\Easy2DGameData";
if (Path::createFolder(localAppPath))
{
s_sDefaultSavePath = localAppPath;
}
else
{
break;
}
if (!sGameName.isEmpty())
{
localAppPath << L"\\" << sGameName;
// 创建文件夹
if (Path::createFolder(localAppPath))
{
s_sDefaultSavePath = localAppPath;
}
}
s_sDefaultSavePath << L"\\";
bInitSavePath = true;
} while (0);
// 获取临时文件目录 // 获取临时文件目录
bool bInitTempPath = false; wchar_t path[_MAX_PATH];
do if (0 == ::GetTempPath(_MAX_PATH, path))
{ {
wchar_t path[_MAX_PATH]; return false;
if (0 == ::GetTempPath(_MAX_PATH, path)) }
{
break;
}
else
{
s_sTempPath = path;
}
// 创建临时文件目录 s_sTempPath << path << L"\\Easy2DGameTemp\\";
String tempPath; if (!gameName.isEmpty())
tempPath << s_sTempPath << L"\\Easy2DGameTemp"; {
// 创建文件夹 s_sTempPath << gameName << L"\\";
if (Path::createFolder(tempPath)) }
{
s_sTempPath = path;
}
else
{
break;
}
if (!sGameName.isEmpty()) if (!Path::existsFolder(s_sTempPath))
{
if (!Path::createFolder(s_sTempPath))
{ {
tempPath << L"\\" << sGameName; s_sTempPath = L"";
// 创建文件夹
if (Path::createFolder(tempPath))
{
s_sTempPath = tempPath;
}
} }
}
s_sTempPath << L"\\"; return true;
bInitTempPath = true;
} while (0);
return SUCCEEDED(hr) && bInitSavePath && bInitTempPath;
} }
e2d::String e2d::Path::getTempPath() e2d::String e2d::Path::getTempPath()
@ -124,9 +78,9 @@ e2d::String e2d::Path::getTempPath()
return s_sTempPath; return s_sTempPath;
} }
e2d::String e2d::Path::getDefaultSavePath() e2d::String e2d::Path::getDataSavePath()
{ {
return s_sDefaultSavePath; return s_sDataSavePath;
} }
e2d::String e2d::Path::getFileExtension(const String& filePath) e2d::String e2d::Path::getFileExtension(const String& filePath)
@ -159,8 +113,8 @@ e2d::String e2d::Path::getSaveFilePath(const String& title, const String& defExt
ofn.nMaxFile = sizeof(strFilename); // 缓冲区长度 ofn.nMaxFile = sizeof(strFilename); // 缓冲区长度
ofn.lpstrInitialDir = nullptr; // 初始目录为默认 ofn.lpstrInitialDir = nullptr; // 初始目录为默认
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
ofn.lpstrTitle = title; // 标题 ofn.lpstrTitle = (LPCWSTR)title; // 标题
ofn.lpstrDefExt = defExt; // 默认追加的扩展名 ofn.lpstrDefExt = (LPCWSTR)defExt; // 默认追加的扩展名
if (GetSaveFileName(&ofn)) if (GetSaveFileName(&ofn))
{ {
@ -171,18 +125,32 @@ e2d::String e2d::Path::getSaveFilePath(const String& title, const String& defExt
bool e2d::Path::createFolder(const String& dirPath) bool e2d::Path::createFolder(const String& dirPath)
{ {
if (dirPath.isEmpty()) if (dirPath.isEmpty() || dirPath.getLength() >= MAX_PATH)
{ {
WARN("Path::createFolder Failed: Invalid directory path!");
return false; return false;
} }
if (-1 == ::_waccess(dirPath, 0)) wchar_t tmpDirPath[_MAX_PATH] = { 0 };
int length = dirPath.getLength();
for (int i = 0; i < length; ++i)
{ {
if (0 != ::_wmkdir(dirPath)) tmpDirPath[i] = dirPath.at(i);
if (tmpDirPath[i] == L'\\' || tmpDirPath[i] == L'/' || i == (length - 1))
{ {
return false; if (::_waccess(tmpDirPath, 0) != 0)
{
if (::_wmkdir(tmpDirPath) != 0)
{
return false;
}
}
} }
} }
return true; return true;
} }
bool e2d::Path::existsFolder(const String & dirPath)
{
return ::_waccess((const wchar_t *)dirPath, 0) == 0;
}

View File

@ -147,6 +147,11 @@ public:
// »ñÈ¡ ANSI ×Ö·û´® // »ñÈ¡ ANSI ×Ö·û´®
std::string getCString() const; std::string getCString() const;
// »ñȡָ¶¨Î»ÖÃ×Ö·û
wchar_t at(
int index
) const;
// ±È½Ï×Ö·û´® // ±È½Ï×Ö·û´®
int compare( int compare(
const String & str const String & str
@ -231,8 +236,8 @@ public:
friend class String operator+ (const wchar_t*, const String &); friend class String operator+ (const wchar_t*, const String &);
// ÀàÐÍת»»²Ù×÷·û // ÀàÐÍת»»²Ù×÷·û
operator const wchar_t* () const; explicit operator const wchar_t* () const;
operator wchar_t* () const; explicit operator wchar_t* () const;
// ±È½ÏÔËËã·û // ±È½ÏÔËËã·û
bool operator== (const String &) const; bool operator== (const String &) const;

View File

@ -433,14 +433,6 @@ public:
const String& defaultValue, /* 默认值 */ const String& defaultValue, /* 默认值 */
const String& field = L"Defalut" /* 字段名称 */ const String& field = L"Defalut" /* 字段名称 */
); );
// 修改数据文件的名称
static void setDataFileName(
const String& filePath /* 文件名称 */
);
// 获取数据文件的完整路径
static String getDataFilePath();
}; };
@ -451,7 +443,7 @@ class Path
public: public:
// 获取数据的默认保存路径 // 获取数据的默认保存路径
static String getDefaultSavePath(); static String getDataSavePath();
// 获取临时文件目录 // 获取临时文件目录
static String getTempPath(); static String getTempPath();
@ -472,9 +464,16 @@ public:
const String& dirPath /* 文件夹路径 */ const String& dirPath /* 文件夹路径 */
); );
// 判断文件夹是否存在
static bool existsFolder(
const String& dirPath /* 文件夹路径 */
);
private: private:
// 初始化 // 初始化
static bool __init(); static bool __init(
const String& gameName
);
}; };
} }