Pick appropriate .rc file on language selection - c++

In my MFC application,there are three resource files(.rc) for three different languages(jap,eng,russian) and one main.rc file which includes other three resource file.All resource files contains same resource string in different languages and they all includes same resource header resource.h.
When user runs the application ,popup window will appear asking user to select one language.Based on the user selection application has to select appropriate rc from which it will load resources.
Is there any way by which when user select one language application will pick appropriate resource file.

In the MFC this is done via satellite DLLs.
Place each language RC in a separate DLL. Than upon load of the application load the specific language DLL and use AfxSetResourceHandle with this handle.
In this case resource are searched in this DLL.

An alternative is to consider adding additional stringtables to your project.
More details are provided here:
http://www.dev102.com/2008/10/20/how-to-localize-your-application-using-string-tables/
Basically, you add an additional table and set the culture information in the resource editor. Then, you can specify that culture before getting the value.
The example provided is for C# but the principles are just the same.
A possible way forward if needed.

Related

Sitecore Media Library restrict upload folder to specific file type / extension

I am using Sitecore 6.6.0 and need a way to limit uploading specific files types (png, jpg, gif) etc. to folders within the Media Library
There is a plugin called Media Library Policemen, but I am not allowed to use a module, plus it doesn't show the user an appropriate error message when he's trying to upload a forbidden file type.
I am kind of a Sitecore novice not sure what's the best way. Any recommendations?
I haven't tested this, but theoretically, if you are able to add your own custom code, then Sitecore has the ability to assign folders to have Insert Rules OR Insert Options. Insert Rules take an argument of Type which is really the assembly and the method name and allows you to dictate Insert rules for what can be inserted. This allows you to write or use your own custom code. Media Library Policeman has the source control available to use. You should be able to look at the code for this and use or adapt it for your purposes. Then you can use the Insert Rule to determine what can be added to the folder and remove the insert options.

VC++ 10 MFC: What is the correct way to do localization

I am a .NET guy who is having to do some work on an MFC app. The app is a VS2008 MFC executable which I have converted to VS2010. The original developers did localisation by specifying the name of a .txt file with key value pairs in it on the applications command line. Installed shortcuts to the executable specify a different .txt file depending on which country the app is being installed in. This of course does not work if you just run the .exe directly. This seems like a weird way to do things to me.
I want to do this the propper MFC way, but I am having difficulty finding definitive answers on Google. My understanding is that the String Table in the .rc file should be used for this localisation? Is this the current best practice for MFC?
With respect to the String Table I have read that the practice is to create multiple string tables each for a different language. How do MFC applications choose which language to use? Is it based on the machines current language settings or can I control this (it may be that we want the language to be specified by the Wix .msi installer we are also building)?
I have also read that embedding all resource inside an MFC application has fallen out of favor and that now you should compile seperate resource .dlls? Is this is true ill investigate how to do it...
Finally, do I have to do something special to get MFC to support Unicode or is MFC Unicode by default?
Thanks
The idea is that all localizable items should be stored in resources. Standard UI objects such as menus and dialogs are automatically stored in there (resources) for you but items such as string literals (eg: error messages, messagebox prompts,...) should be pulled from source code to the string table. This short codeproject article of mine demonstrates how to easily pull strings from the string table in your code.
Note: You should have only one string table in your resource script (.rc).
From there on, you can translate your resources and create resource DLLs (aka satellite DLLs). The idea is that you keep a different copy of the .rc file(s) for each language. Each translation is compiled into a codeless DLL that acts as a container for the resources.
This other codeproject article of mine lets you easily load resource DLLs according to system settings or user preferences: The code looks among your resource DLLs which available language best matches user settings (based on user's UI language and regional settings). The code also lets you easily build a menu with all available languages. That way, your user can override the default choice.
DISCLAIMER: My ad follows. Feel free to skip :-)
Regarding the translation of resources, the management of translations and the creation of resource DLLs, you may want to check out appTranslator.
END OF AD :-)
Regarding Unicode, MFC ships with ANSI and Unicode versions of the code. It's up to you to choose if you want to build an ANSI or a Unicode app: Just make your pick in the first page of project settings. Of course, if you are startgin from scratch, you should definitely go Unicode. But if legacy reasons force you to stay ANSI/MBCS, don't worry to much: It won't prevent you from localizing your app.
Years ago when I had to work with multiple languages in MFC, we used separate resource DLLs. All you need do is make one call to switch which handle the resource functions would use and all was automatic from that point forward.
You need to do more than just change the strings. Dialogs in particular will have strings inside of them, and you may need to change the layout if those strings become too long after translation.

"Conditional" macros in visual studio 2010 property manager

The property manager allows having different property sets for different configurations - for example, release and debug.
However, it still means you have to manually assign each property file to each configuration.
Is there some method to automatically assign a property set to a project based on some parameters (like configuration or platform)
a specific example:
I have a solution with many sub-projects.
this projects depend on various external libraries.
for each external library I have a .props file with the relevant directories and other parameters (include , lib, dll's...)
In some cases the directory names can be easily constructed using the default macros such as $(Configuration), $(Platform), etc.
However some libraries come with a less standard \ consistent naming convention.
for these cases I create .props file which are specific to a configuration (Debug\Release) - but it requires assigning the manfully to each project, which is tedious and error prone.
This is possible, at least in principle, see this post, for example. However, I did not find a practical way to use the whole power of MSBuild in combination with c++ projects from within the IDE. Whatever smart MSBuild expressions you write down in your property sheet, once you fire up the property manager dialog in the IDE everything gets overwritten with either defaults or the values inferred from there. This is an odd behaviour and completely different from other project types. Looks like they just wanted to keep the old pre-MSBuild style of editing VCProjects...
You can record a macro and use VBA to create/generate these with a button click.

MFC resource.h command/message IDs

I'm working on an MFC application, that got pretty messy over years and over different teams of developers. The resource.h file, which contains all command/message mappings grew pretty big over time, and has lots of problems (like duplicate IDs). I am not proficient with MFC, so the question might sound pretty stupid...
MSDN docs mention that Command IDs and Message IDs should not be less than WM_USER and WM_APP correspondingly. I saw that most of the command IDs in resource.h generated by Visual Studio begin around 100. Shouldn't this cause some interfering with MFC/Windows commands and messages, that overlap with the application defined IDs? For example, I have a command ID :
#define ID_MY_ID 101
and there is a windows command that has the same ID. When MC send this command to the APP, it's handled like an application defined ID_MY_ID, and the app is taking unnecessary actions. Is it a possible scenario?
Also, is there some third party tool that helps to profile the project resources?
Update 1:
New question showed up:
What is the preferred way of adding new custom commands to the application classes? As I understood, before they were added in the following way: add a command ID to the resouce.h, and then add a message map handler to the handling class.
You are mixing two things:
Message IDs. These must be larger than WM_USER. Message IDs are not defined in resource.h. It seems from your description that you are not using application private messages.
Command IDs. Your application itself must not have duplicate command IDs. The command ID values should also not interfere with the standard MFC IDs defined in afxres.h. Theses command IDs start at 0xE100, so it is unlikely that the values in resource.h. The resource compiler will generate an error for duplicate IDs in you rc file
There is probably no need for you to edit resource.h manually.
I would recommend to use the "Resource symbols" tool (right click on the resources in resource view and choose from the popup menu, I assume you are using VC++), to remove all the unused IDs from resource.h.
command messages are sent in WM_COMMAND with command id in parameter so it won't conflict other messages.
Generally, there is no need to insert or edit the identifiers in resources manually (identifiers assingned by VS automatically in a correct manner). There are some cases that require manual interference in identifiers, but you can start with assumption, that work of previous teams of developers with resources was right. So if you did not encountered a problem because of resources, keep them untouched (IMHO).
"MSDN docs mention that Command IDs and Message IDs should not be less than WM_USER and WM_APP correspondingly." - It seems you something mixed up.

Embedding multiple, identically named resource (RC) files in a native DLL

For my application (an MMC snap-in) I need to create a single native DLL containing strings that are localized into different languages. In other words, if you were to inspect this DLL with Visual Studio, you would see multiple string tables, each associated with a different locale but containing the same string IDs.
The approach I would like to take is to have various subdirectories under my project directory such as "de", "en", "es", etc (i.e. one for each language). Inside each subdirectory would be a file called "Resources.rc" which would be the RC file containing the strings for that language. Having my resources in this structure would be ideal for the localisation team.
I have managed to create my various RC files and have added them to my Visual C++ project. They all appear correctly in Solution Explorer in Visual Studio (you basically see five instances of an entry called "Resource.rc", but each entry points to a different file).
The problem comes with building my project. It seems that only a single one of the RC files (the one that is specified first in the vcproj file) is compiled into a RES file and included into my DLL. Presumably this is because Visual Studio does not like the fact that the RC files all have the same name.
Is there any way to achieve what I want?
Thanks!
Yes. And No.
If you want multiple RC files you are going to have to leverage off the Operating systems support to have multiple resources in one file. In the resource editor, for each resource, you can set its locale AND the resource editor will allow you to have multiple resources with the same ID, as long as their locale is different.
So, your first step would be to edit each of the RC files to ensure that the resources in one are English/US, another contains French etc.
Next, get the main RC file to #include the others.
Lastly, and this is the problem, you need to rely on the Operating systems logic to load the correct resources. If you are happy to let the locale of the PC determine what UI language is used you have done enough.
If you want to provide a menu option allowing users to change languages: SetThreadLocale used to be an easy way to switch the Locale of loaded resources on the current thread. Since Windows 2000 some unfortunate overloaded usage of the API has caused MS to deprecate its usage in favor of requiring App Developers to always use FindResourceEx - which really doesn't help you if you want, for example, to load a string from a string table.
If you really want an easy way to have a user selectable UI language, then you need to place each of your .rc files into a seperate dll. and then LoadLibrary on the appropriate language resource dll.