Knowledge Base Nr: 00297 multilang.cpp - http://www.swe-kaiser.de
Downloads:
MFC: VS2005 Mehrsprachigkeit (Dialoge und Menüs dynamisch übersetzen)
///////// sprache über menu/toolbarbuttons o.ä. umschalten
void CtestApp::OnSpracheDeutsch()
{
g_isEnglish = false;
CMenu* menu = GetMainWnd()->GetMenu();
TranslateMenu(menu);
}
void CtestApp::OnSpracheEnglish()
{
g_isEnglish = true;
CMenu* menu = GetMainWnd()->GetMenu();
TranslateMenu(menu);
}
///////// applikationsmenu übersetzen
BOOL CtestApp::InitInstance()
{
...
CMenu* menu = GetMainWnd()->GetMenu();
TranslateMenu(menu);
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();
return TRUE;
}
///////// für neue dokumente menu übersetzen
BOOL CtestApp::OpenNewDocument(const char* lpszTarget)
{
...
while (pos != NULL)
{
...
if (strDocName == lpszTarget)
{
pSelectedTemplate->OpenDocumentFile(NULL);
CMenu* menu = GetMainWnd()->GetMenu();
TranslateMenu(menu);
return TRUE;
}
}
...
}
///////// übersetzung dialoge - aufruf TranslateDialog() in OnInitDialog()
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CtestApp* pApp = (CtestApp*)AfxGetApp();
pApp->TranslateDialog(this);
return TRUE; // return TRUE unless you set the focus to a control
}
///////// übersetzung propertysheets - zusätzlich einzelne tabs übersetzen
BOOL NewPropSheet::OnInitDialog()
{
BOOL bResult = CPropertySheet::OnInitDialog();
theApp.TranslateDialog(this);
CTabCtrl* tab = GetTabControl();
int c = tab->GetItemCount();
for (int n=0; n<c; n++)
{
TCHAR text[50] = {0};
TCITEM item;
item.mask = TCIF_TEXT;
item.pszText = text;
item.cchTextMax = sizeof(text);
tab->GetItem(n, &item);
CString title(text);
title = theApp.Translate(title);
if (title != "")
{
item.mask = TCIF_TEXT;
item.pszText = title.GetBuffer();
item.cchTextMax = title.GetLength();
tab->SetItem(n, &item);
title.ReleaseBuffer();
}
}
return bResult;
}
///////// übersetzung statusbartexte über timer
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
...
SetTimer(0, 200, NULL);
return 0;
}
void CMainFrame::OnTimer(UINT_PTR nIDEvent)
{
static bool locked = false;
if (!locked)
{
locked = true;
static CString oldStatText("");
CString statText;
m_wndStatusBar.GetPaneText(0, statText);
if (statText != oldStatText)
{
CtestApp* pApp = (CtestApp*)AfxGetApp();
statText = pApp->Translate(statText);
m_wndStatusBar.SetPaneText(0, statText, true);
}
locked = false;
}
CMDIFrameWnd::OnTimer(nIDEvent);
}
///////// schnittstelle
public:
void TranslateMenu(CMenu* menu, bool bActivate = true);
void TranslateDialog(CDialog* dlg, bool bTranslateEditTexts = false);
protected:
static BOOL CALLBACK DoEnumChildProc(HWND hwnd, LPARAM lParam);
CString Translate(CString txt);
void TranslateMenuItem(CMenu* menu, int i);
///////// implementation generische funktionen
bool g_isEnglish = false;
BOOL CALLBACK CtestApp::DoEnumChildProc(HWND hwnd, LPARAM lParam)
{
bool bTranslateEditTexts = lParam ? true : false;
TCHAR szClass[500] = {0};
TCHAR szText[500] = {0};
::GetClassName(hwnd, szClass, sizeof(szClass));
::GetWindowText(hwnd, szText, sizeof(szText));
if (!bTranslateEditTexts && (wcscmp(szClass, L"Edit")==0))
return TRUE;
if ((wcscmp(szText, L"")==0))
return TRUE;
CtestApp* pApp = (CtestApp*)AfxGetApp();
CString txt = pApp->Translate(CString(szText));
if (txt != "")
::SetWindowText(hwnd, txt);
return TRUE;
}
void CtestApp::TranslateDialog(CDialog* dlg, bool bTranslateEditTexts)
{
CString title;
CtestApp* pApp = (CtestApp*)AfxGetApp();
dlg->GetWindowText(title);
title = pApp->Translate(title);
if (title != "")
dlg->SetWindowText(title);
BOOL bSucc = EnumChildWindows(dlg->GetSafeHwnd(), DoEnumChildProc, (LPARAM)bTranslateEditTexts);
}
CString CtestApp::Translate(CString txt)
{
if (txt != "")
{
//nur ein beispiel - besser texte aus datenbank holen
if ((txt.Left(2) == "E ") || (txt.Left(2) == "D "))
txt.SetAt(0, (g_isEnglish ? 'E' : 'D'));
else
txt = CString(g_isEnglish ? "E " : "D ") + txt;
}
return txt;
}
void CtestApp::TranslateMenuItem(CMenu* menu, int i)
{
TCHAR mt[100];
menu->GetMenuString(i, mt, sizeof(mt), MF_BYPOSITION);
CString txt = mt;
if (txt != "")
{
txt = Translate(txt);
menu->ModifyMenu(i, MF_BYPOSITION, menu->GetMenuItemID(i), txt);
}
}
void CtestApp::TranslateMenu(CMenu* menu, bool bActivate)
{
int Anzahl = menu->GetMenuItemCount();
for (int pos = 0; pos < Anzahl; pos++)
{
int state = menu->GetMenuState(pos, MF_BYPOSITION);
if (!(state & MF_SEPARATOR) || pos == 0 || (state > 128))
{
TranslateMenuItem(menu, pos);
CMenu* popup = menu->GetSubMenu(pos);
if (popup)
{
TranslateMenu(popup, false);
}
}
}
if (bActivate)
{
((CMDIFrameWnd*)AfxGetMainWnd())->DrawMenuBar();
}
}
///////// übersetzung toolbar tooltips über TTN_NEEDTEXTx
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
...
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnDynamicTipText)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnDynamicTipText)
END_MESSAGE_MAP()
BOOL CMainFrame::OnDynamicTipText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
// OnNeedText should only be called for TTN_NEEDTEXT notifications!
ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
// need to handle both ANSI and UNICODE versions of the message
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
TCHAR szFullText[256];
CString strTipText; // used to hold final tool tip text before UNICODE conversion
UINT nID = pNMHDR->idFrom;
if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
{
// idFrom is actually the HWND of the tool
nID = ((UINT)(WORD)::GetDlgCtrlID((HWND)nID));
}
//tooltiptext laden und übersetzen (tooltiptext kommt nach '\n')
strTipText.LoadString(nID);
int p = strTipText.Find(CString("\n"));
if (p>0)
strTipText = strTipText.Mid(p+1);
CtestApp* pApp = (CtestApp*)AfxGetApp();
strTipText = pApp->Translate(strTipText);
if (pNMHDR->code == TTN_NEEDTEXTA)
_wcstombsz(pTTTA->szText, strTipText, _countof(pTTTA->szText));
else
lstrcpyn(pTTTW->szText, strTipText, _countof(pTTTW->szText));
*pResult = 0;
// bring the tooltip window above other popup windows
::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0
, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE);
return TRUE; // message was handled
}