From: mfc on
Hi,

I`ve a sdi application where I want to add multiple language support.
If the user press the button btn1, the language should be changed.

After the OnButtonClick-Function I`m using SendMessage to send a msg
to one function in the mainframe-class
(class CMainFrame : public CFrameWnd)

This is the function in the CMainFrame() - only a small demo:

HINSTANCE hInst = NULL;

if(!m_hInstGerman)
m_hInstGerman = LoadLibrary(_T("LangDeu.dll"));

hInst = m_hInstGerman;

if(hInst)
AfxSetResourceHandle(hInst);

//CTestDialog dlg(this);
//dlg.DoModal();
//dlg.ShowWindow(SW_SHOW);

Which commands will be missing here to start the new language-dialog?
At the moment - nothing happens; the code will be executed without any
errors and the dll is loaded.


Within the vs-project-map: I`ve one main-project (with doc/view sdi
app) with the resources (first shown dialog) and I`ve installed two
further projects which only includes the resource-files (one for
German and one for English). Both have the same resources (dialogs) as
the main-project.

main-project:
resource: IDD_MAIN_DIALOG


german-dll-project:
resourec: IDD_MAIN_DIALOG (with German strings - the same for the
English one)


Thanks for your hints!

best regards
Hans

From: Joseph M. Newcomer on
Why is there *any* button called "btn1". The FIRST thing you do when creating controls is
change all those stupid default IDs (e.g., IDC_BUTTON1) to something meaningful (e.g.
IDC_ASK_USER_FOR_NAME). Only then do you start to create variables (which will have
meaningful names, like c_AskUserForName) and handlers (e.g., OnBnClickedAsUserForName).

So already you are digging yourself into a pit of unmaintainability.
On Fri, 18 Jun 2010 10:30:36 -0700 (PDT), mfc <mfcprog(a)googlemail.com> wrote:

>Hi,
>
>I`ve a sdi application where I want to add multiple language support.
>If the user press the button btn1, the language should be changed.
>
>After the OnButtonClick-Function I`m using SendMessage to send a msg
>to one function in the mainframe-class
>(class CMainFrame : public CFrameWnd)
>
>This is the function in the CMainFrame() - only a small demo:
>
>HINSTANCE hInst = NULL;
>
>if(!m_hInstGerman)
> m_hInstGerman = LoadLibrary(_T("LangDeu.dll"));
****
There are so many things wrong with the above code I cannot hope to list all of them.

Why is there an m_hInstGerman? Do you plan to add a variable for each of the several
hundred languages supported? Will there be an hInstItalian_Italy, hinstItalian_Swiss, an
hInstSpanish_Mexican, an hInstFrench_Canadian? Of course not. One local instance
variable will suffice for all possible languages and that's all you should ever need. In
the worst case, using a simple std::map to map language abbreviations to DLL handles might
be used, if you want to support the user dynamically switching languages. Or, you can
compute the DLL name (GetModuleFileName) and only load the DLL if the name you get is
different from the one you have (don't forget to FreeLibrary the one you are about to
replace!)

Why are you not forming the name from the user's current selected active language? Why
did you hardwire it to "LangDeu.dll"?

Do you plan to add code like the above for each of the hundreds of languages supported by
Windows?

Play with my Locale Explorer (see my MVP Tips site). It will even generate the code for
you!

From the Locale Explorer:

// LOCALE_SABBREVLANGNAME
CString sabbrevlangname_data;
LCID lcid = LOCALE_SYSTEM_DEFAULT;
{ /* get LOCALE_SABBREVLANGNAME */
LPTSTR p = sabbrevlangname_data.GetBuffer(4);
VERIFY(::GetLocaleInfo(lcid, LOCALE_SABBREVLANGNAME, p, 4));
sabbrevlangname_data.ReleaseBuffer();
} /* get LOCALE_SABBREVLANGNAME */
// ... use sabbrevlangname_data here

****
>
>hInst = m_hInstGerman;
****
I have no idea why you need m_hInstGerman at all! It doesn't make any sense to have a
variable for every possible language, because you simply don't know at the time you
compile this how many languages are going to be supported by Windows!

Note that your plan to deliver, say, only a German and English DLL is irrelevant. If I
speak English and Esperanto, I can trivially create an Esperanto DLL. If Esperanto were a
language supported by MIcrosoft (who knows if they won't support it in the future?) then I
would want to use it. Since you don;t know what DLLs are going to be available, you are
making a serious error assuming that it is the "other one" of yours.
*****
>
>if(hInst)
> AfxSetResourceHandle(hInst);
*****
if(hInst != NULL)

It is a horrible artifact of poor C instruction that makes people think that testing a
non-boolean value like you did could possibly make sense. Bad C manuals encourage this.
****
>
>//CTestDialog dlg(this);
>//dlg.DoModal();
>//dlg.ShowWindow(SW_SHOW);
>
>Which commands will be missing here to start the new language-dialog?
****
The ones you commented out. Note that the ShowWindow is a complete nonsense line and
will, in fact, generate an assertion error at runtime because after the DoModal returns,
the dlg window DOES NOT EXIST so trying to show it at that point makes no sense!
****
>At the moment - nothing happens; the code will be executed without any
>errors and the dll is loaded.
****
Well, since you commented out the DoModal, do not expect much to happen!
****
>
>
>Within the vs-project-map: I`ve one main-project (with doc/view sdi
>app) with the resources (first shown dialog) and I`ve installed two
>further projects which only includes the resource-files (one for
>German and one for English). Both have the same resources (dialogs) as
>the main-project.
****
The fact that resources of the same ID exist in the main project is kind of scary. I
would never do that.
****
>
>main-project:
>resource: IDD_MAIN_DIALOG
>
>
>german-dll-project:
>resourec: IDD_MAIN_DIALOG (with German strings - the same for the
>English one)
>
>
>Thanks for your hints!
>
>best regards
>Hans
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: mfc on
On 18 Jun., 20:41, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
> Why is there *any* button called "btn1".  The FIRST thing you do when creating controls is
> change all those stupid default IDs (e.g., IDC_BUTTON1) to something meaningful (e.g.
> IDC_ASK_USER_FOR_NAME).  Only then do you start to create variables (which will have
> meaningful names, like c_AskUserForName) and handlers (e.g., OnBnClickedAsUserForName).
>
> So already you are digging yourself into a pit of unmaintainability.
>
>
>
>
>
> On Fri, 18 Jun 2010 10:30:36 -0700 (PDT), mfc <mfcp...(a)googlemail.com> wrote:
> >Hi,
>
> >I`ve a sdi application where I want to add multiple language support.
> >If the user press the button btn1, the language should be changed.
>
> >After the OnButtonClick-Function I`m using SendMessage to send a msg
> >to one function in the mainframe-class
> >(class CMainFrame : public CFrameWnd)
>
> >This is the function in the CMainFrame() - only a small demo:
>
> >HINSTANCE hInst = NULL;
>
> >if(!m_hInstGerman)
> >    m_hInstGerman = LoadLibrary(_T("LangDeu.dll"));
>
> ****
> There are so many things wrong with the above code I cannot hope to list all of them.
>
> Why is there an m_hInstGerman?  Do you plan to add a variable for each of the several
> hundred languages supported?  Will there be an hInstItalian_Italy, hinstItalian_Swiss, an
> hInstSpanish_Mexican, an hInstFrench_Canadian?  Of course not.  One local instance
> variable will suffice for all possible languages and that's all you should ever need.  In
> the worst case, using a simple std::map to map language abbreviations to DLL handles might
> be used, if you want to support the user dynamically switching languages.  Or, you can
> compute the DLL name (GetModuleFileName) and only load the DLL if the name you get is
> different from the one you have (don't forget to FreeLibrary the one you are about to
> replace!)
>
> Why are you not forming the name from the user's current selected active language?  Why
> did you hardwire it to "LangDeu.dll"?
>
> Do you plan to add code like the above for each of the hundreds of languages supported by
> Windows?
>
> Play with my Locale Explorer (see my MVP Tips site). It will even generate the code for
> you!
>
> From the Locale Explorer:
>
> // LOCALE_SABBREVLANGNAME
> CString sabbrevlangname_data;
> LCID lcid = LOCALE_SYSTEM_DEFAULT;
> { /* get LOCALE_SABBREVLANGNAME */
>  LPTSTR p = sabbrevlangname_data.GetBuffer(4);
>  VERIFY(::GetLocaleInfo(lcid, LOCALE_SABBREVLANGNAME, p, 4));
>  sabbrevlangname_data.ReleaseBuffer();} /* get LOCALE_SABBREVLANGNAME */
>
> // ... use sabbrevlangname_data here

thanks for all these information. Do you know which steps I`ve to do
to start a new dll (during running the programm)? Or is it only
possible to restart the programm to start a new dll???

All the steps which are necessary after loading the new dll file with
LoadLibrary()...






From: mfc on
On 18 Jun., 21:55, mfc <mfcp...(a)googlemail.com> wrote:
> On 18 Jun., 20:41, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
>
>
>
>
>
> > Why is there *any* button called "btn1".  The FIRST thing you do when creating controls is
> > change all those stupid default IDs (e.g., IDC_BUTTON1) to something meaningful (e.g.
> > IDC_ASK_USER_FOR_NAME).  Only then do you start to create variables (which will have
> > meaningful names, like c_AskUserForName) and handlers (e.g., OnBnClickedAsUserForName).
>
> > So already you are digging yourself into a pit of unmaintainability.
>
> > On Fri, 18 Jun 2010 10:30:36 -0700 (PDT), mfc <mfcp...(a)googlemail.com> wrote:
> > >Hi,
>
> > >I`ve a sdi application where I want to add multiple language support.
> > >If the user press the button btn1, the language should be changed.
>
> > >After the OnButtonClick-Function I`m using SendMessage to send a msg
> > >to one function in the mainframe-class
> > >(class CMainFrame : public CFrameWnd)
>
> > >This is the function in the CMainFrame() - only a small demo:
>
> > >HINSTANCE hInst = NULL;
>
> > >if(!m_hInstGerman)
> > >    m_hInstGerman = LoadLibrary(_T("LangDeu.dll"));
>
> > ****
> > There are so many things wrong with the above code I cannot hope to list all of them.
>
> > Why is there an m_hInstGerman?  Do you plan to add a variable for each of the several
> > hundred languages supported?  Will there be an hInstItalian_Italy, hinstItalian_Swiss, an
> > hInstSpanish_Mexican, an hInstFrench_Canadian?  Of course not.  One local instance
> > variable will suffice for all possible languages and that's all you should ever need.  In
> > the worst case, using a simple std::map to map language abbreviations to DLL handles might
> > be used, if you want to support the user dynamically switching languages.  Or, you can
> > compute the DLL name (GetModuleFileName) and only load the DLL if the name you get is
> > different from the one you have (don't forget to FreeLibrary the one you are about to
> > replace!)
>
> > Why are you not forming the name from the user's current selected active language?  Why
> > did you hardwire it to "LangDeu.dll"?
>
> > Do you plan to add code like the above for each of the hundreds of languages supported by
> > Windows?
>
> > Play with my Locale Explorer (see my MVP Tips site). It will even generate the code for
> > you!
>
> > From the Locale Explorer:
>
> > // LOCALE_SABBREVLANGNAME
> > CString sabbrevlangname_data;
> > LCID lcid = LOCALE_SYSTEM_DEFAULT;
> > { /* get LOCALE_SABBREVLANGNAME */
> >  LPTSTR p = sabbrevlangname_data.GetBuffer(4);
> >  VERIFY(::GetLocaleInfo(lcid, LOCALE_SABBREVLANGNAME, p, 4));
> >  sabbrevlangname_data.ReleaseBuffer();} /* get LOCALE_SABBREVLANGNAME */
>
> > // ... use sabbrevlangname_data here
>
> thanks for all these information. Do you know which steps I`ve to do
> to start a new dll (during running the programm)? Or is it only
> possible to restart the programm to start a new dll???
>
> All the steps which are necessary after loading the new dll file with
> LoadLibrary()...- Zitierten Text ausblenden -
>
> - Zitierten Text anzeigen -

I`ve found a good working example besides the effect that the language
didn`t change the dll on-the-fly
http://read.pudn.com/downloads83/sourcecode/chinese/319271/LanguageSupport.cpp__.htm


void CLanguageSupport::OnSwitchLanguage(UINT nId, bool
bLoadNewLanguageImmediately)
with bLoadNewLanguageImmediately = TRUE;

Everything seems to be ok, but it doesn`t work... maybe you know where
the problem would be?

best regards
Hans


From: Joseph M. Newcomer on
See below...
On Fri, 18 Jun 2010 12:55:24 -0700 (PDT), mfc <mfcprog(a)googlemail.com> wrote:

>On 18 Jun., 20:41, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
>> Why is there *any* button called "btn1". �The FIRST thing you do when creating controls is
>> change all those stupid default IDs (e.g., IDC_BUTTON1) to something meaningful (e.g.
>> IDC_ASK_USER_FOR_NAME). �Only then do you start to create variables (which will have
>> meaningful names, like c_AskUserForName) and handlers (e.g., OnBnClickedAsUserForName).
>>
>> So already you are digging yourself into a pit of unmaintainability.
>>
>>
>>
>>
>>
>> On Fri, 18 Jun 2010 10:30:36 -0700 (PDT), mfc <mfcp...(a)googlemail.com> wrote:
>> >Hi,
>>
>> >I`ve a sdi application where I want to add multiple language support.
>> >If the user press the button btn1, the language should be changed.
>>
>> >After the OnButtonClick-Function I`m using SendMessage to send a msg
>> >to one function in the mainframe-class
>> >(class CMainFrame : public CFrameWnd)
>>
>> >This is the function in the CMainFrame() - only a small demo:
>>
>> >HINSTANCE hInst = NULL;
>>
>> >if(!m_hInstGerman)
>> > � �m_hInstGerman = LoadLibrary(_T("LangDeu.dll"));
>>
>> ****
>> There are so many things wrong with the above code I cannot hope to list all of them.
>>
>> Why is there an m_hInstGerman? �Do you plan to add a variable for each of the several
>> hundred languages supported? �Will there be an hInstItalian_Italy, hinstItalian_Swiss, an
>> hInstSpanish_Mexican, an hInstFrench_Canadian? �Of course not. �One local instance
>> variable will suffice for all possible languages and that's all you should ever need. �In
>> the worst case, using a simple std::map to map language abbreviations to DLL handles might
>> be used, if you want to support the user dynamically switching languages. �Or, you can
>> compute the DLL name (GetModuleFileName) and only load the DLL if the name you get is
>> different from the one you have (don't forget to FreeLibrary the one you are about to
>> replace!)
>>
>> Why are you not forming the name from the user's current selected active language? �Why
>> did you hardwire it to "LangDeu.dll"?
>>
>> Do you plan to add code like the above for each of the hundreds of languages supported by
>> Windows?
>>
>> Play with my Locale Explorer (see my MVP Tips site). It will even generate the code for
>> you!
>>
>> From the Locale Explorer:
>>
>> // LOCALE_SABBREVLANGNAME
>> CString sabbrevlangname_data;
>> LCID lcid = LOCALE_SYSTEM_DEFAULT;
>> { /* get LOCALE_SABBREVLANGNAME */
>> �LPTSTR p = sabbrevlangname_data.GetBuffer(4);
>> �VERIFY(::GetLocaleInfo(lcid, LOCALE_SABBREVLANGNAME, p, 4));
>> �sabbrevlangname_data.ReleaseBuffer();} /* get LOCALE_SABBREVLANGNAME */
>>
>> // ... use sabbrevlangname_data here
>
>thanks for all these information. Do you know which steps I`ve to do
>to start a new dll (during running the programm)? Or is it only
>possible to restart the programm to start a new dll???
>
>All the steps which are necessary after loading the new dll file with
>LoadLibrary()..
****
LoadLibrary is all you need to do to load the DLL. The AfxSetResourceHandle makes the DLL
be the default source for the resources. Note that the DLL has to contain *all* the
resources you need, not just some, and for safety, the executable should have none of
these resources. It should only have enough resources to get the system up prior to
InitInstance, which means, essentially, no resources at all, and a few to report that the
DLL is missing.

Use the above code to get the 3-letter locale ID (I found that there are five German
languages supported: Austria, Germany, Switzerland, Leichtenstein and Luxembourg, so
supporting DEU supports only one of them. And to get the LCID, you would use
LOCALE_USER_DEFAULT as the constant instead of the MAKELCID macro.
joe
****
>
>
>
>
>
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
 |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9
Prev: I love MFC!
Next: Using CMFCToolBar and CMFCMenuBar?