'Locale' configuration and its relationship with Windows API - windows

Can the locale configuration of a system OR the keyboard type configuration of that system in anyway affect which API is called at the Kernel level? To be specific, if a program is invoking 'CreateFile()' API then the windows API documentation says that the call gets delegated to either CreateFileA or CreateFileW. If that program is being run on a system present in China with a Chinese Keyboard then which of the two functions will be called?

Unicode and Locale are two completely orthogonal concepts.
With regards to CreateFileA vs CreateFileW - the setting that controls this is a compile time setting: If the application is compiled to run with the Unicode character set, then CreateFileW will be called, if the compile settings indicated that the application should be compiled as a multibyte application, then CreateFileA will be called.
If you are using Visual Studio C++, then examine the Project settings of the application. Under Configuration Properties, on the page called "General" will be a setting "Character Set" - This can be set to "Use Unicode Character Set", or "Use Multi-Byte Character Set". The effect of this setting is to automatically add another property sheet to the solution - visible under the Property Manager: The "Unicode Support" property sheet adds the preprocessor definitions "_UNICODE,UNICODE" - the "Multi-Byte Character Support" property sheet instead adds "_MBCS".
Now, if you look at the definition for CreateFile you will see it is a macro itself, and when you build your application, all CreateFile calls in the code will resolve to CreateFileW calls if UNICODE is defined, and CreateFileA calls otherwise.
UNICODE is used by windows.h to switch between the Wide and Ansi versions of the windows API calls.
_MBCS and _UNICODE are used by the Microsoft C Runtime headers - principally tchar.h - to switch the c-library from supporting single byte to multi byte to unicode characters on functions that support that.

Related

What is the Windows "WorkerW" windows and what creates them?

On some Windows 10 computers (and possibly older versions) there are sometimes "WorkerW" windows that show up in the list from a call to EnumWindows. This is not on all computers - just some. What are these windows and what creates them?
It is basically created by calling Shell API function SHCreateWorkerWindowW. W stands for widechar (unicode) version of the window vs. SHCreateWorkerWindowA for ascii version. Any application that needs to listen to window messages call this Api to create a worker window. The API is basically a wrapper around CreateWindowEx but with window class name that is hardcoded to "WorkerW" or "WorkerA".
Comment requested to provide supporting documentation. Unfortunately, there is no documentation on MSDN because this is an undocumented function. If you look at the disassembly of SHCreateWorkerWindowA in shlwapi.dll you can verify this easily. Alternatively, you can do a GetProcAddress() for SHCreateWorkerWindowA and call the function to create the worker window.

ResourceManager returning null for default culture

I'm working on a Xamarin Forms app, using a .NET Standard library. I've used the TranslateExtension as mentioned in the docs. I've added three resource files:
AppResources.resx (with matching code-behind file, auto-generated)
AppResources.nl.resx (Dutch translations)
AppResources.fr.resx (English tranlations)
When debugging the (UWP) app, I can't get the default culture (English) to be displayed. The following line returns null:
ResMgr.Value.GetString(Text, ci);
I've add some lines for debugging, and the other two languages do return the translated value:
ResMgr.Value.GetString(Text, new CultureInfo("nl")); // OK
ResMgr.Value.GetString(Text, new CultureInfo("fr")); // OK
ResMgr.Value.GetString(Text, new CultureInfo("en")); // returns null
What could possibly be the cause of this?
Things I've tried:
I've copy-pasted the key across all resource files, so I've ruled out misspelling the resource key.
I've tested "en-GB", "en-US", CultureInfo.InvariantCulture.
I've changed the default lanuage in the appxmanifest from en-US to en.
On UWP, watch that your resource name does not have a period in it..
You also likely need to tell the UWP project what its default language is. This can be done in the .csproj in the top <PropertyGroup> element (the one with no conditions) by adding <DefaultLanguage>en-US</DefaultLanguage> (using the proper culture for your scenario).
Don't forget to set the [assembly: NeutralResourcesLanguage("en-US")] as well for the assembly containing the resources - this is required for .NET Standard 2.0 and likely PCL.
Well it seems like you've got resx files for "nl" and "fr" (which you've said works fine) but you don't have one for "en". If you're trying to get the English value like that, I would think you need an "en" file the same way you do for "nl" and "fr"
I noticed that you told about NET Standard library
ResourceManager.GetString started giving null for new entries after moving from PCL to .NET Standard
I also observed that the file AppResources.Designer.cs disapeared from the Solution Explorer (but I don't know how, was still considered) and, in the VS res editon of AppResources.resx, Access Modifier was No Code Generation.
Here is what I did to fix that:
I double-clicked on AppResources.resx and set Access Modifier to Internal or Public
In .NET Standard you may no longer be able to see "View Code" from resx files; so, I righ-clicked on AppResources.resx-> Open With -> Source Code Editor and copy the new created entries to all the others *.fr (also *.nl in your case) ...
NOTE
In the context menu you should see Run Custom Tool. You may need to delete the old AppResources.Designer.cs and do "Run Custom Tool"
Don't forget to clear the solution (or olny UWP and the standard library), close VS, delete all .\bin and .\obj and restart VS. This to ensure your issue is fixed or not using the very very new generated true code :)

How does the language bar (input language) impact keyboard hooks?

I ran into a reproducible bug which doesn't really make sense to me. Hopefully someone knows more about the internals of keyboard input under Windows (I'm using Windows 7) and can point me in the right direction on how to solve it. As it stands now I don't really know where I should start to look.
My application creates a global keyboard hook, using the MouseKeyboardActivityMonitor library. This was working fine for me, but I quickly received bug reports from people using different keyboard input languages. When they write letters with accents, e.g. ë and ê, they show up as ¨¨e and ^^e respectively. This bug is also reported on the library's website, but hasn't been resolved yet.
To try to reproduce the bug I set up an alternate input language 'Dutch (Belgium)' next to my existing 'English (United States)'. After some toying around I discovered the following:
The bug doesn't occurs when the application which installs the hook has focus, and language is set to 'English (United States)'. Writing in any other application (e.g. notepad) and using 'Dutch (Belgium)' to write the special characters work. The bug does occur when the application which installs the hook has focus, and language is set to 'Dutch (Belgium)'.
I am looking for any clue as how the two are related. Perhaps I need to introduce some extra checks in the keyboard hook library? The source code of the keyboard hook is available on line.
It seems that the input language is not updated in your application. Looking at the source code of the library that you are using, it seems that they use this call to get the correct keyboard layout:
internal static extern uint GetKeyboardLayout( int dwLayout );
The documentation of this method however emphasises:
The input locale identifier is a broader concept than a keyboard
layout, since it can also encompass a speech-to-text converter, an
Input Method Editor (IME), or any other form of input. Since the
keyboard layout can be dynamically changed, applications that cache
information about the current keyboard layout should process the
WM_INPUTLANGCHANGE message to be informed of changes in the input
language.
However, based on a quick glance at the code, the library does not seem to respond to this WM_INPUTLANGCHANGE message, which might cause this behaviour
Also, here is a useful link to an explanation how the Keyboard is handled by Windows

