Merge pull request #3442 from thedax/win32OSKUnicode

Win32: Update OSK bypass with Unicode/wchar/wstring support.
This commit is contained in:
Henrik Rydgård
2013-08-27 05:54:49 -07:00
6 changed files with 84 additions and 27 deletions
+50 -26
View File
@@ -160,6 +160,32 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_
_string = stringBuffer;
}
void GetWideStringFromPSPPointer(std::wstring& _string, const PSPPointer<u16_le> em_address)
{
if (!em_address.IsValid())
{
_string = L"";
return;
}
const size_t maxLength = 2048;
wchar_t stringBuffer[maxLength];
wchar_t *string = stringBuffer;
auto input = em_address;
int c;
u32 count = 0;
while ((c = *input++) != 0)
{
if ( !(++count >= maxLength) )
*string++ = c;
else
break;
}
*string++ = '\0';
_string = stringBuffer;
}
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const wchar_t *input)
{
char stringBuffer[2048];
@@ -742,7 +768,7 @@ void PSPOskDialog::RenderKeyboard()
// TODO: Use a wstring to allow Japanese/Russian/etc.. on _WIN32(others?)
int PSPOskDialog::NativeKeyboard()
{
char *input = new char[FieldMaxLength()];
wchar_t *input = new wchar_t[FieldMaxLength()];
memset(input, 0, sizeof(input));
if (status == SCE_UTILITY_STATUS_INITIALIZE)
@@ -752,37 +778,35 @@ int PSPOskDialog::NativeKeyboard()
else if (status == SCE_UTILITY_STATUS_RUNNING)
{
std::string initial_text;
ConvertUCS2ToUTF8(initial_text, oskParams->fields[0].intext);
std::wstring titleText;
GetWideStringFromPSPPointer(titleText, oskParams->fields[0].desc);
const size_t defaultText_len = 512;
char defaultText[defaultText_len];
std::wstring defaultText;
GetWideStringFromPSPPointer(defaultText, oskParams->fields[0].intext);
memset(defaultText, 0, sizeof(defaultText));
if(defaultText.length() <= 0)
defaultText.assign(L"VALUE");
if(initial_text.length() < defaultText_len)
strncat(defaultText, initial_text.c_str(), strlen(initial_text.c_str()));
else {
ERROR_LOG(HLE, "NativeKeyboard: initial text length is too long");
strncat(defaultText, "VALUE", strlen("VALUE"));
std::wstring inputWide;
if(!host->InputBoxGetWString(titleText.c_str(), defaultText, inputWide))
{
wcsncat(input, L"", wcslen(L""));
}
else
{
size_t maxInputLength = FieldMaxLength();
char windowTitle[defaultText_len];
memset(windowTitle, 0, sizeof(windowTitle));
std::string description_text;
ConvertUCS2ToUTF8(description_text, oskParams->fields[0].desc);
if(description_text.length() < defaultText_len)
strncat(windowTitle, description_text.c_str(), strlen(description_text.c_str()));
size_t maxInputLength = FieldMaxLength();
if(host->InputBoxGetString(windowTitle, defaultText, input, maxInputLength)) {
strncat(input, "", strlen(""));
if(inputWide.length() < maxInputLength)
{
wcsncat(input, inputWide.c_str(), inputWide.length());
}
else
{
ERROR_LOG(HLE, "NativeKeyboard: input text too long(%d characters/glyphs max), truncating to game-requested length.", maxInputLength);
wcsncat(input, inputWide.c_str(), maxInputLength);
}
}
status = SCE_UTILITY_STATUS_FINISHED;
}
else if (status == SCE_UTILITY_STATUS_FINISHED)
+1
View File
@@ -68,6 +68,7 @@ public:
#ifdef _WIN32
// Implement this on your platform to grab text input from the user for whatever purpose.
virtual bool InputBoxGetString(char *title, const char *defaultValue, char *outValue, size_t outlength) { return false; }
virtual bool InputBoxGetWString(const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue) { return false; }
#endif
// Used for headless.
+22
View File
@@ -85,6 +85,28 @@ bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, con
return false;
}
bool InputBox_GetWString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::wstring &defaultValue, std::wstring &outvalue)
{
const wchar_t *defaultTitle = L"Input value";
defaultSelected = true;
textBoxContents = defaultValue;
if (title && wcslen(title) <= 0)
windowTitle = defaultTitle;
else if (title && wcslen(title) < 255)
windowTitle = title;
else
windowTitle = defaultTitle;
if (IDOK == DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc)) {
outvalue = out;
return true;
}
else
return false;
}
bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t *title, u32 defaultvalue, u32 &outvalue)
{
wchar_t temp[256];
+1
View File
@@ -8,4 +8,5 @@
// All I/O is in UTF-8
bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultvalue, std::string &outvalue, bool selected);
bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultvalue, std::string &outvalue);
bool InputBox_GetWString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue);
bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t *title, u32 defaultvalue, u32 &outvalue);
+9
View File
@@ -309,6 +309,15 @@ bool WindowsHost::InputBoxGetString(char *title, const char *defaultValue, char
}
}
bool WindowsHost::InputBoxGetWString(const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue)
{
if (InputBox_GetWString(MainWindow::GetHInstance(), MainWindow::GetHWND(), title, defaultvalue, outvalue)) {
return true;
} else {
return false;
}
}
// http://msdn.microsoft.com/en-us/library/aa969393.aspx
HRESULT CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszArguments, LPCWSTR lpszPathLink, LPCWSTR lpszDesc) {
+1 -1
View File
@@ -59,7 +59,7 @@ public:
virtual bool CreateDesktopShortcut(std::string argumentPath, std::string title);
bool InputBoxGetString(char *title, const char *defaultValue, char *outValue, size_t outlength);
bool InputBoxGetWString(const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue);
std::shared_ptr<KeyboardDevice> keyboard;
private: