54485

Modify main window's locale after user changes settings in Control Panel->Regional and Langu

Question:

<h2>INTRODUCTION AND RELEVANT INFORMATION:</h2>

I have MS Access 2007 database which I fill using ADO.

Among other data types ( string, integer...) I also have a double.

Since I work on Windows XP and use pure Win32 API to create GUI, I collect data from edit controls with GetDlgItemText API and then I convert that text into double using _wtof_l.

<h2>PROBLEM:</h2>

Everything works well if the user sets English or Serbian ( we use European notation for decimal and group separator ) locale and <strong>then starts the program</strong>, but the problem occurs when user changes locale settings <strong>while the program is working.</strong>

Let me demonstrate this on a small example:

Let us assume that user has English locale set.

Then user starts my application.

Then user decides to change the locale ( Control Panel->Regional and Language Settings for Windows XP ) before he hits the "Save" button.

After the changes apply he then enters data and then hits "save".

The error in converting text to double must occur ( _wtof_l will now truncate 1.25 to 1 ), since my program uses default ANSI "C" locale and did not adapt it to reflect users modification.

<h2>MY EFFORTS TO SOLVE THE PROBLEM:</h2>

To prevent this I need to adapt my program to the possibility described above-I need to set my locale to the one user selected before executing query.

To do so I use <a href="https://stackoverflow.com/questions/21504075/is-there-a-message-or-notification-in-win32-that-detects-when-user-changes-local" rel="nofollow">message from answer to my previous question</a> to detect when user changes settings in Control Panel->Regional and Language Options.

Then I use _wsetlocale(LC_ALL,"") to set my applications locale to the one selected by the user.

However, wrong conversion from text to decimal number described above still occurs.

This only happens when I change the locale during my program's work. If I leave locale untouched ( as 99.9% of users will ) everything seems to work fine.

To further help the community I have made a demo application that illustrates the problem. It will be presented in the <strong>APPENDIX</strong> section at the end of this post.

<h2>QUESTION:</h2>

How can I respond to WM_SETTINGCHANGE message to set my application's locale to the one currently selected by the user so my "save" button handler can perform proper conversion from string to double with _wtof_l function?

Thank you.

Best regards.

<h2>APPENDIX:</h2>

Steps to create the demo application that illustrates my problem:

1.Create default Win32 project in Visual Studio.

2.Add the following WM_CREATE handler:

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.Add the following handler to detect when user changes locale settings

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 handler add the following 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 database in the project folder.

6.Create table MyTable and add 2 fields field1 as TEXT field, and add field2 which is double.

Answer1:

The problem was in improper setting of the current locale.

I was using the wrong function to do that.

I do not wish to steal other people's credits so <a href="http://www.codeproject.com/Questions/719903/Set-main-windows-locale-to-the-locale-set-by-user?loginkey=false" rel="nofollow">here</a> is the link where I got the solution from.

This way, any time user changes local settings in <em>Control Panel</em>, my application will be able to properly convert string to double and my INSERT queries will not have errors!

Hopefully this will help others with the same problem.

Recommend

  • How do CL commands build their exact parameter lists?
  • Gnuplot multiplot: Convenient method for creating more complex layouts
  • Using bitbake is it possible to have a different do_install for a package based on the target image?
  • Autohotkey script running program with command line arguments
  • In Akka, is ActorContext thread safe?
  • How to use the resource module to measure the running time of a function?
  • Counting Treaps
  • How do I check if System::Collections:ArrayList is empty / nullptr / null?
  • How can I restyle a word when rendering a pdf with pdf.js?
  • Image map in Flex
  • Who propagate bugfixes across branches (corporate development)?
  • converting text file into xml using php?
  • Code in Job's Script Block after Start-Process Does not Execute
  • MySQL Order by column = x, column asc?
  • How to define custom class, title, and target in Link Browser for content elements and the new rte_c
  • Retrieve list of sent friend requests from friend_request FQL table
  • Blackberry - Custom EditField Cursor
  • Ionic 2 storage is not cleaning up on uninstall - Only for signed APK
  • preg_replace Double Spaces to tab (\\t) at the beginning of a line
  • Content-Length header not returned from Pylons response
  • ActiveRecord query for a count of new users by day
  • Can you perform a UNION without a subquery in SQLAlchemy?
  • PostgreSQL Query without WHERE only ORDER BY and LIMIT doesn't use index
  • NHibernate Validation Localization with S#arp Architecture
  • Ajax Loaded meta Tags
  • Xamarin Forms - UWP Fonts
  • How can I send an e-mail from a vbs script
  • Accessing IRQ description array within a module and displaying action names
  • javascript inside java/jsp code
  • Arrow is showed instead of the material design version hamburger icon. Why doesn't syncState in
  • Updated Ionic CLI but shows previous version (Windows)
  • Display Images one by one with next and previous functionality
  • Jquery - Jquery Wysiwyg return html as a string
  • Arrays break string types in Julia
  • SQL merge duplicate rows and join values that are different
  • WPF Applying a trigger on binding failure
  • Getting Messege Twice Using IMvxMessenger
  • Java static initializers and reflection
  • Conditional In-Line CSS for IE and Others?
  • How to push additional view controllers onto NavigationController but keep the TabBar?