ActiveX Control - MFC Locale

I have an MFC application developed with Visual Studio 2008 where I use Adobe ActiveX control (I have Adobe Reader X installed). I try to set the zooming rectangle using the setViewRect function and it works perfectly.
Now the problem appears when in my Windows Regional Settings, the decimal symbol is set to comma instead of dot (such as in the German Regional Settings). The parameters of the zooming rectangle seem to be interpreted incorrectly.
I used ProcessMonitor and discovered that when Adobe ActiveX Control is created and its DLL is loaded in my process, it calls setlocale, and hence the application is using the current Windows Regional Settings instead of the default "C" locale. Therefore, the application interprets the numbers in a wrong way.
I tried to reset the locale to "C" right after loading Adobe and this workaround fixed the problem.
Now the problem happened again when I migrated my application to Visual Studio 2010. Apparently Adobe DLL ("c:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX\AcroPDF.dll") is developed using Visual Studio 2008. So when it sets the locale, it is done in MSVCR90.dll. When I reset the locale, I did so using the same DLL.
Now as my application is in VS2010, calling setlocale is done in MSVCR100.dll, so it does not affect the locale already set in MSVCR90.dll.
Is there a way to set the locale of the COM object that I am hosting inside my application?
Thank you so much in advance :)
This is just a shot in the dark, but you could try loading MSVCR90.dll with LoadLibrary (since the DLL is already loaded, it'll just give you a HANDLE to it, it won't load it twice), then finding the pointer to its setlocale function with GetProcAddress. Then you will be able to call the setlocale function for this DLL. It's an ugly hack, but it might work.

QT and Win32 Console Applications

I have a Win32 console app that is showing this behavior.
1) Using VC 2005 cl to compile and link, the application works fine. What I mean by working fine is that characters above 128 display correctly according to Code Page 437.
2) When I use QT qmake to construct a project (QT += console) and SOURCES = main.c, the build goes fine and my main.exe is created. But the characters above 128, using WriteConsoleOuput function display differently (some weird characters). I have the felling that this has to do with the Code Page not being set up correctly. I did not call any QT functions, neither have I created QApplication, or QCoreApplication object. When I created QApplication Object or QCoreApplication Object, the results where the same (Not displaying the correct characters).
Is there anyway to display the characters above 128 correctly using Win32 console and QT ?
I certainly wouldn't recommend using WriteConsoleOuput if that's a Windows specific API. Qt provides an easy way to write out strings using QTextStream:
// setup
QFile f;
f.open(stdout, QIODevice::WriteOnly);
QTextStream qout(&f);
// usage
qout << tr("translate this text");
I would recommend you use UTF-8 for everything, if possible. Then you don't have to worry about the different encodings, etc. If you are required to output in your local encoding for some reason, then consider QString::fromLocal8bit().
I solved the problem by using WriteConsoleA functions.

Resources