Изменить язык главного окна после того, как пользователь изменит настройки в Панели управления -> Язык и региональные стандарты

ВВЕДЕНИЕ И СООТВЕТСТВУЮЩАЯ ИНФОРМАЦИЯ:

я имею MS Access 2007 База данных, которую я заполняю, используя ADO,

Среди других типов данных ( string, integer…) У меня тоже есть double,

Так как я работаю над Windows XP и использовать чистый Win32 API чтобы создать графический интерфейс, я собираю данные из edit контролирует с GetDlgItemText API а затем я преобразую этот текст в double с помощью _wtof_l,

ПРОБЛЕМА:

Все работает хорошо, если пользователь устанавливает английский или сербский язык (мы используем европейские обозначения для десятичного разделителя и разделителя групп) и затем запускает программу, но проблема возникает, когда пользователь меняет настройки локали пока программа работает.

Позвольте мне продемонстрировать это на небольшом примере:

Предположим, что у пользователя установлен английский языковой стандарт.

Затем пользователь запускает мое приложение.

Затем пользователь решает изменить локаль ( Control Panel->Regional and Language Settings за Windows XP ), прежде чем он нажмет кнопку «Сохранить».

После внесения изменений он вводит данные и затем нажимает «сохранить».

Ошибка в преобразовании текста в 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.Create default Win32 project в Visual Studio,

2. Добавьте следующее WM_CREATE обработчик:

case WM_CREATE:
{
_wsetlocale( LC_ALL, L"" ); //set current locale at window creation

INITCOMMONCONTROLSEX iccex;
memset( &iccex, 0, sizeof(INITCOMMONCONTROLSEX) );
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_STANDARD_CLASSES | ICC_TAB_CLASSES | ICC_BAR_CLASSES;
InitCommonControlsEx( &iccex );

// text

HWND hEdit = CreateWindowEx( 0, L"Edit", L"",
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
50, 50, 150, 25, hWnd, (HMENU)8002, hInst, 0 );

// decimal number

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"" ); //set it to current locale
return 0L; // "say" we handled it
}
else
break; // pass it to default window procedure

4.In WM_COMMAND обработчик добавить следующее cases:

case 8004:
{
// initialize COM
HRESULT hr = CoInitialize(NULL);

// format connection string
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 );    // text
GetDlgItemText( hWnd, 8003, number, 5 );   // double

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(); // close connection

CoUninitialize(); // uninitialize COM
}
else
throw _com_error(hr); //something failed-report it
}
catch(_com_error& e)
{
MessageBox(hWnd, (LPWSTR)(e.Description()), L"Error", MB_OK |
MB_ICONERROR );

CoUninitialize();
}

}
break;

5.Create MS Access 2007 База данных в папке проекта.

6.Создать таблицу MyTable и добавить 2 поля field1 как TEXT поле и добавить field2 который double,

1

Решение

Проблема была в неправильной настройке тока locale,

Я использовал неправильную функцию, чтобы сделать это.

Я не хочу воровать чужие кредиты так Вот это ссылка, откуда я получил решение.

Таким образом, каждый раз, когда пользователь меняет локальные настройки в Панель управления, мое приложение сможет правильно конвертировать string в double и мой INSERT запросы не будут иметь ошибок!

Надеюсь, это поможет другим с той же проблемой.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]