Skip to content

Commit a73dc10

Browse files
authored
SetText/GetText优化 (#12)
* SetTextA/GetTextA, in-progress * Unnececcary + 1 * DUIRichEdit::GetLineText, 确保当字符小于sizeof(int) -1 时,分配足够空间,避免踩无效内存 * 优化,避免不必要的buffer深拷贝 * Use external to manage dependeicies * 利用函数重载 * fix vs2013 compile issue * 避免不必要的强转 * Add c++ standard choose support, _CXX_STD=17 * C++17 compiler support * Implement DM::CStringW to std::string for ntcvt * Explicit match c style string * Rename name * Define WIN32_LEAN_AND_MEAN
1 parent 58395c6 commit a73dc10

19 files changed

Lines changed: 335 additions & 111 deletions

File tree

CMakeLists.txt

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,37 @@ OPTION(USE_DMSKIA_ "DM user skia render draw" OFF)
5959
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Tools/CMake)
6060
INCLUDE(PrecompiledHeader)
6161

62+
# --- The compiler flags
63+
message("-- Building REDM with cpp${_CXX_STD} support")
64+
if ( IOS )
65+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode" CACHE INTERNAL "CMAKE_CXX_FLAGS")
66+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode" CACHE INTERNAL "CMAKE_C_FLAGS")
67+
endif ()
68+
if (NOT WIN32 OR CYGWIN)
69+
if (_CXX_STD EQUAL 17)
70+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z" CACHE INTERNAL "CMAKE_CXX_FLAGS")
71+
if ( IOS )
72+
# Aligned deallocation function of type 'void (void *, std::align_val_t) noexcept' is only available on iOS 11 or newer
73+
# most of time, low level malloc will alloc a aligned address for new operator,
74+
# so it's ok to add -faligned-allocation, certainly, still need find a ios9.0 device
75+
# to test does it works well?
76+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -faligned-allocation" CACHE INTERNAL "CMAKE_CXX_FLAGS")
77+
endif()
78+
elseif(_CXX_STD EQUAL 14)
79+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y" CACHE INTERNAL "CMAKE_CXX_FLAGS")
80+
else()
81+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" CACHE INTERNAL "CMAKE_CXX_FLAGS")
82+
endif()
83+
else()
84+
if(_CXX_STD EQUAL 17)
85+
# target_compile_features(REDM PUBLIC cxx_std_17) works
86+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17" CACHE INTERNAL "CMAKE_CXX_FLAGS")
87+
elseif(_CXX_STD EQUAL 14)
88+
# target_compile_features(REDM PUBLIC cxx_std_14) not works
89+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++14" CACHE INTERNAL "CMAKE_CXX_FLAGS")
90+
endif()
91+
endif()
92+
6293
# 增加子文件夹
6394
ADD_SUBDIRECTORY(${PROJDIR}/DmMain)
6495
ADD_SUBDIRECTORY(${PROJDIR}/Samples/DMDemo)
@@ -77,4 +108,4 @@ ADD_SUBDIRECTORY(${PROJDIR}/3rdParty/lua)
77108
ADD_SUBDIRECTORY(${PROJDIR}/3rdParty/scintilla)
78109
if(USE_DMSKIA_)
79110
ADD_SUBDIRECTORY(${PROJDIR}/3rdParty/skia)
80-
endif()
111+
endif()

DmMain/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ target_include_directories(DmMain
177177
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc/Modules/Skin
178178
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc/Modules/Task
179179
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc/Widgets
180+
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../External
180181
)
181182
SET_TARGET_PROPERTIES(DmMain PROPERTIES OUTPUT_NAME "DmMain")
182183

DmMain/inc/Common/Template/DMStringT.h

Lines changed: 67 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#define TSTRING_PADDING 0
2020
#endif
2121

