#include "Win32InputBox.h" #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) #include #pragma warning (disable: 4312) typedef struct _MSDN_DLGTEMPLATEEX { WORD dlgVer; WORD signature; DWORD helpID; DWORD exStyle; DWORD style; WORD cDlgItems; short x; short y; short cx; short cy; BYTE _rest[1]; // rest of structure } MSDN_DLGTEMPLATEEX; static bool IsDlgTemplateExtended(DLGTEMPLATE *dlgTemplate) { MSDN_DLGTEMPLATEEX *dgExTemplate = (MSDN_DLGTEMPLATEEX *) dlgTemplate; // MSDN excerpt: //* dlgVer // Specifies the version number of the extended dialog box template. This member must be 1. //* signature // Indicates whether a template is an extended dialog box template. // If signature is 0xFFFF, this is an extended dialog box template. // In this case, the dlgVer member specifies the template version number. // If signature is any value other than 0xFFFF, this is a standard dialog box template that uses the DLGTEMPLATE and DLGITEMTEMPLATE structures. return (dgExTemplate->dlgVer == 1) && (dgExTemplate->signature == 0xFFFF); } // Use alignment if supported by the compiler #ifdef _MSC_VER #if _MSC_VER > 1200 __declspec(align(4)) #endif #endif // per the MSDN, the DLGTEMPLATE must be DWORD aligned // this was generated by the DlgResToDlgTemplate tool static unsigned char definputbox_dlg[] = { 0x01,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x00,0xc8,0x00,0x06, 0x00,0x16,0x00,0x11,0x00,0xe7,0x00,0x6d,0x00,0x00,0x00,0x00,0x00,0x57,0x00,0x69, 0x00,0x6e,0x00,0x33,0x00,0x32,0x00,0x49,0x00,0x6e,0x00,0x70,0x00,0x75,0x00,0x74, 0x00,0x42,0x00,0x6f,0x00,0x78,0x00,0x00,0x00,0x08,0x00,0xbc,0x02,0x00,0x00,0x4d, 0x00,0x53,0x00,0x20,0x00,0x53,0x00,0x68,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x20, 0x00,0x44,0x00,0x6c,0x00,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x80,0x00,0x02,0x50,0x06,0x00,0x04,0x00,0x9d,0x00,0x21,0x00,0xe8, 0x03,0x00,0x00,0xff,0xff,0x82,0x00,0x50,0x00,0x72,0x00,0x6f,0x00,0x6d,0x00,0x70, 0x00,0x74,0x00,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x80,0x00,0x81,0x50,0x06,0x00,0x25,0x00,0xd8,0x00,0x0e,0x00,0xe9, 0x03,0x00,0x00,0xff,0xff,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x84,0x10,0xa1,0x50,0x06,0x00,0x37,0x00,0xd8,0x00,0x31,0x00,0xea, 0x03,0x00,0x00,0xff,0xff,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x00,0x03,0x50,0xab,0x00,0x04,0x00,0x33,0x00,0x0e,0x00,0x01, 0x00,0x00,0x00,0xff,0xff,0x80,0x00,0x4f,0x00,0x4b,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x50,0xab,0x00,0x15,0x00,0x33, 0x00,0x0e,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0x80,0x00,0x43,0x00,0x41,0x00,0x4e, 0x00,0x43,0x00,0x45,0x00,0x4c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x02,0x40,0x00,0x00,0x27,0x00,0x08,0x00,0x08,0x00,0xff, 0xff,0xff,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0x00,0x00 }; static LPCTSTR definputbox_buttonnames[] = { _T("OK"), _T("CANCEL") }; static const INT_PTR definputbox_buttonids[] = { IDOK, IDCANCEL }; static const INT definputbox_id_prompt = 1000, definputbox_id_edit1 = 1001, definputbox_id_edit2 = 1002; WIN32INPUTBOX_PARAM::WIN32INPUTBOX_PARAM() { bMultiline = false; hwndOwner = 0; DlgTemplateName = 0; hInstance = (HINSTANCE) ::GetModuleHandle(0); DlgTemplateData = definputbox_dlg; bCenter = true; dwStylesPlus = 0; dwExStylesPlus = 0; dwStylesMinus = 0xFFFFFFFF; dwExStylesMinus = 0xFFFFFFFF; xPos = yPos = -1; szResult = 0; nResultSize = 0; } CWin32InputBox::CWin32InputBox(WIN32INPUTBOX_PARAM *param) { _param = param; } CWin32InputBox::~CWin32InputBox() { } void CWin32InputBox::SetParam(WIN32INPUTBOX_PARAM *param) { _param = param; } WIN32INPUTBOX_PARAM *CWin32InputBox::GetParam() { return _param; } INT_PTR CWin32InputBox::InputBoxEx(WIN32INPUTBOX_PARAM *param) { // Check mandatory parameters if (param->szResult == 0) { ::SetLastError(ERROR_INVALID_PARAMETER); return 0; } LPDLGTEMPLATE dlgTemplate; if (param->DlgTemplateName != 0) { HMODULE hModule = (HMODULE)param->hInstance; HRSRC rcDlg = ::FindResource(hModule, MAKEINTRESOURCE(param->DlgTemplateName), RT_DIALOG); if (rcDlg == NULL) return 0; HGLOBAL hglobalDlg = ::LoadResource(hModule, rcDlg); if (hglobalDlg == NULL) return 0; dlgTemplate = (LPDLGTEMPLATE) hglobalDlg; } else if (param->DlgTemplateData != 0) { dlgTemplate = (LPDLGTEMPLATE) param->DlgTemplateData; } MSDN_DLGTEMPLATEEX *dlgTemplateEx = IsDlgTemplateExtended((LPDLGTEMPLATE) dlgTemplate) ? (MSDN_DLGTEMPLATEEX *) dlgTemplate : 0; if (dlgTemplateEx != 0) { dlgTemplateEx->exStyle |= param->dwExStylesPlus; dlgTemplateEx->style |= param->dwStylesPlus; dlgTemplateEx->exStyle &= param->dwExStylesMinus; dlgTemplateEx->style &= param->dwStylesMinus; if (param->bCenter) dlgTemplateEx->style |= DS_CENTER; if (param->xPos != -1) dlgTemplateEx->x = param->xPos; if (param->yPos != -1) dlgTemplateEx->y = param->yPos; } else { dlgTemplate->dwExtendedStyle |= param->dwExStylesPlus; dlgTemplate->style |= param->dwStylesPlus; dlgTemplate->dwExtendedStyle &= param->dwExStylesMinus; dlgTemplate->style &= param->dwStylesMinus; if (param->bCenter) dlgTemplate->style |= DS_CENTER; if (param->xPos != -1) dlgTemplate->x = param->xPos; if (param->yPos != -1) dlgTemplate->y = param->yPos; } CWin32InputBox inputbox(param); // Resize dialog and SHOW or HIDE multiline INT_PTR r = ::DialogBoxIndirectParam(param->hInstance, dlgTemplate, param->hwndOwner, (DLGPROC)DlgProc, (LPARAM)&inputbox); return r; } INT_PTR CWin32InputBox::InputBox( LPCSTR szTitle, LPCSTR szPrompt, LPSTR szResult, DWORD nResultSize, bool bMultiLine, HWND hwndParent) { WIN32INPUTBOX_PARAM param; param.szTitle = szTitle; param.szPrompt = szPrompt; param.szResult = szResult; param.nResultSize = nResultSize; param.bMultiline = bMultiLine; return InputBoxEx(¶m); } void CWin32InputBox::InitDialog() { // Set the button captions for (size_t i=0;ihDlg, (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()); HWND hwndEdit1 = ::GetDlgItem(_param->hDlg, definputbox_id_edit1); HWND hwndEdit2 = ::GetDlgItem(_param->hDlg, definputbox_id_edit2); if (_param->bMultiline) _hwndEditCtrl = hwndEdit2; else _hwndEditCtrl = hwndEdit1; ::SetWindowTextA(_hwndEditCtrl, Utf8ToAnsi(_param->szResult).c_str()); RECT rectDlg, rectEdit1, rectEdit2; ::GetWindowRect(_param->hDlg, &rectDlg); ::GetWindowRect(hwndEdit1, &rectEdit1); ::GetWindowRect(hwndEdit2, &rectEdit2); if (_param->bMultiline) { ::ShowWindow(hwndEdit1, SW_HIDE); ::SetWindowPos( hwndEdit2, HWND_NOTOPMOST, rectEdit1.left - rectDlg.left, (rectEdit1.top - rectDlg.top) - (rectEdit1.bottom - rectEdit1.top), 0, 0, SWP_NOSIZE | SWP_NOZORDER); ::SetWindowPos( _param->hDlg, HWND_NOTOPMOST, 0, 0, rectDlg.right - rectDlg.left, rectDlg.bottom - rectDlg.top - (rectEdit1.bottom - rectEdit1.top), SWP_NOMOVE); } else { ::SetWindowPos( _param->hDlg, HWND_NOTOPMOST, 0, 0, rectDlg.right - rectDlg.left, rectEdit1.bottom - rectDlg.top + 5, SWP_NOMOVE); ::ShowWindow(hwndEdit2, SW_HIDE); } } // Message handler for about box. LRESULT CALLBACK CWin32InputBox::DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { CWin32InputBox *_this = (CWin32InputBox *) ::GetWindowLong(hDlg, GWL_USERDATA); WIN32INPUTBOX_PARAM *param = _this ? _this->GetParam() : 0; switch (message) { case WM_INITDIALOG: { ::SetWindowLong(hDlg, GWL_USERDATA, (LONG) lParam); _this = (CWin32InputBox *) lParam; _this->_param->hDlg = hDlg; _this->InitDialog(); return TRUE; } case WM_COMMAND: { #ifdef _MY_DEBUG CHAR buf[1024]; static int i=0; sprintf(buf, "WM_COMMAND: %09d wParam=%08X lParam=%08X\n", i++, wParam, lParam); OutputDebugString(buf); #endif INT_PTR buttonId = LOWORD(wParam); for (size_t i=0; i_hwndEditCtrl, _this->_param->szResult, _this->_param->nResultSize); std::string strUtf8 = AnsiToUtf8(_this->_param->szResult); memset(_this->_param->szResult, 0, _this->_param->nResultSize); strncpy(_this->_param->szResult, strUtf8.c_str(), _this->_param->nResultSize-1); ::EndDialog(hDlg, buttonId); return TRUE; } } } break; } return FALSE; } std::string CWin32InputBox::AnsiToUtf8(std::string strAnsi) { std::string ret; if (strAnsi.length() > 0) { int nWideStrLength = MultiByteToWideChar(CP_ACP, 0, strAnsi.c_str(), -1, NULL, 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,NULL,0,NULL,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), NULL, 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, NULL, 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,NULL,0,NULL,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), NULL, FALSE); ret = pszAnsiBuf; free(pszAnsiBuf); free(pwszBuf); } return ret; } #endif /* #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) */