mirror of https://github.com/axmolengine/axmol.git
Fixed missing ui::EditBox functionalities on Win32
1. There was 100-byte input limit at ui::EditBoxImplWin::openKeyboard() 2. Implemented MaxLength as LengthFilter, not ByteFilter. (same as Android's InputFilter - LengthFilter) 3. Users can input unicode characters that is not supported by CP_ACP.
This commit is contained in:
parent
16ac6c2709
commit
e7a39287f1
|
@ -66,8 +66,9 @@ struct WIN32INPUTBOX_PARAM
|
|||
IN LPCSTR szTitle, szPrompt;
|
||||
|
||||
// Return buffer
|
||||
OUT LPSTR szResult;
|
||||
IN DWORD nResultSize;
|
||||
std::string* pstrResult;
|
||||
|
||||
IN DWORD nMaxLength;
|
||||
|
||||
// Owner window
|
||||
HWND hwndOwner;
|
||||
|
@ -100,13 +101,10 @@ public:
|
|||
static INT_PTR InputBox(
|
||||
LPCSTR szTitle,
|
||||
LPCSTR szPrompt,
|
||||
LPSTR szResult,
|
||||
DWORD nResultSize,
|
||||
std::string* pstrResult,
|
||||
DWORD nMaxLength,
|
||||
bool bMultiLine = false,
|
||||
HWND hwndParent = 0);
|
||||
|
||||
static std::string AnsiToUtf8(std::string strAnsi);
|
||||
static std::string Utf8ToAnsi(std::string strUTF8);
|
||||
};
|
||||
|
||||
|
||||
|
@ -201,8 +199,8 @@ WIN32INPUTBOX_PARAM::WIN32INPUTBOX_PARAM()
|
|||
|
||||
xPos = yPos = -1;
|
||||
|
||||
szResult = 0;
|
||||
nResultSize = 0;
|
||||
pstrResult = nullptr;
|
||||
nMaxLength = (DWORD) -1;
|
||||
}
|
||||
|
||||
CWin32InputBox::CWin32InputBox(WIN32INPUTBOX_PARAM *param)
|
||||
|
@ -228,7 +226,7 @@ WIN32INPUTBOX_PARAM *CWin32InputBox::GetParam()
|
|||
INT_PTR CWin32InputBox::InputBoxEx(WIN32INPUTBOX_PARAM *param)
|
||||
{
|
||||
// Check mandatory parameters
|
||||
if (param->szResult == 0)
|
||||
if (param->pstrResult == nullptr)
|
||||
{
|
||||
::SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
|
@ -304,7 +302,7 @@ INT_PTR CWin32InputBox::InputBoxEx(WIN32INPUTBOX_PARAM *param)
|
|||
INT_PTR CWin32InputBox::InputBox(
|
||||
LPCSTR szTitle,
|
||||
LPCSTR szPrompt,
|
||||
LPSTR szResult,
|
||||
std::string* pstrResult,
|
||||
DWORD nResultSize,
|
||||
bool bMultiLine,
|
||||
HWND hwndParent)
|
||||
|
@ -313,8 +311,8 @@ INT_PTR CWin32InputBox::InputBox(
|
|||
|
||||
param.szTitle = szTitle;
|
||||
param.szPrompt = szPrompt;
|
||||
param.szResult = szResult;
|
||||
param.nResultSize = nResultSize;
|
||||
param.pstrResult = pstrResult;
|
||||
param.nMaxLength = nResultSize;
|
||||
param.bMultiline = bMultiLine;
|
||||
param.hwndOwner = hwndParent;
|
||||
return InputBoxEx(¶m);
|
||||
|
@ -327,8 +325,13 @@ void CWin32InputBox::InitDialog()
|
|||
::SetDlgItemText(_param->hDlg, (int)definputbox_buttonids[i], definputbox_buttonnames[i]);
|
||||
|
||||
// Set other controls
|
||||
::SetWindowTextA(_param->hDlg, Utf8ToAnsi(_param->szTitle).c_str());
|
||||
::SetDlgItemTextA(_param->hDlg, definputbox_id_prompt, Utf8ToAnsi(_param->szPrompt).c_str());
|
||||
std::u16string utf16Title;
|
||||
cocos2d::StringUtils::UTF8ToUTF16(_param->szTitle, utf16Title);
|
||||
::SetWindowTextW(_param->hDlg, (LPCWSTR) utf16Title.c_str());
|
||||
|
||||
std::u16string utf16Prompt;
|
||||
cocos2d::StringUtils::UTF8ToUTF16(_param->szTitle, utf16Prompt);
|
||||
::SetDlgItemTextW(_param->hDlg, definputbox_id_prompt, (LPCWSTR) utf16Prompt.c_str());
|
||||
|
||||
HWND hwndEdit1 = ::GetDlgItem(_param->hDlg, definputbox_id_edit1);
|
||||
HWND hwndEdit2 = ::GetDlgItem(_param->hDlg, definputbox_id_edit2);
|
||||
|
@ -338,7 +341,9 @@ void CWin32InputBox::InitDialog()
|
|||
else
|
||||
_hwndEditCtrl = hwndEdit1;
|
||||
|
||||
::SetWindowTextA(_hwndEditCtrl, Utf8ToAnsi(_param->szResult).c_str());
|
||||
std::u16string utf16Result;
|
||||
cocos2d::StringUtils::UTF8ToUTF16(_param->pstrResult->c_str(), utf16Result);
|
||||
::SetWindowTextW(_hwndEditCtrl, (LPCWSTR) utf16Result.c_str());
|
||||
|
||||
RECT rectDlg, rectEdit1, rectEdit2;
|
||||
|
||||
|
@ -416,15 +421,40 @@ LRESULT CALLBACK CWin32InputBox::DlgProc(HWND hDlg, UINT message, WPARAM wParam,
|
|||
{
|
||||
if (buttonId == definputbox_buttonids[i])
|
||||
{
|
||||
::GetWindowTextA(
|
||||
std::u16string wstrResult;
|
||||
std::string utf8Result;
|
||||
|
||||
int inputLength = ::GetWindowTextLengthW(_this->_hwndEditCtrl);
|
||||
wstrResult.resize(inputLength);
|
||||
|
||||
::GetWindowTextW(
|
||||
_this->_hwndEditCtrl,
|
||||
_this->_param->szResult,
|
||||
_this->_param->nResultSize);
|
||||
(LPWSTR) const_cast<char16_t*>(wstrResult.c_str()),
|
||||
inputLength+1);
|
||||
|
||||
std::string strUtf8 = AnsiToUtf8(_this->_param->szResult);
|
||||
bool conversionResult = cocos2d::StringUtils::UTF16ToUTF8(wstrResult, utf8Result);
|
||||
_this->_param->pstrResult->clear();
|
||||
if (conversionResult)
|
||||
{
|
||||
if((_this->_param->nMaxLength > 0) && (_this->_param->nMaxLength < (DWORD) cocos2d::StringUtils::getCharacterCountInUTF8String(utf8Result)))
|
||||
{
|
||||
// LengthFilter
|
||||
for(size_t pos=0; pos < _this->_param->nMaxLength; pos++)
|
||||
{
|
||||
std::string utf8Bytes;
|
||||
std::u16string utf16Character(1, wstrResult[pos]);
|
||||
|
||||
memset(_this->_param->szResult, 0, _this->_param->nResultSize);
|
||||
strncpy(_this->_param->szResult, strUtf8.c_str(), _this->_param->nResultSize - 1);
|
||||
if(cocos2d::StringUtils::UTF16ToUTF8(utf16Character, utf8Bytes))
|
||||
{
|
||||
_this->_param->pstrResult->append(utf8Bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*(_this->_param->pstrResult) = utf8Result;
|
||||
}
|
||||
}
|
||||
|
||||
::EndDialog(hDlg, buttonId);
|
||||
return TRUE;
|
||||
|
@ -437,55 +467,6 @@ LRESULT CALLBACK CWin32InputBox::DlgProc(HWND hDlg, UINT message, WPARAM wParam,
|
|||
}
|
||||
|
||||
|
||||
std::string CWin32InputBox::AnsiToUtf8(std::string strAnsi)
|
||||
{
|
||||
std::string ret;
|
||||
if (strAnsi.length() > 0)
|
||||
{
|
||||
int nWideStrLength = MultiByteToWideChar(CP_ACP, 0, strAnsi.c_str(), -1, nullptr, 0);
|
||||
WCHAR* pwszBuf = (WCHAR*)malloc((nWideStrLength + 1)*sizeof(WCHAR));
|
||||
memset(pwszBuf, 0, (nWideStrLength + 1)*sizeof(WCHAR));
|
||||
MultiByteToWideChar(CP_ACP, 0, strAnsi.c_str(), -1, pwszBuf, (nWideStrLength + 1)*sizeof(WCHAR));
|
||||
|
||||
int nUtf8Length = WideCharToMultiByte(CP_UTF8, 0, pwszBuf, -1, nullptr, 0, nullptr, FALSE);
|
||||
char* pszUtf8Buf = (char*)malloc((nUtf8Length + 1)*sizeof(char));
|
||||
memset(pszUtf8Buf, 0, (nUtf8Length + 1)*sizeof(char));
|
||||
|
||||
WideCharToMultiByte(CP_UTF8, 0, pwszBuf, -1, pszUtf8Buf, (nUtf8Length + 1)*sizeof(char), nullptr, FALSE);
|
||||
ret = pszUtf8Buf;
|
||||
|
||||
free(pszUtf8Buf);
|
||||
free(pwszBuf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string CWin32InputBox::Utf8ToAnsi(std::string strUTF8)
|
||||
{
|
||||
std::string ret;
|
||||
if (strUTF8.length() > 0)
|
||||
{
|
||||
int nWideStrLength = MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, nullptr, 0);
|
||||
WCHAR* pwszBuf = (WCHAR*)malloc((nWideStrLength + 1)*sizeof(WCHAR));
|
||||
memset(pwszBuf, 0, (nWideStrLength + 1)*sizeof(WCHAR));
|
||||
MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, pwszBuf, (nWideStrLength + 1)*sizeof(WCHAR));
|
||||
|
||||
int nAnsiStrLength = WideCharToMultiByte(CP_ACP, 0, pwszBuf, -1, nullptr, 0, nullptr, FALSE);
|
||||
char* pszAnsiBuf = (char*)malloc((nAnsiStrLength + 1)*sizeof(char));
|
||||
memset(pszAnsiBuf, 0, (nAnsiStrLength + 1)*sizeof(char));
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, pwszBuf, -1, pszAnsiBuf, (nAnsiStrLength + 1)*sizeof(char), nullptr, FALSE);
|
||||
ret = pszAnsiBuf;
|
||||
|
||||
free(pszAnsiBuf);
|
||||
free(pwszBuf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
namespace ui {
|
||||
|
@ -714,16 +695,13 @@ void EditBoxImplWin::openKeyboard()
|
|||
if (placeHolder.length() == 0)
|
||||
placeHolder = "Enter value";
|
||||
|
||||
char pText[100]= {0};
|
||||
std::string text = getText();
|
||||
if (text.length())
|
||||
strncpy(pText, text.c_str(), 100);
|
||||
auto glView = Director::getInstance()->getOpenGLView();
|
||||
HWND hwnd = glView->getWin32Window();
|
||||
bool didChange = CWin32InputBox::InputBox("Input", placeHolder.c_str(), pText, 100, false, hwnd) == IDOK;
|
||||
bool didChange = CWin32InputBox::InputBox("Input", placeHolder.c_str(), &text, _maxLength, false, hwnd) == IDOK;
|
||||
|
||||
if (didChange)
|
||||
setText(pText);
|
||||
setText(text.c_str());
|
||||
|
||||
if (_delegate != nullptr) {
|
||||
if (didChange)
|
||||
|
|
Loading…
Reference in New Issue