22+
#include "ntcvt/ntcvt.hpp"
23+
2224
namespace DM
2325
{
2426
__pragma(warning(push))
@@ -1676,74 +1678,6 @@ namespace DM
16761678
typedef CStringA CStringT;
16771679
#endif
16781680

1679-
static CStringW DMA2W(const CStringA &str, UINT CodePage=CP_ACP)
1680-
{
1681-
int nSize = ::MultiByteToWideChar(CodePage, 0, str, str.GetLength(), NULL, 0);
1682-
if (nSize>0)
1683-
{
1684-
wchar_t *pBuf=new wchar_t[nSize];
1685-
::MultiByteToWideChar(CodePage, 0, str, str.GetLength(), pBuf, nSize);
1686-
CStringW strw(pBuf, nSize);
1687-
delete []pBuf;
1688-
pBuf = NULL;
1689-
return strw;
1690-
}
1691-
return L"";
1692-
}
1693-
1694-
/// <summary>
1695-
/// 用于脚本中char*直接转CStringW
1696-
/// </summary>
1697-
static CStringW DMCA2W(LPCSTR lpsz, UINT CodePage=CP_ACP)
1698-
{
1699-
CStringA str = lpsz;
1700-
CStringW strw = DMA2W(str, CodePage);
1701-
return strw;
1702-
}
1703-
1704-
static CStringA DMW2A(const CStringW &str, UINT CodePage=CP_ACP)
1705-
{
1706-
int nSize = ::WideCharToMultiByte(CodePage,0,str, str.GetLength(), NULL, 0, NULL, NULL);
1707-
if (nSize>0)
1708-
{
1709-
char *pBuf = new char[nSize];
1710-
::WideCharToMultiByte(CodePage,0,str, str.GetLength(), pBuf, nSize, NULL, NULL);
1711-
CStringA stra(pBuf,nSize);
1712-
delete []pBuf;
1713-
pBuf = NULL;
1714-
return stra;
1715-
}
1716-
return "";
1717-
}
1718-
1719-
static CStringW DMW2W(const CStringW &str)
1720-
{
1721-
return str;
1722-
}
1723-
1724-
static CStringA DMA2A(const CStringA &str, UINT CodePageFrom=CP_UTF8, UINT CodePageTo=CP_ACP)
1725-
{
1726-
if (CodePageFrom == CodePageTo)
1727-
{
1728-
return str;
1729-
}
1730-
CStringW strw = DMA2W(str,CodePageFrom);
1731-
return DMW2A(strw, CodePageTo);
1732-
}
1733-
1734-
1735-
#ifdef UNICODE
1736-
#define DMA2T DMA2W
1737-
#define DMW2T DMW2W
1738-
#define DMT2A DMW2A
1739-
#define DMT2W DMW2W
1740-
#else
1741-
#define DMA2T DMA2A
1742-
#define DMW2T DMW2A
1743-
#define DMT2A DMA2A
1744-
#define DMT2W DMA2W
1745-
#endif
1746-
17471681
template< typename T >
17481682
class SStringElementTraits
17491683
{
@@ -1807,3 +1741,68 @@ namespace DM
18071741

18081742
}//end of namespace
18091743

1744+
namespace ntcvt {
1745+
namespace buffer_traits {
1746+
inline char* inplaced(DM::CStringA& str, int size) {
1747+
return str.GetBufferSetLength(size);
1748+
}
1749+
inline wchar_t* inplaced(DM::CStringW& str, int size) {
1750+
return str.GetBufferSetLength(size);
1751+
}
1752+
}
1753+
inline std::string from_chars(const DM::CStringW& wcb, UINT cp = CP_ACP)
1754+
{
1755+
return wcbs2a<std::string>((LPCWSTR)wcb, wcb.GetLength(), cp);
1756+
}
1757+
}
1758+
1759+
namespace DM {
1760+
/// <summary>
1761+
/// 用于脚本中char*直接转CStringW
1762+
/// </summary>
1763+
static CStringW DMCA2W(LPCSTR lpsz, int len /*=-1*/, UINT CodePage/* = CP_ACP*/)
1764+
{
1765+
return ntcvt::mcbs2w<CStringW>(lpsz, len, CodePage);
1766+
}
1767+
1768+
static CStringW DMA2W(const CStringA& str, UINT CodePage = CP_ACP)
1769+
{
1770+
return DMCA2W((LPCSTR)str, str.GetLength(), CodePage);
1771+
}
1772+
1773+
static CStringA DMWC2A(LPCWSTR lpsz, int len /*=-1*/, UINT CodePage /*=CP_ACP*/)
1774+
{
1775+
return ntcvt::wcbs2a<CStringA>(lpsz, len, CodePage);
1776+
}
1777+
1778+
static CStringA DMW2A(const CStringW& str, UINT CodePage = CP_ACP)
1779+
{
1780+
return DMWC2A((LPCWSTR)str, str.GetLength(), CodePage);
1781+
}
1782+
1783+
static CStringW DMW2W(const CStringW& str)
1784+
{
1785+
return str;
1786+
}
1787+
1788+
static CStringA DMA2A(const CStringA& str, UINT CodePageFrom = CP_UTF8, UINT CodePageTo = CP_ACP)
1789+
{
1790+
if (CodePageFrom == CodePageTo)
1791+
return str;
1792+
CStringW strw = DMA2W(str, CodePageFrom);
1793+
return DMW2A(strw, CodePageTo);
1794+
}
1795+
1796+
1797+
#ifdef UNICODE
1798+
#define DMA2T DMA2W
1799+
#define DMW2T DMW2W
1800+
#define DMT2A DMW2A
1801+
#define DMT2W DMW2W
1802+
#else
1803+
#define DMA2T DMA2A
1804+
#define DMW2T DMW2A
1805+
#define DMT2A DMA2A
1806+
#define DMT2W DMA2W
1807+
#endif
1808+
}

DmMain/inc/Widgets/DUIEdit.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,16 @@ namespace DM
9090

9191
public:
9292
//---------------------------------------------------
93-
// Function Des: 对外接口,参看afxcmn.inl,和CRichEditCtrl保持一致
93+
// Function Des: 对外接口
9494
//---------------------------------------------------
95+
void SetText(const CStringW& text) override;
96+
CStringW GetText() const override;
97+
98+
// [deprecated] 参看afxcmn.inl,和CRichEditCtrl保持一致
99+
void SetWindowText(LPCWSTR lpszText) { SetText(lpszText); }
95100
CStringW GetWindowText();
96-
int GetWindowText(LPWSTR lpString,int nMaxCount);
101+
int GetWindowText(LPWSTR lpString, int nMaxCount);
97102
int GetWindowTextLength();
98-
void SetWindowText(LPCWSTR lpszText);
99103

100104
DWORD GetEventMask();
101105
DWORD SetEventMask(DWORD dwEventMask); ///< 设置需要接收的事件类型 SetEventMask(ENM_OBJECTPOSITIONS | ENM_PROTECTED | ENM_DROPFILES | ENM_CHANGE | ENM_LINK | ENM_SELCHANGE | ENM_DRAGDROPDONE);

DmMain/inc/Widgets/DUIWindow.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,21 @@ namespace DM
196196
virtual DMCode DV_OnStateChanged(DWORD dwOldState,DWORD dwNewState); ///< 状态改变时绘制
197197

198198
/// 文字相关
199-
virtual DMCode DV_SetWindowText(LPCWSTR lpszText); ///< 设置文本
200-
virtual const CStringW& DV_GetWindowText() const;
199+
#if _HAS_CXX17
200+
void SetText(std::string_view text, UINT cp = CP_UTF8) { SetText(DMCA2W(text.data(), text.length(), cp)); }
201+
#else
202+
void SetText(const char* text, UINT cp = CP_UTF8) { SetText(DMCA2W(text, -1, cp)); }
203+
#endif
204+
virtual void SetText(const CStringW& text);
205+
206+
CStringA GetTextA(UINT cp = CP_UTF8) { return DM::DMW2A(GetText(), cp); }
207+
virtual CStringW GetText() const;
208+
209+
// [deprecated]
210+
DMCode DV_SetWindowText(LPCWSTR lpszText); ///< 设置文本
211+
const CStringW& DV_GetWindowText() const;
212+
213+
// Draw文字
201214
virtual DMCode DV_DrawText(IDMCanvas* pCanvas, LPCWSTR pszBuf,int cchText,LPRECT lpRect,UINT uFormat); ///< 绘制文字,在WM_PAINT中触发
202215
virtual DMCode DV_DrawMultText(IDMCanvas* pCanvas, LPCWSTR pszBuf,int cchText,LPRECT lpRect,UINT uFormat,int nLineInter); ///< 示例代码,用于xml中的字符串\R\N解析
203216

DmMain/src/Common/Plugins/DMPluginsTool.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ namespace DM
253253
DMXmlNode directory = body.FirstChild(L"directory");
254254
while (directory.IsValid())
255255
{
256-
wchar_t *pDir = (wchar_t*)directory.Attribute(L"name");
256+
CStringW pDir = directory.Attribute(L"name");
257257
wchar_t szPluginDir[MAX_PATH] = {0};
258258
if (NULL == PathCombineW(szPluginDir, szExeDir, pDir))
259259
{
@@ -269,7 +269,7 @@ namespace DM
269269
strDir += L'\\';
270270
}
271271

272-
wchar_t *pPluginName = (wchar_t*)item.Attribute(L"name");
272+
CStringW pPluginName = item.Attribute(L"name");
273273
LoadPlugin(strDir+pPluginName);
274274
item = item.NextSibling(L"item");
275275
}

DmMain/src/Core/Dui/DUISkinPool.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ namespace DM
5353
{
5454
if (!pItem->IsKeyExist(strId))
5555
{// key不存在时才加入
56-
LPCWSTR lpszClassName = XmlSkin.GetName();
56+
CStringW lpszClassName = XmlSkin.GetName();
5757
IDMSkinPtr pSkinPtr = NULL;
5858
if (DMSUCCEEDED(g_pDMApp->CreateRegObj((void**)&pSkinPtr,lpszClassName,DMREG_Skin)))
5959
{
@@ -231,7 +231,7 @@ namespace DM
231231
}
232232

233233
//4.创建skin对象
234-
LPCWSTR lpszClassName = XmlNode.GetName();
234+
CStringW lpszClassName = XmlNode.GetName();
235235
IDMSkinPtr pSkinPtr = NULL;
236236
if (!DMSUCCEEDED(g_pDMApp->CreateRegObj((void**)&pSkinPtr,lpszClassName,DMREG_Skin)))
237237
{

DmMain/src/Modules/DMResFolderImpl.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,8 @@ namespace DM
342342
DMXmlNode XmlFileNode = XmlNode.FirstChild(L"file");
343343
while (XmlFileNode.IsValid())
344344
{
345-
LPCWSTR lpszName = XmlFileNode.Attribute(L"name");
346-
LPCWSTR lpszFilePath = XmlFileNode.Attribute(L"path");
345+
CStringW lpszName = XmlFileNode.Attribute(L"name");
346+
CStringW lpszFilePath = XmlFileNode.Attribute(L"path");
347347
wchar_t szPath[MAX_PATH] = {0};
348348
if (0 != PathCombineW(szPath, m_strDir, lpszFilePath))
349349
{
@@ -415,13 +415,13 @@ namespace DM
415415
XmlNode = XmlNode.FirstChild();
416416
while (XmlNode.IsValid())
417417
{
418-
LPCWSTR lpszType = XmlNode.GetName();
418+
CStringW lpszType = XmlNode.GetName();
419419
DMXmlNode XmlFileNode = XmlNode.FirstChild(L"file");
420420
while (XmlFileNode.IsValid())
421421
{
422-
LPCWSTR lpszName = XmlFileNode.Attribute(L"name");
423-
LPCWSTR lpszFilePath = XmlFileNode.Attribute(L"path");
424-
if (NULL!=lpszFilePath&&0!=wcslen(lpszFilePath))
422+
CStringW lpszName = XmlFileNode.Attribute(L"name");
423+
CStringW lpszFilePath = XmlFileNode.Attribute(L"path");
424+
if (!lpszFilePath.IsEmpty())
425425
{
426426
wchar_t szPath[MAX_PATH] = {0};
427427
if (0 != PathCombineW(szPath, m_strDir, lpszFilePath))

DmMain/src/Widgets/DUIEdit.cpp

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,28 @@ namespace DM
6464

6565
//---------------------------------------------------
6666
// Function Des: 对外接口
67-
CStringW DUIRichEdit::GetWindowText()
67+
void DUIRichEdit::SetText(const CStringW& text)
6868
{
69+
DM_SendMessage(WM_SETTEXT, 0, (LPARAM)(LPCWSTR)text);
70+
}
71+
72+
CStringW DUIRichEdit::GetText() const
73+
{
74+
DUIRichEdit* thiz = const_cast<DUIRichEdit*>(this);
6975
CStringW strRet;
70-
int nLen = (int)DM_SendMessage(WM_GETTEXTLENGTH);
71-
wchar_t *pBuf = strRet.GetBufferSetLength(nLen+1);
72-
DM_SendMessage(WM_GETTEXT,(WPARAM)nLen+1,(LPARAM)pBuf);
73-
strRet.ReleaseBuffer();
76+
int nLen = (int)thiz->DM_SendMessage(WM_GETTEXTLENGTH);
77+
if (nLen > 0) {
78+
wchar_t* pBuf = strRet.GetBufferSetLength(nLen); // 内部会预留'\0'的空间
79+
thiz->DM_SendMessage(WM_GETTEXT, (WPARAM)nLen + 1, (LPARAM)pBuf);
80+
}
7481
return strRet;
7582
}
7683

84+
CStringW DUIRichEdit::GetWindowText()
85+
{
86+
return GetText();
87+
}
88+
7789
int DUIRichEdit::GetWindowText(LPWSTR lpString,int nMaxCount)
7890
{
7991
int iNum = -1;
@@ -95,11 +107,6 @@ namespace DM
95107
return (int)DM_SendMessage(WM_GETTEXTLENGTH);
96108
}
97109

98-
void DUIRichEdit::SetWindowText(LPCWSTR lpszText)
99-
{
100-
DM_SendMessage(WM_SETTEXT,0,(LPARAM)lpszText);
101-
}
102-
103110
DWORD DUIRichEdit::GetEventMask()
104111
{
105112
return (DWORD)DM_SendMessage(EM_GETEVENTMASK, 0, 0L);
@@ -151,16 +158,18 @@ namespace DM
151158

152159
CStringW DUIRichEdit::GetLineText(int nLine /*= -1*/)
153160
{
154-
CStringW strRet;
155-
int nLen = LineLength(nLine)+1;
156-
wchar_t *pBuf = strRet.GetBufferSetLength(nLen);
157-
*(LPINT)pBuf = nLen;
158161
if (-1 == nLine)
159-
{
160162
nLine = LineFromChar(-1);
163+
164+
CStringW strRet;
165+
int nLen = LineLength(nLine);
166+
if (nLen > 0) {
167+
wchar_t* pBuf = strRet.GetBuffer(max(nLen, sizeof(INT) - 1));
168+
*(LPINT)pBuf = nLen; // windowsx Edit_GetLine, mfc CRichEdit::GetLine
169+
170+
DM_SendMessage(EM_GETLINE, nLine, (LPARAM)pBuf);
171+
strRet.SetLength(nLen);
161172
}
162-
DM_SendMessage(EM_GETLINE,nLine,(LPARAM)pBuf);
163-
strRet.ReleaseBuffer();
164173
return strRet;
165174
}
166175

DmMain/src/Widgets/DUIHeaderCtrl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ namespace DM
6262
{
6363
pNewItem->pSkin = m_pItemSkin;
6464
}
65-
strValue = (LPWSTR)XmlNode.Attribute(DMAttr::DUIHeaderCtrlAttr::ITEM_text);
65+
strValue = XmlNode.Attribute(DMAttr::DUIHeaderCtrlAttr::ITEM_text);
6666
pNewItem->lpszText = _wcsdup(strValue);
6767
pNewItem->cchTextMax = strValue.GetLength();
6868
strValue = XmlNode.Attribute(DMAttr::DUIHeaderCtrlAttr::ITEM_data);

0 commit comments

Comments
 (0)