PRPackedBool doExtend = PR_FALSE; nsCOMPtr<nsIStringBundle> strBundle; if (NS_SUCCEEDED(GetLocalizedBundle(PRINTDLG_PROPERTIES, getter_AddRefs(strBundle)))) { nsAutoString doExtendStr; if (NS_SUCCEEDED(GetLocalizedString(strBundle, "extend", doExtendStr))) { doExtend = doExtendStr.EqualsLiteral("true"); } }
ShowNativePrintDialog(HWND              aHWnd,                      nsIPrintSettings* aPrintSettings){  //NS_ENSURE_ARG_POINTER(aHWnd);  NS_ENSURE_ARG_POINTER(aPrintSettings);  nsresult  rv = NS_ERROR_FAILURE;  gDialogWasExtended  = PR_FALSE;  HGLOBAL hGlobalDevMode = NULL;  HGLOBAL hDevNames      = NULL;  // Get the Print Name to be used  PRUnichar * printerName;  aPrintSettings->GetPrinterName(&printerName);  // If there is no name then use the default printer  if (!printerName || (printerName && !*printerName)) {    printerName = GetDefaultPrinterNameFromGlobalPrinters();  }  NS_ASSERTION(printerName, "We have to have a printer name");  if (!printerName) return NS_ERROR_FAILURE;  // Now create a DEVNAMES struct so the the dialog is initialized correctly.  PRUint32 len = nsCRT::strlen(printerName);  hDevNames = (HGLOBAL)::GlobalAlloc(GHND, len+sizeof(DEVNAMES)+1);  DEVNAMES* pDevNames = (DEVNAMES*)::GlobalLock(hDevNames);  pDevNames->wDriverOffset = sizeof(DEVNAMES);  pDevNames->wDeviceOffset = sizeof(DEVNAMES);  pDevNames->wOutputOffset = sizeof(DEVNAMES)+len+1;  pDevNames->wDefault      = 0;  char* device = &(((char*)pDevNames)[pDevNames->wDeviceOffset]);  strcpy(device, NS_ConvertUCS2toUTF8(printerName).get());  ::GlobalUnlock(hDevNames);  // Create a Moveable Memory Object that holds a new DevMode  // from the Printer Name  // The PRINTDLG.hDevMode requires that it be a moveable memory object  // NOTE: We only need to free hGlobalDevMode when the dialog is cancelled  // When the user prints, it comes back in the printdlg struct and   // is used and cleaned up later#ifdef UNICODE  hGlobalDevMode = CreateGlobalDevModeAndInit(printerName, aPrintSettings);#else   hGlobalDevMode = CreateGlobalDevModeAndInit(NS_CONST_CAST(char*, NS_ConvertUCS2toUTF8(printerName).get()), aPrintSettings);#endif  // Prepare to Display the Print Dialog  PRINTDLG  prntdlg;  memset(&prntdlg, 0, sizeof(PRINTDLG));  prntdlg.lStructSize = sizeof(prntdlg);  prntdlg.hwndOwner   = aHWnd;  prntdlg.hDevMode    = hGlobalDevMode;  prntdlg.hDevNames   = hDevNames;  prntdlg.hDC         = NULL;  prntdlg.Flags       = PD_ALLPAGES | PD_RETURNIC | PD_HIDEPRINTTOFILE | PD_USEDEVMODECOPIESANDCOLLATE;  // if there is a current selection then enable the "Selection" radio button  PRInt16 howToEnableFrameUI = nsIPrintSettings::kFrameEnableNone;  PRBool isOn;  aPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn);  if (!isOn) {    prntdlg.Flags |= PD_NOSELECTION;  }  aPrintSettings->GetHowToEnableFrameUI(&howToEnableFrameUI);  // Determine whether we have a completely native dialog  // or whether we cshould extend it  // true  - do only the native  // false - extend the dialog  PRPackedBool doExtend = PR_FALSE;  nsCOMPtr<nsIStringBundle> strBundle;  if (NS_SUCCEEDED(GetLocalizedBundle(PRINTDLG_PROPERTIES, getter_AddRefs(strBundle)))) {    nsAutoString doExtendStr;    if (NS_SUCCEEDED(GetLocalizedString(strBundle, "extend", doExtendStr))) {      doExtend = doExtendStr.EqualsLiteral("true");    }  }  prntdlg.nFromPage           = 0xFFFF;  prntdlg.nToPage             = 0xFFFF;  prntdlg.nMinPage            = 1;  prntdlg.nMaxPage            = 0xFFFF;  prntdlg.nCopies             = 1;  prntdlg.lpfnSetupHook       = NULL;  prntdlg.lpSetupTemplateName = NULL;  prntdlg.hPrintTemplate      = NULL;  prntdlg.hSetupTemplate      = NULL;  prntdlg.hInstance           = NULL;  prntdlg.lpPrintTemplateName = NULL;  if (!doExtend) {    prntdlg.lCustData         = NULL;    prntdlg.lpfnPrintHook     = NULL;  } else {    // Set up print dialog "hook" procedure for extending the dialog    prntdlg.lCustData         = (DWORD)howToEnableFrameUI;    prntdlg.lpfnPrintHook     = (LPPRINTHOOKPROC)PrintHookProc;    prntdlg.Flags            |= PD_ENABLEPRINTHOOK;  }  BOOL result = ::PrintDlg(&prntdlg);  if (TRUE == result) {    if (aPrintSettings && prntdlg.hDevMode != NULL) {      // Transfer the settings from the native data to the PrintSettings      LPDEVMODE devMode = (LPDEVMODE)::GlobalLock(prntdlg.hDevMode);      SetPrintSettingsFromDevMode(aPrintSettings, devMode);      ::GlobalUnlock(prntdlg.hDevMode);    }    DEVNAMES *devnames = (DEVNAMES *)::GlobalLock(prntdlg.hDevNames);    if ( NULL != devnames ) {      char* device = &(((char *)devnames)[devnames->wDeviceOffset]);      char* driver = &(((char *)devnames)[devnames->wDriverOffset]);      nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(aPrintSettings));      // Setup local Data members      psWin->SetDeviceName(device);      psWin->SetDriverName(driver);#if defined(DEBUG_rods) || defined(DEBUG_dcone)      printf("printer: driver %s, device %s  flags: %d\n", driver, device, prntdlg.Flags);#endif      // fill the print options with the info from the dialog      if (aPrintSettings != nsnull) {        nsString printerName;        printerName.AssignWithConversion(device);        aPrintSettings->SetPrinterName(printerName.get());        if (prntdlg.Flags & PD_SELECTION) {          aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSelection);        } else if (prntdlg.Flags & PD_PAGENUMS) {          aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSpecifiedPageRange);          aPrintSettings->SetStartPageRange(prntdlg.nFromPage);          aPrintSettings->SetEndPageRange(prntdlg.nToPage);        } else { // (prntdlg.Flags & PD_ALLPAGES)          aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages);        }        if (howToEnableFrameUI != nsIPrintSettings::kFrameEnableNone) {          // make sure the dialog got extended          if (gDialogWasExtended) {            // check to see about the frame radio buttons            switch (gFrameSelectedRadioBtn) {              case rad4:                 aPrintSettings->SetPrintFrameType(nsIPrintSettings::kFramesAsIs);                break;              case rad5:                 aPrintSettings->SetPrintFrameType(nsIPrintSettings::kSelectedFrame);                break;              case rad6:                 aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep);                break;            } // switch          } else {            // if it didn't get extended then have it default to printing            // each frame separately            aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep);          }        } else {          aPrintSettings->SetPrintFrameType(nsIPrintSettings::kNoFrames);        }      }      ::GlobalUnlock(prntdlg.hDevNames);#if defined(DEBUG_rods) || defined(DEBUG_dcone)    PRBool  printSelection = prntdlg.Flags & PD_SELECTION;    PRBool  printAllPages  = prntdlg.Flags & PD_ALLPAGES;    PRBool  printNumPages  = prntdlg.Flags & PD_PAGENUMS;    PRInt32 fromPageNum    = 0;    PRInt32 toPageNum      = 0;    if (printNumPages) {      fromPageNum = prntdlg.nFromPage;      toPageNum   = prntdlg.nToPage;    }     if (printSelection) {      printf("Printing the selection\n");    } else if (printAllPages) {      printf("Printing all the pages\n");    } else {      printf("Printing from page no. %d to %d\n", fromPageNum, toPageNum);    }#endif          LPDEVMODE devMode = (LPDEVMODE)::GlobalLock(prntdlg.hDevMode);      psWin->SetDevMode(devMode);      SetPrintSettingsFromDevMode(aPrintSettings, devMode);      ::GlobalUnlock(prntdlg.hDevMode);    }  } else {    aPrintSettings->SetIsCancelled(PR_TRUE);    ::GlobalFree(hGlobalDevMode);    return NS_ERROR_ABORT;  }  return NS_OK;}