diff --git a/CMakeLists.txt b/CMakeLists.txt
index 88beee75..b7bcb23b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -59,6 +59,37 @@ OPTION(USE_DMSKIA_ "DM user skia render draw" OFF)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Tools/CMake)
INCLUDE(PrecompiledHeader)
+# --- The compiler flags
+message("-- Building REDM with cpp${_CXX_STD} support")
+if ( IOS )
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode" CACHE INTERNAL "CMAKE_CXX_FLAGS")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode" CACHE INTERNAL "CMAKE_C_FLAGS")
+endif ()
+if (NOT WIN32 OR CYGWIN)
+ if (_CXX_STD EQUAL 17)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z" CACHE INTERNAL "CMAKE_CXX_FLAGS")
+ if ( IOS )
+ # Aligned deallocation function of type 'void (void *, std::align_val_t) noexcept' is only available on iOS 11 or newer
+ # most of time, low level malloc will alloc a aligned address for new operator,
+ # so it's ok to add -faligned-allocation, certainly, still need find a ios9.0 device
+ # to test does it works well?
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -faligned-allocation" CACHE INTERNAL "CMAKE_CXX_FLAGS")
+ endif()
+ elseif(_CXX_STD EQUAL 14)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y" CACHE INTERNAL "CMAKE_CXX_FLAGS")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" CACHE INTERNAL "CMAKE_CXX_FLAGS")
+ endif()
+else()
+ if(_CXX_STD EQUAL 17)
+ # target_compile_features(REDM PUBLIC cxx_std_17) works
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17" CACHE INTERNAL "CMAKE_CXX_FLAGS")
+ elseif(_CXX_STD EQUAL 14)
+ # target_compile_features(REDM PUBLIC cxx_std_14) not works
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++14" CACHE INTERNAL "CMAKE_CXX_FLAGS")
+ endif()
+endif()
+
# 增加子文件夹
ADD_SUBDIRECTORY(${PROJDIR}/DmMain)
ADD_SUBDIRECTORY(${PROJDIR}/Samples/DMDemo)
@@ -77,4 +108,4 @@ ADD_SUBDIRECTORY(${PROJDIR}/3rdParty/lua)
ADD_SUBDIRECTORY(${PROJDIR}/3rdParty/scintilla)
if(USE_DMSKIA_)
ADD_SUBDIRECTORY(${PROJDIR}/3rdParty/skia)
-endif()
\ No newline at end of file
+endif()
diff --git a/DmMain/CMakeLists.txt b/DmMain/CMakeLists.txt
index 4a352971..230ce733 100644
--- a/DmMain/CMakeLists.txt
+++ b/DmMain/CMakeLists.txt
@@ -177,6 +177,7 @@ target_include_directories(DmMain
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc/Modules/Skin
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc/Modules/Task
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc/Widgets
+ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../External
)
SET_TARGET_PROPERTIES(DmMain PROPERTIES OUTPUT_NAME "DmMain")
diff --git a/DmMain/inc/Common/Template/DMStringT.h b/DmMain/inc/Common/Template/DMStringT.h
index e69c2646..e215b2bb 100644
--- a/DmMain/inc/Common/Template/DMStringT.h
+++ b/DmMain/inc/Common/Template/DMStringT.h
@@ -19,6 +19,8 @@
#define TSTRING_PADDING 0
#endif
+#include "ntcvt/ntcvt.hpp"
+
namespace DM
{
__pragma(warning(push))
@@ -1676,74 +1678,6 @@ namespace DM
typedef CStringA CStringT;
#endif
- static CStringW DMA2W(const CStringA &str, UINT CodePage=CP_ACP)
- {
- int nSize = ::MultiByteToWideChar(CodePage, 0, str, str.GetLength(), NULL, 0);
- if (nSize>0)
- {
- wchar_t *pBuf=new wchar_t[nSize];
- ::MultiByteToWideChar(CodePage, 0, str, str.GetLength(), pBuf, nSize);
- CStringW strw(pBuf, nSize);
- delete []pBuf;
- pBuf = NULL;
- return strw;
- }
- return L"";
- }
-
- ///
- /// ڽűchar*ֱתCStringW
- ///
- static CStringW DMCA2W(LPCSTR lpsz, UINT CodePage=CP_ACP)
- {
- CStringA str = lpsz;
- CStringW strw = DMA2W(str, CodePage);
- return strw;
- }
-
- static CStringA DMW2A(const CStringW &str, UINT CodePage=CP_ACP)
- {
- int nSize = ::WideCharToMultiByte(CodePage,0,str, str.GetLength(), NULL, 0, NULL, NULL);
- if (nSize>0)
- {
- char *pBuf = new char[nSize];
- ::WideCharToMultiByte(CodePage,0,str, str.GetLength(), pBuf, nSize, NULL, NULL);
- CStringA stra(pBuf,nSize);
- delete []pBuf;
- pBuf = NULL;
- return stra;
- }
- return "";
- }
-
- static CStringW DMW2W(const CStringW &str)
- {
- return str;
- }
-
- static CStringA DMA2A(const CStringA &str, UINT CodePageFrom=CP_UTF8, UINT CodePageTo=CP_ACP)
- {
- if (CodePageFrom == CodePageTo)
- {
- return str;
- }
- CStringW strw = DMA2W(str,CodePageFrom);
- return DMW2A(strw, CodePageTo);
- }
-
-
-#ifdef UNICODE
-#define DMA2T DMA2W
-#define DMW2T DMW2W
-#define DMT2A DMW2A
-#define DMT2W DMW2W
-#else
-#define DMA2T DMA2A
-#define DMW2T DMW2A
-#define DMT2A DMA2A
-#define DMT2W DMA2W
-#endif
-
template< typename T >
class SStringElementTraits
{
@@ -1807,3 +1741,68 @@ namespace DM
}//end of namespace
+namespace ntcvt {
+ namespace buffer_traits {
+ inline char* inplaced(DM::CStringA& str, int size) {
+ return str.GetBufferSetLength(size);
+ }
+ inline wchar_t* inplaced(DM::CStringW& str, int size) {
+ return str.GetBufferSetLength(size);
+ }
+ }
+ inline std::string from_chars(const DM::CStringW& wcb, UINT cp = CP_ACP)
+ {
+ return wcbs2a((LPCWSTR)wcb, wcb.GetLength(), cp);
+ }
+}
+
+namespace DM {
+ ///
+ /// ڽűchar*ֱתCStringW
+ ///
+ static CStringW DMCA2W(LPCSTR lpsz, int len /*=-1*/, UINT CodePage/* = CP_ACP*/)
+ {
+ return ntcvt::mcbs2w(lpsz, len, CodePage);
+ }
+
+ static CStringW DMA2W(const CStringA& str, UINT CodePage = CP_ACP)
+ {
+ return DMCA2W((LPCSTR)str, str.GetLength(), CodePage);
+ }
+
+ static CStringA DMWC2A(LPCWSTR lpsz, int len /*=-1*/, UINT CodePage /*=CP_ACP*/)
+ {
+ return ntcvt::wcbs2a(lpsz, len, CodePage);
+ }
+
+ static CStringA DMW2A(const CStringW& str, UINT CodePage = CP_ACP)
+ {
+ return DMWC2A((LPCWSTR)str, str.GetLength(), CodePage);
+ }
+
+ static CStringW DMW2W(const CStringW& str)
+ {
+ return str;
+ }
+
+ static CStringA DMA2A(const CStringA& str, UINT CodePageFrom = CP_UTF8, UINT CodePageTo = CP_ACP)
+ {
+ if (CodePageFrom == CodePageTo)
+ return str;
+ CStringW strw = DMA2W(str, CodePageFrom);
+ return DMW2A(strw, CodePageTo);
+ }
+
+
+#ifdef UNICODE
+#define DMA2T DMA2W
+#define DMW2T DMW2W
+#define DMT2A DMW2A
+#define DMT2W DMW2W
+#else
+#define DMA2T DMA2A
+#define DMW2T DMW2A
+#define DMT2A DMA2A
+#define DMT2W DMA2W
+#endif
+}
diff --git a/DmMain/inc/Widgets/DUIEdit.h b/DmMain/inc/Widgets/DUIEdit.h
index eaf03452..6c9f019a 100644
--- a/DmMain/inc/Widgets/DUIEdit.h
+++ b/DmMain/inc/Widgets/DUIEdit.h
@@ -90,12 +90,16 @@ namespace DM
public:
//---------------------------------------------------
- // Function Des: ӿ,οafxcmn.inlCRichEditCtrlһ
+ // Function Des: ӿ
//---------------------------------------------------
+ void SetText(const CStringW& text) override;
+ CStringW GetText() const override;
+
+ // [deprecated] οafxcmn.inlCRichEditCtrlһ
+ void SetWindowText(LPCWSTR lpszText) { SetText(lpszText); }
CStringW GetWindowText();
- int GetWindowText(LPWSTR lpString,int nMaxCount);
+ int GetWindowText(LPWSTR lpString, int nMaxCount);
int GetWindowTextLength();
- void SetWindowText(LPCWSTR lpszText);
DWORD GetEventMask();
DWORD SetEventMask(DWORD dwEventMask); ///< Ҫյ¼ SetEventMask(ENM_OBJECTPOSITIONS | ENM_PROTECTED | ENM_DROPFILES | ENM_CHANGE | ENM_LINK | ENM_SELCHANGE | ENM_DRAGDROPDONE);
diff --git a/DmMain/inc/Widgets/DUIWindow.h b/DmMain/inc/Widgets/DUIWindow.h
index 648d1135..d348cfc6 100644
--- a/DmMain/inc/Widgets/DUIWindow.h
+++ b/DmMain/inc/Widgets/DUIWindow.h
@@ -196,8 +196,21 @@ namespace DM
virtual DMCode DV_OnStateChanged(DWORD dwOldState,DWORD dwNewState); ///< ״̬ıʱ
///
- virtual DMCode DV_SetWindowText(LPCWSTR lpszText); ///< ı
- virtual const CStringW& DV_GetWindowText() const;
+#if _HAS_CXX17
+ void SetText(std::string_view text, UINT cp = CP_UTF8) { SetText(DMCA2W(text.data(), text.length(), cp)); }
+#else
+ void SetText(const char* text, UINT cp = CP_UTF8) { SetText(DMCA2W(text, -1, cp)); }
+#endif
+ virtual void SetText(const CStringW& text);
+
+ CStringA GetTextA(UINT cp = CP_UTF8) { return DM::DMW2A(GetText(), cp); }
+ virtual CStringW GetText() const;
+
+ // [deprecated]
+ DMCode DV_SetWindowText(LPCWSTR lpszText); ///< ı
+ const CStringW& DV_GetWindowText() const;
+
+ // Draw
virtual DMCode DV_DrawText(IDMCanvas* pCanvas, LPCWSTR pszBuf,int cchText,LPRECT lpRect,UINT uFormat); ///< ,WM_PAINTд
virtual DMCode DV_DrawMultText(IDMCanvas* pCanvas, LPCWSTR pszBuf,int cchText,LPRECT lpRect,UINT uFormat,int nLineInter); ///< ʾ,xmlеַ\R\N
diff --git a/DmMain/src/Common/Plugins/DMPluginsTool.cpp b/DmMain/src/Common/Plugins/DMPluginsTool.cpp
index 7155baf5..87bbcd84 100644
--- a/DmMain/src/Common/Plugins/DMPluginsTool.cpp
+++ b/DmMain/src/Common/Plugins/DMPluginsTool.cpp
@@ -253,7 +253,7 @@ namespace DM
DMXmlNode directory = body.FirstChild(L"directory");
while (directory.IsValid())
{
- wchar_t *pDir = (wchar_t*)directory.Attribute(L"name");
+ CStringW pDir = directory.Attribute(L"name");
wchar_t szPluginDir[MAX_PATH] = {0};
if (NULL == PathCombineW(szPluginDir, szExeDir, pDir))
{
@@ -269,7 +269,7 @@ namespace DM
strDir += L'\\';
}
- wchar_t *pPluginName = (wchar_t*)item.Attribute(L"name");
+ CStringW pPluginName = item.Attribute(L"name");
LoadPlugin(strDir+pPluginName);
item = item.NextSibling(L"item");
}
diff --git a/DmMain/src/Core/Dui/DUISkinPool.cpp b/DmMain/src/Core/Dui/DUISkinPool.cpp
index 17839820..005981d1 100644
--- a/DmMain/src/Core/Dui/DUISkinPool.cpp
+++ b/DmMain/src/Core/Dui/DUISkinPool.cpp
@@ -53,7 +53,7 @@ namespace DM
{
if (!pItem->IsKeyExist(strId))
{// keyʱż
- LPCWSTR lpszClassName = XmlSkin.GetName();
+ CStringW lpszClassName = XmlSkin.GetName();
IDMSkinPtr pSkinPtr = NULL;
if (DMSUCCEEDED(g_pDMApp->CreateRegObj((void**)&pSkinPtr,lpszClassName,DMREG_Skin)))
{
@@ -231,7 +231,7 @@ namespace DM
}
//4.skin
- LPCWSTR lpszClassName = XmlNode.GetName();
+ CStringW lpszClassName = XmlNode.GetName();
IDMSkinPtr pSkinPtr = NULL;
if (!DMSUCCEEDED(g_pDMApp->CreateRegObj((void**)&pSkinPtr,lpszClassName,DMREG_Skin)))
{
diff --git a/DmMain/src/Modules/DMResFolderImpl.cpp b/DmMain/src/Modules/DMResFolderImpl.cpp
index d1d23d0d..237f03fc 100644
--- a/DmMain/src/Modules/DMResFolderImpl.cpp
+++ b/DmMain/src/Modules/DMResFolderImpl.cpp
@@ -342,8 +342,8 @@ namespace DM
DMXmlNode XmlFileNode = XmlNode.FirstChild(L"file");
while (XmlFileNode.IsValid())
{
- LPCWSTR lpszName = XmlFileNode.Attribute(L"name");
- LPCWSTR lpszFilePath = XmlFileNode.Attribute(L"path");
+ CStringW lpszName = XmlFileNode.Attribute(L"name");
+ CStringW lpszFilePath = XmlFileNode.Attribute(L"path");
wchar_t szPath[MAX_PATH] = {0};
if (0 != PathCombineW(szPath, m_strDir, lpszFilePath))
{
@@ -415,13 +415,13 @@ namespace DM
XmlNode = XmlNode.FirstChild();
while (XmlNode.IsValid())
{
- LPCWSTR lpszType = XmlNode.GetName();
+ CStringW lpszType = XmlNode.GetName();
DMXmlNode XmlFileNode = XmlNode.FirstChild(L"file");
while (XmlFileNode.IsValid())
{
- LPCWSTR lpszName = XmlFileNode.Attribute(L"name");
- LPCWSTR lpszFilePath = XmlFileNode.Attribute(L"path");
- if (NULL!=lpszFilePath&&0!=wcslen(lpszFilePath))
+ CStringW lpszName = XmlFileNode.Attribute(L"name");
+ CStringW lpszFilePath = XmlFileNode.Attribute(L"path");
+ if (!lpszFilePath.IsEmpty())
{
wchar_t szPath[MAX_PATH] = {0};
if (0 != PathCombineW(szPath, m_strDir, lpszFilePath))
diff --git a/DmMain/src/Widgets/DUIEdit.cpp b/DmMain/src/Widgets/DUIEdit.cpp
index 35bc1577..db7797d9 100644
--- a/DmMain/src/Widgets/DUIEdit.cpp
+++ b/DmMain/src/Widgets/DUIEdit.cpp
@@ -64,16 +64,28 @@ namespace DM
//---------------------------------------------------
// Function Des: ӿ
- CStringW DUIRichEdit::GetWindowText()
+ void DUIRichEdit::SetText(const CStringW& text)
{
+ DM_SendMessage(WM_SETTEXT, 0, (LPARAM)(LPCWSTR)text);
+ }
+
+ CStringW DUIRichEdit::GetText() const
+ {
+ DUIRichEdit* thiz = const_cast(this);
CStringW strRet;
- int nLen = (int)DM_SendMessage(WM_GETTEXTLENGTH);
- wchar_t *pBuf = strRet.GetBufferSetLength(nLen+1);
- DM_SendMessage(WM_GETTEXT,(WPARAM)nLen+1,(LPARAM)pBuf);
- strRet.ReleaseBuffer();
+ int nLen = (int)thiz->DM_SendMessage(WM_GETTEXTLENGTH);
+ if (nLen > 0) {
+ wchar_t* pBuf = strRet.GetBufferSetLength(nLen); // ڲԤ'\0'Ŀռ
+ thiz->DM_SendMessage(WM_GETTEXT, (WPARAM)nLen + 1, (LPARAM)pBuf);
+ }
return strRet;
}
+ CStringW DUIRichEdit::GetWindowText()
+ {
+ return GetText();
+ }
+
int DUIRichEdit::GetWindowText(LPWSTR lpString,int nMaxCount)
{
int iNum = -1;
@@ -95,11 +107,6 @@ namespace DM
return (int)DM_SendMessage(WM_GETTEXTLENGTH);
}
- void DUIRichEdit::SetWindowText(LPCWSTR lpszText)
- {
- DM_SendMessage(WM_SETTEXT,0,(LPARAM)lpszText);
- }
-
DWORD DUIRichEdit::GetEventMask()
{
return (DWORD)DM_SendMessage(EM_GETEVENTMASK, 0, 0L);
@@ -151,16 +158,18 @@ namespace DM
CStringW DUIRichEdit::GetLineText(int nLine /*= -1*/)
{
- CStringW strRet;
- int nLen = LineLength(nLine)+1;
- wchar_t *pBuf = strRet.GetBufferSetLength(nLen);
- *(LPINT)pBuf = nLen;
if (-1 == nLine)
- {
nLine = LineFromChar(-1);
+
+ CStringW strRet;
+ int nLen = LineLength(nLine);
+ if (nLen > 0) {
+ wchar_t* pBuf = strRet.GetBuffer(max(nLen, sizeof(INT) - 1));
+ *(LPINT)pBuf = nLen; // windowsx Edit_GetLine, mfc CRichEdit::GetLine
+
+ DM_SendMessage(EM_GETLINE, nLine, (LPARAM)pBuf);
+ strRet.SetLength(nLen);
}
- DM_SendMessage(EM_GETLINE,nLine,(LPARAM)pBuf);
- strRet.ReleaseBuffer();
return strRet;
}
diff --git a/DmMain/src/Widgets/DUIHeaderCtrl.cpp b/DmMain/src/Widgets/DUIHeaderCtrl.cpp
index 421b1e56..3a0532e8 100644
--- a/DmMain/src/Widgets/DUIHeaderCtrl.cpp
+++ b/DmMain/src/Widgets/DUIHeaderCtrl.cpp
@@ -62,7 +62,7 @@ namespace DM
{
pNewItem->pSkin = m_pItemSkin;
}
- strValue = (LPWSTR)XmlNode.Attribute(DMAttr::DUIHeaderCtrlAttr::ITEM_text);
+ strValue = XmlNode.Attribute(DMAttr::DUIHeaderCtrlAttr::ITEM_text);
pNewItem->lpszText = _wcsdup(strValue);
pNewItem->cchTextMax = strValue.GetLength();
strValue = XmlNode.Attribute(DMAttr::DUIHeaderCtrlAttr::ITEM_data);
diff --git a/DmMain/src/Widgets/DUIWindow.cpp b/DmMain/src/Widgets/DUIWindow.cpp
index 37218236..892c0368 100644
--- a/DmMain/src/Widgets/DUIWindow.cpp
+++ b/DmMain/src/Widgets/DUIWindow.cpp
@@ -1421,13 +1421,22 @@ namespace DM
return DM_ECODE_OK;
}
- DMCode DUIWindow::DV_SetWindowText(LPCWSTR lpszText)
+ void DUIWindow::SetText(const CStringW& text)
{
- m_pDUIXmlInfo->m_strText = lpszText;
+ m_pDUIXmlInfo->m_strText = text;
if (DM_IsVisible(true))
{
DM_Invalidate();
}
+ }
+
+ CStringW DUIWindow::GetText() const {
+ return m_pDUIXmlInfo->m_strText;
+ }
+
+ DMCode DUIWindow::DV_SetWindowText(LPCWSTR lpszText)
+ {
+ SetText(lpszText);
return DM_ECODE_OK;
}
diff --git a/External/ntcvt/ntcvt.hpp b/External/ntcvt/ntcvt.hpp
new file mode 100644
index 00000000..36f30857
--- /dev/null
+++ b/External/ntcvt/ntcvt.hpp
@@ -0,0 +1,151 @@
+#ifndef SIMDSOFT__NTCVT_HPP
+#define SIMDSOFT__NTCVT_HPP
+
+#pragma once
+#if !defined(WIN32_LEAN_AND_MEAN)
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include
+#include
+
+namespace ntcvt {
+enum code_page
+{
+ code_page_acp = CP_ACP,
+ code_page_utf8 = CP_UTF8
+};
+
+// different with resize, not all of fill new memory with '\0'
+namespace buffer_traits
+{
+template ,
+ class _Alloc = std::allocator<_Elem>>
+class string : public std::basic_string<_Elem, _Traits, _Alloc>
+ {
+ public:
+#if _MSC_VER > 1900 // VS2017 or later
+ using _Alty = std::_Rebind_alloc_t<_Alloc, _Elem>;
+ using _Alty_traits = std::allocator_traits<_Alty>;
+
+ using _Scary_val = std::_String_val, std::_Simple_types<_Elem>,
+ std::_String_iter_types<_Elem, typename _Alty_traits::size_type, typename _Alty_traits::difference_type,
+ typename _Alty_traits::pointer, typename _Alty_traits::const_pointer, _Elem&, const _Elem&>>>;
+#endif
+ // See also afxmfc CString::GetBufferSetLength
+ // Why do this hack?
+ // stupid: because the default c++ standard resize always fill with '\0'
+ // std::string: use memset (usually implemented with SIMD)
+ // std::wstring: for loop (slow performance)
+ // only works on msvc currently
+ _Elem* setnbuf(int len)
+ {
+ this->reserve(len);
+#if _MSC_VER > 1900 // VS2017 or later
+ std::_Compressed_pair<_Alty, _Scary_val>* _Myval = (std::_Compressed_pair<_Alty, _Scary_val> *)this;
+ _Myval->_Myval2._Mysize = len;
+ auto front = &this->front();
+ front[len] = '\0';
+ return front;
+#else
+ this->_Eos(len);
+ return &this->front();
+#endif
+ }
+ };
+
+ template static _Elem* inplaced(std::basic_string<_Elem> & str, int size)
+ {
+ string<_Elem>& helper = (string<_Elem>&)str;
+ return helper.setnbuf(size);
+ }
+#if defined(_AFX)
+ template _Elem* inplaced(CStringT < _Elem, StrTraitMFC_DLL<_Elem>>& str, int size) {
+ return str.GetBufferSetLength(size);
+ }
+#endif
+}
+
+template
+inline _StringContType wcbs2a(const wchar_t* wcb, int len, UINT cp = code_page_acp)
+{
+ if (len == -1)
+ len = lstrlenW(wcb);
+ _StringContType buffer;
+ int cch;
+ if (len > 0 && (cch = ::WideCharToMultiByte(cp, 0, wcb, len, NULL, 0, NULL, NULL)) > 0)
+ ::WideCharToMultiByte(cp, 0, wcb, len, buffer_traits::inplaced(buffer, cch), cch, NULL, NULL);
+ return buffer;
+}
+
+template
+inline _StringContType mcbs2w(const char* mcb, int len, UINT cp = code_page_acp)
+{
+ if (len == -1)
+ len = lstrlenA(mcb);
+ _StringContType buffer;
+ int cch;
+ if (len > 0 && (cch = ::MultiByteToWideChar(cp, 0, mcb, len, NULL, 0)) > 0)
+ ::MultiByteToWideChar(cp, 0, mcb, len, buffer_traits::inplaced(buffer, cch), cch);
+
+ return buffer;
+}
+
+#if _HAS_CXX17
+inline std::string from_chars(const std::wstring_view& wcb, UINT cp = code_page_acp)
+{
+ return wcbs2a(wcb.data(), wcb.length(), cp);
+}
+
+inline std::wstring from_chars(const std::string_view& mcb, UINT cp = code_page_acp)
+{
+ return mcbs2w(mcb.data(), mcb.length(), cp);
+}
+#else
+inline std::string from_chars(const std::wstring& wcb, UINT cp = code_page_acp)
+{
+ return wcbs2a(wcb.c_str(), wcb.length(), cp);
+}
+
+inline std::wstring from_chars(const std::string& mcb, UINT cp = code_page_acp)
+{
+ return mcbs2w(mcb.c_str(), mcb.length(), cp);
+}
+#endif
+
+inline std::string from_chars(const wchar_t* str, UINT cp = code_page_acp)
+{
+ return wcbs2a(str, -1, cp);
+}
+
+inline std::wstring from_chars(const char* str, UINT cp = code_page_acp)
+{
+ return mcbs2w(str, -1, cp);
+}
+
+// ntcs or std::string to CStringW
+#if defined(_AFX)
+inline std::string from_chars(const CStringW& wcb, UINT cp = CP_ACP)
+{
+ return wcbs2a(wcb.GetString(), wcb.GetLength(), cp);
+}
+namespace afx {
+#if _HAS_CXX17
+ inline CStringW from_chars(std::string_view mcb, UINT cp = CP_ACP)
+ {
+ return mcbs2w(mcb.data(), mcb.length(), cp);
+ }
+#else
+ inline CStringW from_chars(const char* str, UINT cp = code_page_acp)
+ {
+ return mcbs2w(str, -1, cp);
+ }
+ inline CStringW from_chars(const std::string& mcb, UINT cp = CP_ACP)
+ {
+ return mcbs2w(mcb.c_str(), mcb.length(), cp);
+ }
+#endif
+}
+#endif
+}
+
+#endif
diff --git a/PlugIns/Plugin_Designer/CMakeLists.txt b/PlugIns/Plugin_Designer/CMakeLists.txt
index 965fdbe3..84cbfec4 100644
--- a/PlugIns/Plugin_Designer/CMakeLists.txt
+++ b/PlugIns/Plugin_Designer/CMakeLists.txt
@@ -28,7 +28,8 @@ INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/DmMain/inc
${DM_SOURCE_DIR}/DmMain/inc/Core/Event;
${DM_SOURCE_DIR}/DmMain/inc/IDmMain;
${DM_SOURCE_DIR}/DmMain/inc/Modules;
- ${DM_SOURCE_DIR}/DmMain/inc/Widgets;)
+ ${DM_SOURCE_DIR}/DmMain/inc/Widgets;
+ ${DM_SOURCE_DIR}/External;)
# Plugin_Designerͷļ
INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/PlugIns/Plugin_Designer/inc)
diff --git a/PlugIns/Plugin_Expand/CMakeLists.txt b/PlugIns/Plugin_Expand/CMakeLists.txt
index 2b6ac653..e72d74dc 100644
--- a/PlugIns/Plugin_Expand/CMakeLists.txt
+++ b/PlugIns/Plugin_Expand/CMakeLists.txt
@@ -60,7 +60,8 @@ INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/DmMain/inc
${DM_SOURCE_DIR}/DmMain/inc/Core/Event;
${DM_SOURCE_DIR}/DmMain/inc/IDmMain;
${DM_SOURCE_DIR}/DmMain/inc/Modules;
- ${DM_SOURCE_DIR}/DmMain/inc/Widgets;)
+ ${DM_SOURCE_DIR}/DmMain/inc/Widgets;
+ ${DM_SOURCE_DIR}/External;)
# Plugin_Expandͷļ
INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/PlugIns/Plugin_Expand/inc)
diff --git a/Samples/DMDemo/CMakeLists.txt b/Samples/DMDemo/CMakeLists.txt
index 9ecb12f7..536db99e 100644
--- a/Samples/DMDemo/CMakeLists.txt
+++ b/Samples/DMDemo/CMakeLists.txt
@@ -27,7 +27,8 @@ INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/DmMain/inc
${DM_SOURCE_DIR}/DmMain/inc/Core/Event;
${DM_SOURCE_DIR}/DmMain/inc/IDmMain;
${DM_SOURCE_DIR}/DmMain/inc/Modules;
- ${DM_SOURCE_DIR}/DmMain/inc/Widgets;)
+ ${DM_SOURCE_DIR}/DmMain/inc/Widgets;
+ ${DM_SOURCE_DIR}/External;)
# Plugin_Expandͷļ
INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/PlugIns/Plugin_Expand/inc)
diff --git a/Samples/DMDesigner/CMakeLists.txt b/Samples/DMDesigner/CMakeLists.txt
index 968e9c06..99a225d8 100644
--- a/Samples/DMDesigner/CMakeLists.txt
+++ b/Samples/DMDesigner/CMakeLists.txt
@@ -58,7 +58,8 @@ INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/DmMain/inc
${DM_SOURCE_DIR}/DmMain/inc/Core/Event;
${DM_SOURCE_DIR}/DmMain/inc/IDmMain;
${DM_SOURCE_DIR}/DmMain/inc/Modules;
- ${DM_SOURCE_DIR}/DmMain/inc/Widgets;)
+ ${DM_SOURCE_DIR}/DmMain/inc/Widgets;
+ ${DM_SOURCE_DIR}/External;)
# scintillaͷļ
INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/3rdParty/scintilla/inc)
diff --git a/Samples/DMUnitTest/CMakeLists.txt b/Samples/DMUnitTest/CMakeLists.txt
index 3df36ed2..1c3d3377 100644
--- a/Samples/DMUnitTest/CMakeLists.txt
+++ b/Samples/DMUnitTest/CMakeLists.txt
@@ -36,7 +36,8 @@ INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/DmMain/inc
${DM_SOURCE_DIR}/DmMain/inc/Core/Event;
${DM_SOURCE_DIR}/DmMain/inc/IDmMain;
${DM_SOURCE_DIR}/DmMain/inc/Modules;
- ${DM_SOURCE_DIR}/DmMain/inc/Widgets;)
+ ${DM_SOURCE_DIR}/DmMain/inc/Widgets;
+ ${DM_SOURCE_DIR}/External;)
# luaͷļ
INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/3rdParty/lua
diff --git a/Samples/QQDemo/CMakeLists.txt b/Samples/QQDemo/CMakeLists.txt
index 4293fd05..c38cbc77 100644
--- a/Samples/QQDemo/CMakeLists.txt
+++ b/Samples/QQDemo/CMakeLists.txt
@@ -42,7 +42,8 @@ INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/DmMain/inc
${DM_SOURCE_DIR}/DmMain/inc/Core/Event;
${DM_SOURCE_DIR}/DmMain/inc/IDmMain;
${DM_SOURCE_DIR}/DmMain/inc/Modules;
- ${DM_SOURCE_DIR}/DmMain/inc/Widgets;)
+ ${DM_SOURCE_DIR}/DmMain/inc/Widgets;
+ ${DM_SOURCE_DIR}/External;)
# luaͷļ
INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/3rdParty/lua
diff --git a/Samples/TGPDemo/CMakeLists.txt b/Samples/TGPDemo/CMakeLists.txt
index 3f567f02..d5e2b062 100644
--- a/Samples/TGPDemo/CMakeLists.txt
+++ b/Samples/TGPDemo/CMakeLists.txt
@@ -39,7 +39,8 @@ INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/DmMain/inc
${DM_SOURCE_DIR}/DmMain/inc/Core/Event;
${DM_SOURCE_DIR}/DmMain/inc/IDmMain;
${DM_SOURCE_DIR}/DmMain/inc/Modules;
- ${DM_SOURCE_DIR}/DmMain/inc/Widgets;)
+ ${DM_SOURCE_DIR}/DmMain/inc/Widgets;
+ ${DM_SOURCE_DIR}/External;)
# luaͷļ
INCLUDE_DIRECTORIES(${DM_SOURCE_DIR}/3rdParty/lua