INTRODUCTION AND RELATED INFORMATION:
I have a database MS Access 2007that I populate with ADO.
Among other data types ( string, integer...) I also have double.
Since I work on Windows XPand use pure Win32 APIto create a GUI, I collect data from editcontrols with GetDlgItemText API, and then convert this text to doublewith _wtof_l.
Problem:
Everything works well if the user sets English or Serbian (we use European notation for the decimal and group separator) and then launches the program , but the problem occurs when the user changes the locale settings while the program is running.
Let me demonstrate this with a small example:
Suppose the user has English.
Then the user launches my application.
The user then decides to change the locale ( Control Panel->Regional and Language Settingsfor Windows XP) before he clicks the Save button.
After making the changes, he then enters the data and then deletes "save".
double (_wtof_l 1.25 1), ANSI "C" locale .
:
, - , .
, , Control Panel->Regional and Language Options.
_wsetlocale(LC_ALL,""), , .
, , .
, . ( 99,9% ), , , .
, , .
.
:
WM_SETTINGCHANGE, , , "" string double _wtof_l?
.
.
:
, :
1. default Win32 project Visual Studio.
2. WM_CREATE:
case WM_CREATE:
{
_wsetlocale( LC_ALL, L"" );
INITCOMMONCONTROLSEX iccex;
memset( &iccex, 0, sizeof(INITCOMMONCONTROLSEX) );
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_STANDARD_CLASSES | ICC_TAB_CLASSES | ICC_BAR_CLASSES;
InitCommonControlsEx( &iccex );
HWND hEdit = CreateWindowEx( 0, L"Edit", L"",
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
50, 50, 150, 25, hWnd, (HMENU)8002, hInst, 0 );
HWND hEdit1 = CreateWindowEx( 0, L"Edit", L"",
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
250, 50, 150, 25, hWnd, (HMENU)8003, hInst, 0 );
HWND hButton = CreateWindowEx( 0, L"Button", L"Save",
WS_CHILD | WS_VISIBLE | WS_BORDER | BS_PUSHBUTTON,
50, 150, 150, 25, hWnd, (HMENU)8004, hInst, 0 );
SendMessage( hEdit, EM_LIMITTEXT, (WPARAM)9, (LPARAM)0 );
SendMessage( hEdit1, EM_LIMITTEXT, (WPARAM)4, (LPARAM)0 );
}
return 0L;
3. , ,
case WM_SETTINGCHANGE:
if( !wParam && !wcscmp( (wchar_t*)lParam, L"intl" ) )
{
_wsetlocale( LC_ALL, L"" );
return 0L;
}
else
break;
4.In WM_COMMAND case s:
case 8004:
{
HRESULT hr = CoInitialize(NULL);
wchar_t *bstrConnect= L"Provider=Microsoft.ACE.OLEDB.12.0; \
Data Source = .\\test.accdb";
try
{
ADODB::_ConnectionPtr pConn("ADODB.Connection");
hr = pConn->Open(bstrConnect, L"admin", L"", ADODB::adConnectUnspecified);
if ( SUCCEEDED(hr) )
{
wchar_t text[10], number[5];
memset( &text, L'\0', sizeof(text) );
memset( &number, L'\0', sizeof(number) );
GetDlgItemText( hWnd, 8002, text, 10 );
GetDlgItemText( hWnd, 8003, number, 5 );
ADODB::_CommandPtr pCmd("ADODB.Command");
pCmd->ActiveConnection = pConn;
pCmd->CommandText = L" insert into MyTable ( field1, field2 ) values ( ?, ? );";
pCmd->Parameters->Append( pCmd->CreateParameter( "?", ADODB::adDouble,
ADODB::adParamInput, sizeof(double),
_wtof_l( number, _get_current_locale() ) ) );
pCmd->Parameters->Append( pCmd->CreateParameter( "?",
ADODB::adVarWChar, ADODB::adParamInput,
wcslen(text), text ) );
pCmd->Execute( NULL, NULL, ADODB::adCmdText );
pConn->Close();
CoUninitialize();
}
else
throw _com_error(hr);
}
catch(_com_error& e)
{
MessageBox(hWnd, (LPWSTR)(e.Description()), L"Error", MB_OK |
MB_ICONERROR );
CoUninitialize();
}
}
break;
5. MS Access 2007 .
6. MyTable 2 field1 TEXT field2, double.