nsString printerName; printerName.AssignWithConversion(device);
nsDependentCString printerNameNative(device); nsAutoString printerName; NS_CopyNativeToUnicode(printerNameNative, printerName);
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.  nsCAutoString tempPrinterName;  rv = NS_CopyUnicodeToNative(nsDependentString(printerName), tempPrinterName);  NS_ENSURE_SUCCESS(rv, rv);  PRUint32 len = tempPrinterName.Length();  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, tempPrinterName.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  hGlobalDevMode = CreateGlobalDevModeAndInit(tempPrinterName.get(), aPrintSettings);  // 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_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");    }  }  PRInt32 pg = 1;  aPrintSettings->GetStartPageRange(&pg);  prntdlg.nFromPage           = pg;    aPrintSettings->GetEndPageRange(&pg);  prntdlg.nToPage             = pg;  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) {    // check to make sure we don't have any NULL pointers    NS_ENSURE_TRUE(aPrintSettings && prntdlg.hDevMode, NS_ERROR_FAILURE);    if (prntdlg.hDevNames == NULL) {      ::GlobalFree(hGlobalDevMode);      return NS_ERROR_FAILURE;    }    // Lock the deviceNames and check for NULL    DEVNAMES *devnames = (DEVNAMES *)::GlobalLock(prntdlg.hDevNames);    if (devnames == NULL) {      ::GlobalFree(hGlobalDevMode);      return NS_ERROR_FAILURE;    }    char* device = &(((char *)devnames)[devnames->wDeviceOffset]);    char* driver = &(((char *)devnames)[devnames->wDriverOffset]);    // Check to see if the "Print To File" control is checked    // then take the name from devNames and set it in the PrintSettings    //    // NOTE:    // As per Microsoft SDK documentation the returned value offset from    // devnames->wOutputOffset is either "FILE:" or NULL    // if the "Print To File" checkbox is checked it MUST be "FILE:"    // We assert as an extra safety check.    if (prntdlg.Flags & PD_PRINTTOFILE) {      char* fileName = &(((char *)devnames)[devnames->wOutputOffset]);      NS_ASSERTION(strcmp(fileName, "FILE:") == 0, "FileName must be `FILE:`");      aPrintSettings->SetToFileName(NS_ConvertASCIItoUCS2(fileName).get());      aPrintSettings->SetPrintToFile(PR_TRUE);    } else {      // clear "print to file" info      aPrintSettings->SetPrintToFile(PR_FALSE);      aPrintSettings->SetToFileName(nsnull);    }    nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(aPrintSettings));    if (!psWin) {      ::GlobalFree(hGlobalDevMode);      return NS_ERROR_FAILURE;    }    // 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    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);    }    // Unlock DeviceNames    ::GlobalUnlock(prntdlg.hDevNames);    // Transfer the settings from the native data to the PrintSettings    LPDEVMODE devMode = (LPDEVMODE)::GlobalLock(prntdlg.hDevMode);    if (devMode == NULL) {      ::GlobalFree(hGlobalDevMode);      return NS_ERROR_FAILURE;    }    psWin->SetDevMode(devMode); // copies DevMode    SetPrintSettingsFromDevMode(aPrintSettings, devMode);    ::GlobalUnlock(prntdlg.hDevMode);#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      } else {    aPrintSettings->SetIsCancelled(PR_TRUE);    if (hGlobalDevMode) ::GlobalFree(hGlobalDevMode);    return NS_ERROR_ABORT;  }  return NS_OK;}