1
votes

I am developing a custom print dialog and page setup using MFC and VS2008 for my Win32 program. Since the code is legacy, I can't take much advantage from MFC view/doc architecture. As a result, I wrote a printing code completely from scratch.

I setup CPrintInfo, instantiate my custom print dialog box and hook this dialog box to the CPrintInfo I just created. When my custom print dialog is up, I have a radio button to let a user toggles the page orientation. For some reasons, I couldn't modify the current DEVMODE at the run-time. As a result, every page I print will end up as a portrait.

Even if I manually set pDevMode->dmOrientation to DMORIENT_LANDSCAPE from the event handler of the custom print dialog, the printing result is still ended up as portrait. I am really not sure why this is happening and how to modify the DevMode after the print dialog is up.

Thank you in advance for any help.

Here is the code I have:

void PrintSomething(CWnd* currentWnd) {
  // Create CPrintInfo
  CPrintInfo* pPrintInfo = new CPrintInfo;
  SetupPrintInfo(pPrintInfo); // simply setup some member variables of CPrintInfo

  // Create a custom print dialog 
  CustomPrintDlg* pCustomPrtDlg = new CustomPrintDlg(FALSE, PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS
           | PD_HIDEPRINTTOFILE | PD_NOSELECTION, pPrintInfo, currentWnd);
  SetupPrintDialog(pPrintInfo,pCustomPrtDlg);

  if ( AfxGetApp()->DoPrintDialog(pCustomPrtDlg) == IDOK ) {
        ... // proceed a print loop 
  }
}

Code for setting up the custom print dialog:

void SetupPrintDialog(CPrintInfo* pPrintInfo,CustomPrintDlg* pCustomPrtDlg) {
  delete pInfo->m_pPD;
  pInfo->m_pPD = pCustomPrtDlg;

  pInfo->m_pPD->m_pd.hInstance = AfxGetInstanceHandle();
  pInfo->m_pPD->m_pd.lpPrintTemplateName = MAKEINTRESOURCE(IDD_CUSTOM_PRTDLG);

  // Set the Flags of the PRINTDLG structure as shown, else the
  // changes will have no effect.
  pInfo>m_pPD->m_pd.Flags |= PD_ENABLEPRINTTEMPLATE;

  // Set the page range.
  pInfo>m_pPD->m_pd.nMinPage = 1;         // one based page numbers.
  pInfo>m_pPD->m_pd.nMaxPage = 0xffff; // how many pages is unknown. 
}

When a user toggles the radio button to Landscape, this function will be invoked:

void CustomPrintDlg::OnLandscapeChecked() {
  // set the current Devmode to landscape
  LPDEVMODE pDevMode = GetDevMode();
  GlobalUnlock(pDevMode);
  pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
}

A pseucode for the custom print dialog class:

class CustomPrintDlg: public CPrintDialog {

  ...   // just override some methods from CPrintDialog
};

Thanks again, Unagi

2

2 Answers

2
votes

I figured out the solution:

All I need is to call GlobalLock to obtain a pointer to the Devmode before changing the current DevMode.

void CustomPrintDlg::OnLandscapeChecked()
{
      // set the current Devmode to landscape
      LPDEVMODE pDevMode = GetDevMode();
      GlobalLock(pDevMode);
      pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
      GlobalUnlock(pDevMode)
}

Thanks again for helping me.

0
votes

Nowhere in your example code do you show how you're creating the DC for printing. When you call CreateDC, you must pass a pointer to a DEVMODE structure; this defines whether the printing will be portrait or landscape.