Click here to Skip to main content
15,881,424 members
Articles / Programming Languages / C++
Article

Localizing print preview

Rate me:
Please Sign up or sign in to vote.
4.50/5 (12 votes)
4 Jul 20042 min read 63.6K   1.5K   19   6
Draw your print preview buttons in your customers' language

Introduction

If you ever tried to distribute an international (multilingual) application you know maybe the obstacles to translate all the texts.

Some dialog controls like those ones of the MessageBox can't be transformed into another language, they are part of the Windows installed on your machine. So the 'Cancel' button of a German Windows OS will always be "Abbrechen" or "Annuler" in a French Windows OS.

However, this is not the problem, but the entire rest of your application should be in your customers' language. Title bar, menus, tooltips, dialogs and its controls can get accessed and modified at runtime.

Print preview problem

But the print preview gave me headache, because normally you have to define at compilation time the printing resources you'd like to link.

e.g.

#include "l.deu\afxprint.rc" // German printing resources<br>
#include "l.fra\afxprint.rc" // French printing resources<br>
#include "l.ita\afxprint.rc" // Italian printing resources<br>

After linking one of the indicated examples, the preview buttons seem to be invariant. So, I consulted MSDN and figured out, they are accessible in a certain way.

Image 1

Solution

Derive from CPreviewView your own class, where you should have access to the desired buttons. Then make sure the framework calls your derived class.

void CLangPreviewView::OnActivateView(BOOL bActivate, CView*, CView*)
{
  if (bActivate)
  {
    if (m_pToolBar) {
      m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_PRINT)  
       ->SetWindowText(CDic::GetText(_T("Preview"),
        _T("PRINT"), _T("&Print...")));
      m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_NEXT)   
       ->SetWindowText(CDic::GetText(_T("Preview"), 
       _T("NEXT"), _T("&Next Page")));
      m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_PREV)   
       ->SetWindowText(CDic::GetText(_T("Preview"), 
       _T("PREV"), _T("Pre&v Page")));
      //m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_NUMPAGE)->
       SetWindowText(CDic::GetText(_T("Preview"), 
       _T("NUMPAGE"), _T("")));
      m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_ZOOMIN) 
       ->SetWindowText(CDic::GetText(_T("Preview"),
        _T("ZOOMIN"), _T("Zoom &In")));
      m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_ZOOMOUT)->
       SetWindowText(CDic::GetText(_T("Preview"), 
       _T("ZOOMOUT"), _T("Zoom &Out")));
      m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_CLOSE)  ->
       SetWindowText(CDic::GetText(_T("Preview"), 
       _T("CLOSE"), _T("&Close")));
    }
  }
}

void CLangPreviewView::OnUpdateNumPageChange(CCmdUI* pCmdUI)
{
  CPreviewView::OnUpdateNumPageChange(pCmdUI);

  UINT nPages = (m_nZoomState == ZOOM_OUT ? m_nPages : m_nZoomOutPages);
  if (nPages == 1)
    pCmdUI->SetText(CDic::GetText(_T("Preview"), 
     _T("TWOPAGE"), _T("&Two Page")));
  else
    pCmdUI->SetText(CDic::GetText(_T("Preview"), 
     _T("ONEPAGE"), _T("&One Page")));
}

Steps

  • Add "LangPreviewView.cpp/.h" to your application
  • Add "Dic.cpp/.h" to your application (a dictionary class, see below)
  • Call "CDic::LoadLanguage(LPCTSTR)" to load/reload application language specific texts (e.g. in CYourAppDocument::OnNewDocument)
  • CDic::LoadLanguage(_T("Lang_de.txt"));
      // loads German application strings
  • Override the OnFilePrintPreview function of your view class to call CPreviewView
    //ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)
    void CYourAppView::OnFilePrintPreview()
    {
      // In derived classes, implement special window handling here.
      // Be sure to Unhook Frame Window close if hooked.
      // Must not create this on the frame. Must outlive this function.
    
      CPrintPreviewState* pState = new CPrintPreviewState;
    
      // DoPrintPreview's return value does not necessarily indicate that
      // Print Preview succeeded or failed, but rather what actions are
      // necessary at this point. If DoPrintPreview returns TRUE, it means
      // that OnEndPrintPreview will be (or has already been) called and
      // the pState structure will be/has been deleted.
      // If DoPrintPreview returns FALSE, it means that OnEndPrintPreview
      // WILL NOT be called and that cleanup, including deleting pState,
      // must be done here.
    
      if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this,
         RUNTIME_CLASS(CYourAppView), pState))
      {
         // In derived classes, reverse special window handling here for
         // Preview failure case.
    
         TRACE0("Error: DoPrintPreview failed.\n");
         AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
         delete pState; // Preview failed to initialize, delete State now.
      }
    }
  • Modify the OnPreparePrinting function of your view class to enable localized (language depending) status bar page display
    BOOL CYourAppView::OnPreparePrinting(CPrintInfo* pInfo)
    {
      // Standardvorbereitung
      BOOL bReturn = DoPreparePrinting(pInfo);
    
      pInfo->m_strPageDesc = CDic::GetText(_T("Preview"), 
       _T("PAGEDESC"), _T("Page %u\nPages %u-%u\n"), true);
    
      return bReturn;
    }

(I prefer collecting localized texts in several external text files to having everything in internal stringtable resources. If there is a new language added to your application, you don't have to recompile the entire project or part of it, simply add the language file to your distribution.)

Now, we are ready to test the application.

Test

Select one of the five languages by clicking the flag of the toolbar and then start the print preview.

Image 2

Preview in German

Image 3

Preview in French

Image 4

Preview in Italian

Image 5

Preview in Spanish

Image 6

Point of interest

CDic

There is a handy class to retrieve localized texts from a file.

Its member functions are static, therefore they can be called from almost everywhere.

bool CDic::LoadLanguage(LPCTSTR strFilepath)
// Loads/reloads the desired language file<br>

CString CDic::GetText(LPCTSTR strSection, LPCTSTR strID, 
 LPCTSTR strDefaultText, bool bTransform)
//Retrieves a text entry (strID) from a section (strSection)
//if a text can't be found, the given default text 
//(strDefaultText) will be given back

History

  • 1.00 04-July-2004 Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralCorrection in the displayed code Pin
gautamdeshpande4-Dec-05 21:18
gautamdeshpande4-Dec-05 21:18 
GeneralRe: Correction in the displayed code Pin
Eric Trinh12-Jan-06 0:34
Eric Trinh12-Jan-06 0:34 
GeneralHelp Pin
sreejith ss nair18-Sep-05 21:28
sreejith ss nair18-Sep-05 21:28 
GeneralGood! Pin
WREY6-Jul-04 0:07
WREY6-Jul-04 0:07 
Question#undef??? Pin
Eric Trinh5-Jul-04 0:30
Eric Trinh5-Jul-04 0:30 
AnswerRe: #undef??? Pin
Eric Trinh5-Jul-04 0:31
Eric Trinh5-Jul-04 0:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.