mirror of https://github.com/axmolengine/axmol.git
384 lines
11 KiB
C++
384 lines
11 KiB
C++
#include "Win32InputBox.h"
|
|
|
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
|
|
|
#include <stdio.h>
|
|
|
|
#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;
|
|
#ifdef __MINGW32__
|
|
HRSRC rcDlg = ::FindResource(hModule, (LPWSTR)(ULONG_PTR)(size_t)(param->DlgTemplateName), RT_DIALOG);
|
|
#else
|
|
HRSRC rcDlg = ::FindResource(hModule, MAKEINTRESOURCE(param->DlgTemplateName), RT_DIALOG);
|
|
#endif
|
|
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;i<sizeof(definputbox_buttonids)/sizeof(definputbox_buttonids[0]);i++)
|
|
::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());
|
|
|
|
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<sizeof(definputbox_buttonids)/sizeof(definputbox_buttonids[0]);
|
|
i++)
|
|
{
|
|
if (buttonId == definputbox_buttonids[i])
|
|
{
|
|
::GetWindowTextA(
|
|
_this->_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) */
|