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
}