gfx/src/windows/nsDeviceContextSpecWin.cpp - Revision 3.5

There were 19 changes made.
Legend
   Added lines
   Changed lines
   Removed lines

gfx/src/windows/nsDeviceContextSpecWin.cpp,3.5
.
Disk File
Skipping to line 37. 
 * ***** END LICENSE BLOCK ***** */
.
 * ***** END LICENSE BLOCK ***** */
 
.
 
#include "nsDeviceContextSpecWin.h"
.
#include "nsDeviceContextSpecWin.h"
#include "prmem.h"
.
#include "prmem.h"
#include "plstr.h"
.
#include "plstr.h"
 
.
#include <windows.h>
 
.
#include <commdlg.h>
 
.
 
 
.
#include "nsIDOMWindow.h"
 
.
#include "nsIServiceManager.h"
 
.
#include "nsIDialogParamBlock.h"
 
.
#include "nsISupportsPrimitives.h"
 
.
#include "nsIWindowWatcher.h"
 
.
#include "nsIDOMWindowInternal.h"
 
.
#include "nsVoidArray.h"
 
.
#include "nsSupportsArray.h"
 
.
 
 
.
#include "nsString.h"
 
.
#include "nsIServiceManager.h"
 
.
#include "nsReadableUtils.h"
 
.
#include "nsGfxCIID.h"
 
.
static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID);
 
.
#include "nsIPromptService.h"
 
.
 
 
.
#include "nsIPref.h"
 
.
#include "prenv.h" /* for PR_GetEnv */
 
.
 
 
.
#include <windows.h>
 
.
#include <winspool.h> 
 
.
 
 
.
// For Localization
 
.
#include "nsIStringBundle.h"
 
.
#include "nsDeviceContext.h"
 
.
#include "nsDeviceContextWin.h"
 
.
 
 
.
// This is for extending the dialog
 
.
#include <dlgs.h>
 
.
 
 
.
static NS_DEFINE_CID(kStringBundleServiceCID,  NS_STRINGBUNDLESERVICE_CID);
 
.
 
 
.
//-----------------------------------------------
 
.
// Global Data
 
.
//-----------------------------------------------
 
.
// Identifies which new radio btn was cliked on
 
.
static UINT         gFrameSelectedRadioBtn = NULL;
 
.
 
 
.
// Indicates whether the native print dialog was successfully extended
 
.
static PRPackedBool gDialogWasExtended     = PR_FALSE;
 
.
 
 
 
.
#define PRINTDLG_PROPERTIES "chrome://communicator/locale/gfx/printdialog.prop
erties"
 
.
#define TEMPLATE_NAME "PRINTDLGNEW"
 
.
 
 
.
static HWND gParentWnd = NULL;
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
 
.
// The printer data is shared between the PrinterEnumerator and the nsDeviceCo
ntextSpecWin
 
.
// The PrinterEnumerator creates the printer info
 
.
// but the nsDeviceContextSpecWin cleans it up
 
 
.
// If it gets created (via the Page Setup Dialog) but the user never prints an
ything
 
.
// then it will never be delete, so this class takes care of that.
 
.
class GlobalPrinters {
 
.
public:
 
 
.
  static GlobalPrinters* GetInstance() { return &gCleanUpGlobalPrintersProtect
ed; }
 
.
  ~GlobalPrinters() { FreeGlobalPrinters(); }
 
.
 
 
.
  void FreeGlobalPrinters();
 
.
 
 
 
.
  PRBool       PrintersAreAllocated() { return mPrinters != nsnull && mPrinter
InfoArray != nsnull; }
 
.
 
 
.
  LPPRINTER_INFO_2 FindPrinterByName(const PRUnichar* aPrinterName);
 
 
.
  LPPRINTER_INFO_2 GetPrinterByIndex(PRInt32 aInx) { return mPrinters?(LPPRINT
ER_INFO_2)mPrinters->ElementAt(aInx):nsnull; }
 
.
 
 
.
  nsresult         EnumeratePrinterList();
 
.
  void             GetDefaultPrinterName(char*& aDefaultPrinterName);
 
 
.
  PRInt32          GetNumPrinters()             { return mPrinters?mPrinters->
Count():0; }
 
.
 
 
.
protected:
 
.
  GlobalPrinters() {}
 
.
  nsresult EnumerateNativePrinters(DWORD aWhichPrinters, char* aDefPrinter);
 
.
  void     AllocatePrinters();
 
.
 
 
.
  static GlobalPrinters gCleanUpGlobalPrintersProtected;
 
.
  static nsVoidArray*   mPrinters;
 
.
  static nsVoidArray*   mPrinterInfoArray;
 
.
};
 
.
//---------------
 
.
// static members
 
.
GlobalPrinters GlobalPrinters::gCleanUpGlobalPrintersProtected;
 
.
nsVoidArray*   GlobalPrinters::mPrinters         = nsnull;
 
.
nsVoidArray*   GlobalPrinters::mPrinterInfoArray = nsnull;
 
.
 
 
.
 
 
.
//******************************************************
 
.
// Define native paper sizes
 
.
//******************************************************
 
.
typedef struct {
 
.
  short  mPaperSize; // native enum
 
.
  double mWidth;
 
.
  double mHeight;
 
.
  PRBool mIsInches;
 
.
} NativePaperSizes;
 
.
 
 
.
// There are around 40 default print sizes defined by Windows
 
.
const NativePaperSizes kPaperSizes[] = {
 
.
  {DMPAPER_LETTER,    8.5,   11.0,  PR_TRUE},
 
.
  {DMPAPER_LEGAL,     8.5,   14.0,  PR_TRUE},
 
.
  {DMPAPER_A4,        210.0, 297.0, PR_FALSE},
 
.
  {DMPAPER_TABLOID,   11.0,  17.0,  PR_TRUE},
 
.
  {DMPAPER_LEDGER,    17.0,  11.0,  PR_TRUE},
 
.
  {DMPAPER_STATEMENT, 5.5,   8.5,   PR_TRUE},
 
.
  {DMPAPER_EXECUTIVE, 7.25,  10.5,  PR_TRUE},
 
.
  {DMPAPER_A3,        297.0, 420.0, PR_FALSE},
 
.
  {DMPAPER_A5,        148.0, 210.0, PR_FALSE},
 
.
  {DMPAPER_CSHEET,    17.0,  22.0,  PR_TRUE},  
 
.
  {DMPAPER_DSHEET,    22.0,  34.0,  PR_TRUE},  
 
.
  {DMPAPER_ESHEET,    34.0,  44.0,  PR_TRUE},  
 
.
  {DMPAPER_LETTERSMALL, 8.5, 11.0,  PR_TRUE},  
 
.
  {DMPAPER_A4SMALL,   210.0, 297.0, PR_FALSE}, 
 
.
  {DMPAPER_B4,        250.0, 354.0, PR_FALSE}, 
 
.
  {DMPAPER_B5,        182.0, 257.0, PR_FALSE},
 
.
  {DMPAPER_FOLIO,     8.5,   13.0,  PR_TRUE},
 
.
  {DMPAPER_QUARTO,    215.0, 275.0, PR_FALSE},
 
.
  {DMPAPER_10X14,     10.0,  14.0,  PR_TRUE},
 
.
  {DMPAPER_11X17,     11.0,  17.0,  PR_TRUE},
 
.
  {DMPAPER_NOTE,      8.5,   11.0,  PR_TRUE},  
 
.
  {DMPAPER_ENV_9,     3.875, 8.875, PR_TRUE},  
 
.
  {DMPAPER_ENV_10,    40.125, 9.5,  PR_TRUE},  
 
.
  {DMPAPER_ENV_11,    4.5,   10.375, PR_TRUE},  
 
.
  {DMPAPER_ENV_12,    4.75,  11.0,  PR_TRUE},  
 
.
  {DMPAPER_ENV_14,    5.0,   11.5,  PR_TRUE},  
 
.
  {DMPAPER_ENV_DL,    110.0, 220.0, PR_FALSE}, 
 
.
  {DMPAPER_ENV_C5,    162.0, 229.0, PR_FALSE}, 
 
.
  {DMPAPER_ENV_C3,    324.0, 458.0, PR_FALSE}, 
 
.
  {DMPAPER_ENV_C4,    229.0, 324.0, PR_FALSE}, 
 
.
  {DMPAPER_ENV_C6,    114.0, 162.0, PR_FALSE}, 
 
.
  {DMPAPER_ENV_C65,   114.0, 229.0, PR_FALSE}, 
 
.
  {DMPAPER_ENV_B4,    250.0, 353.0, PR_FALSE}, 
 
.
  {DMPAPER_ENV_B5,    176.0, 250.0, PR_FALSE}, 
 
.
  {DMPAPER_ENV_B6,    176.0, 125.0, PR_FALSE}, 
 
.
  {DMPAPER_ENV_ITALY, 110.0, 230.0, PR_FALSE}, 
 
.
  {DMPAPER_ENV_MONARCH,  3.875,  7.5, PR_TRUE},  
 
.
  {DMPAPER_ENV_PERSONAL, 3.625,  6.5, PR_TRUE},  
 
.
  {DMPAPER_FANFOLD_US,   14.875, 11.0, PR_TRUE},  
 
.
  {DMPAPER_FANFOLD_STD_GERMAN, 8.5, 12.0, PR_TRUE},  
 
.
  {DMPAPER_FANFOLD_LGL_GERMAN, 8.5, 13.0, PR_TRUE},  
 
.
};
 
.
const PRInt32 kNumPaperSizes = 41;
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
nsDeviceContextSpecWin :: nsDeviceContextSpecWin()
.
nsDeviceContextSpecWin :: nsDeviceContextSpecWin()
{
.
{
  NS_INIT_REFCNT();
.
  NS_INIT_REFCNT();
 
.
 
  mDriverName = nsnull;
.
  mDriverName    = nsnull;
  mDeviceName = nsnull;
.
  mDeviceName    = nsnull;
  mDEVMODE = NULL;
.
  mDevMode       = NULL;
 
.
  mGlobalDevMode = NULL;
 
.
  mIsDEVMODEGlobalHandle = PR_FALSE;
}
.
}
 
.
 
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
NS_IMPL_ISUPPORTS1(nsDeviceContextSpecWin, nsIDeviceContextSpec)
 
.
 
nsDeviceContextSpecWin :: ~nsDeviceContextSpecWin()
.
nsDeviceContextSpecWin :: ~nsDeviceContextSpecWin()
{
.
{
  if (nsnull != mDriverName)
.
  SetDeviceName(nsnull);
  {
.
  SetDriverName(nsnull);
    PR_Free(mDriverName);
.
  SetDevMode(NULL);
    mDriverName = nsnull;
.
  SetGlobalDevMode(NULL);
  }
.
 
 
.
  // Free them, we won't need them for a while
  if (nsnull != mDeviceName)
.
  GlobalPrinters::GetInstance()->FreeGlobalPrinters();
  {
.
}
    PR_Free(mDeviceName);
.
 
    mDeviceName = nsnull;
.
 
  }
 
.
//----------------------------------------------------------------------------
------
 
.
// Map an incoming size to a Windows Native enum in the DevMode
  if (NULL != mDEVMODE)
.
static void 
  {
.
MapPaperSizeToNativeEnum(LPDEVMODE aDevMode,
    ::GlobalFree(mDEVMODE);
.
                         PRInt16   aType, 
    mDEVMODE = NULL;
.
                         double    aW, 
 
.
                         double    aH)
 
.
{
 
.
 
 
.
#ifdef DEBUG_rods
 
.
  BOOL doingOrientation = aDevMode->dmFields & DM_ORIENTATION;
 
.
  BOOL doingPaperSize   = aDevMode->dmFields & DM_PAPERSIZE;
 
.
  BOOL doingPaperLength = aDevMode->dmFields & DM_PAPERLENGTH;
 
.
  BOOL doingPaperWidth  = aDevMode->dmFields & DM_PAPERWIDTH;
 
.
#endif
 
.
 
 
.
  PRBool foundEnum = PR_FALSE;
 
.
  for (PRInt32 i=0;i<kNumPaperSizes;i++) {
 
.
    if (kPaperSizes[i].mWidth == aW && kPaperSizes[i].mHeight == aH) {
 
.
      aDevMode->dmPaperSize = kPaperSizes[i].mPaperSize;
 
.
      aDevMode->dmFields &= ~DM_PAPERLENGTH;
 
.
      aDevMode->dmFields &= ~DM_PAPERWIDTH;
 
.
      aDevMode->dmFields |= DM_PAPERSIZE;
 
.
      return;
 
.
    }
  }
.
  }
 
.
 
 
.
  short width  = 0;
 
.
  short height = 0;
 
.
  if (aType == nsIPrintSettings::kPaperSizeInches) {
 
 
.
    width  = short(NS_TWIPS_TO_MILLIMETERS(NS_INCHES_TO_TWIPS(float(aW))) / 10
);
 
 
.
    height = short(NS_TWIPS_TO_MILLIMETERS(NS_INCHES_TO_TWIPS(float(aH))) / 10
);
 
.
 
 
.
  } else if (aType == nsIPrintSettings::kPaperSizeMillimeters) {
 
.
    width  = short(aW / 10.0);
 
.
    height = short(aH / 10.0);
 
.
  } else {
 
.
    return; // don't set anything
 
.
  }
 
.
 
 
.
  // width and height is in 
 
.
  aDevMode->dmPaperSize   = 0;
 
.
  aDevMode->dmPaperWidth  = width;
 
.
  aDevMode->dmPaperLength = height;
 
.
 
 
.
  aDevMode->dmFields |= DM_PAPERSIZE;
 
.
  aDevMode->dmFields |= DM_PAPERLENGTH;
 
.
  aDevMode->dmFields |= DM_PAPERWIDTH;
}
.
}
 
.
 
NS_IMPL_ISUPPORTS1(nsDeviceContextSpecWin, nsIDeviceContextSpec)
 
.
//----------------------------------------------------------------------------
------
 
.
// Setup Paper Size & Orientation options into the DevMode
 
.
// 
 
.
static void 
 
 
.
SetupDevModeFromSettings(LPDEVMODE aDevMode, nsIPrintSettings* aPrintSettings)
 
.
{
 
.
  // Setup paper size
 
.
  if (aPrintSettings) {
 
.
    PRInt16 type;
 
.
    aPrintSettings->GetPaperSizeType(&type);
 
.
    if (type == nsIPrintSettings::kPaperSizeNativeData) {
 
.
      PRInt16 paperEnum;
 
.
      aPrintSettings->GetPaperData(&paperEnum);
 
.
      aDevMode->dmPaperSize = paperEnum;
 
.
      aDevMode->dmFields &= ~DM_PAPERLENGTH;
 
.
      aDevMode->dmFields &= ~DM_PAPERWIDTH;
 
.
      aDevMode->dmFields |= DM_PAPERSIZE;
 
.
    } else {
 
.
      PRInt16 unit;
 
.
      double width, height;
 
.
      aPrintSettings->GetPaperSizeUnit(&unit);
 
.
      aPrintSettings->GetPaperWidth(&width);
 
.
      aPrintSettings->GetPaperHeight(&height);
 
.
      MapPaperSizeToNativeEnum(aDevMode, unit, width, height);
 
.
    }
 
.
 
 
.
    // Setup Orientation
 
.
    PRInt32 orientation;
 
.
    aPrintSettings->GetOrientation(&orientation);
 
 
.
    aDevMode->dmOrientation = orientation == nsIPrintSettings::kPortraitOrient
ation?DMORIENT_PORTRAIT:DMORIENT_LANDSCAPE;
 
.
    aDevMode->dmFields |= DM_ORIENTATION;
 
.
 
 
.
    // Setup Number of Copies
 
.
    PRInt32 copies;
 
.
    aPrintSettings->GetNumCopies(&copies);
 
.
    aDevMode->dmCopies = copies;
 
.
    aDevMode->dmFields |= DM_COPIES;
 
.
  }
 
.
 
 
.
}
 
.
 
NS_IMETHODIMP nsDeviceContextSpecWin :: Init(char *aDriverName, char *aDeviceN
ame, HGLOBAL aDEVMODE)
.
//----------------------------------------------------------------------------
------
 
.
// Helper Function - Free and reallocate the string
 
 
.
static nsresult SetPrintSettingsFromDevMode(nsIPrintSettings* aPrintSettings, 
LPDEVMODE aDevMode)
{
.
{
  if (nsnull != aDriverName)
.
  if (aPrintSettings == nsnull) {
  {
.
    return NS_ERROR_FAILURE;
    mDriverName = (char *)PR_Malloc(PL_strlen(aDriverName) + 1);
.
  }
    PL_strcpy(mDriverName, aDriverName);
.
  BOOL doingNumCopies   = aDevMode->dmFields & DM_COPIES;
 
.
  BOOL doingOrientation = aDevMode->dmFields & DM_ORIENTATION;
 
.
  BOOL doingPaperSize   = aDevMode->dmFields & DM_PAPERSIZE;
 
.
  BOOL doingPaperLength = aDevMode->dmFields & DM_PAPERLENGTH;
 
.
  BOOL doingPaperWidth  = aDevMode->dmFields & DM_PAPERWIDTH;
 
.
 
 
.
  if (doingOrientation) {
 
.
    PRInt32 orientation  = aDevMode->dmOrientation == DMORIENT_PORTRAIT?
 
 
.
      nsIPrintSettings::kPortraitOrientation:nsIPrintSettings::kLandscapeOrien
tation;
 
.
    aPrintSettings->SetOrientation(orientation);
  }
.
  }
 
.
 
  if (nsnull != aDeviceName)
.
  // Setup Number of Copies
  {
.
  if (doingNumCopies) {
    mDeviceName = (char *)PR_Malloc(PL_strlen(aDeviceName) + 1);
.
    aPrintSettings->SetNumCopies(PRInt32(aDevMode->dmCopies));
    PL_strcpy(mDeviceName, aDeviceName);
.
 
  }
.
  }
 
.
 
  mDEVMODE = aDEVMODE;
.
  if (doingPaperSize) {
 
.
    aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeNativeData);
 
.
    aPrintSettings->SetPaperData(aDevMode->dmPaperSize);
 
.
 
 
.
  } else if (doingPaperLength && doingPaperWidth) {
 
.
    PRBool found = PR_FALSE;
 
.
    for (PRInt32 i=0;i<kNumPaperSizes;i++) {
 
.
      if (kPaperSizes[i].mPaperSize == aDevMode->dmPaperSize) {
 
 
.
        aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeDefined);
 
.
        aPrintSettings->SetPaperWidth(kPaperSizes[i].mWidth);
 
.
        aPrintSettings->SetPaperHeight(kPaperSizes[i].mHeight);
 
 
.
        aPrintSettings->SetPaperSizeUnit(kPaperSizes[i].mIsInches?nsIPrintSett
ings::kPaperSizeInches:nsIPrintSettings::kPaperSizeInches);
 
.
        found = PR_TRUE;
 
.
        break;
 
.
      }
 
.
    }
 
.
    if (!found) {
 
.
      return NS_ERROR_FAILURE;
 
.
    }
 
.
  } else {
 
.
    return NS_ERROR_FAILURE;
 
.
  }
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP nsDeviceContextSpecWin :: GetDriverName(char *&aDriverName) cons
t
.
//----------------------------------------------------------------------------
------
 
.
NS_IMETHODIMP nsDeviceContextSpecWin :: Init(nsIWidget* aWidget, 
 
 
.
                                             nsIPrintSettings* aPrintSettings,
 
.
                                             PRBool aQuiet)
 
.
{
 
.
  mPrintSettings = aPrintSettings;
 
.
 
 
.
  gParentWnd = (HWND)aWidget->GetNativeData(NS_NATIVE_WINDOW);
 
.
 
 
.
  PRBool doNativeDialog = PR_FALSE;
 
.
  nsresult rv = NS_ERROR_FAILURE;
 
.
  nsCOMPtr<nsIPref> pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv);
 
.
  if (NS_SUCCEEDED(rv)) {
 
.
    pPrefs->GetBoolPref("print.use_native_print_dialog", &doNativeDialog);
 
.
  }
 
.
 
 
.
  if (doNativeDialog || aQuiet) {
 
.
    rv = ShowNativePrintDialog(aWidget, aQuiet);
 
.
  } else {
 
.
    rv = ShowXPPrintDialog(aQuiet);
 
.
  }
 
.
 
 
.
  return rv;
 
.
}
 
.
 
 
.
//----------------------------------------------------------
 
.
// Helper Function - Free and reallocate the string
 
.
static void CleanAndCopyString(char*& aStr, char* aNewStr)
 
.
{
 
.
  if (aStr != nsnull) {
 
 
.
    if (aNewStr != nsnull && strlen(aStr) > strlen(aNewStr)) { // reuse it if 
we can
 
.
      PL_strcpy(aStr, aNewStr);
 
.
      return;
 
.
    } else {
 
.
      PR_Free(aStr);
 
.
      aStr = nsnull;
 
.
    }
 
.
  }
 
.
 
 
.
  if (nsnull != aNewStr) {
 
.
    aStr = (char *)PR_Malloc(PL_strlen(aNewStr) + 1);
 
.
    PL_strcpy(aStr, aNewStr);
 
.
  }
 
.
}
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
void nsDeviceContextSpecWin :: SetDeviceName(char* aDeviceName)
 
.
{
 
.
  CleanAndCopyString(mDeviceName, aDeviceName);
 
.
}
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
void nsDeviceContextSpecWin :: SetDriverName(char* aDriverName)
 
.
{
 
.
  CleanAndCopyString(mDriverName, aDriverName);
 
.
}
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
void nsDeviceContextSpecWin :: SetGlobalDevMode(HGLOBAL aHGlobal)
 
.
{
 
.
  if (mGlobalDevMode) {
 
.
    ::GlobalFree(mGlobalDevMode);
 
.
    mGlobalDevMode = NULL;
 
.
  }
 
.
  mGlobalDevMode = aHGlobal;
 
.
  mIsDEVMODEGlobalHandle = PR_TRUE;
 
.
}
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
void nsDeviceContextSpecWin :: SetDevMode(LPDEVMODE aDevMode)
 
.
{
 
.
  mDevMode = aDevMode;
 
.
  mIsDEVMODEGlobalHandle = PR_FALSE;
 
.
}
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
// Return localized bundle for resource strings
 
.
static nsresult
 
.
GetLocalizedBundle(const char * aPropFileName, nsIStringBundle** aStrBundle)
 
.
{
 
.
  NS_ENSURE_ARG_POINTER(aPropFileName);
 
.
  NS_ENSURE_ARG_POINTER(aStrBundle);
 
.
 
 
.
  nsresult rv;
 
.
  nsCOMPtr<nsIStringBundle> bundle;
 
.
  
 
.
 
 
.
  // Create bundle
 
.
  nsCOMPtr<nsIStringBundleService> stringService = 
 
.
    do_GetService(kStringBundleServiceCID, &rv);
 
.
  if (NS_SUCCEEDED(rv) && stringService) {
 
.
    rv = stringService->CreateBundle(aPropFileName, aStrBundle);
 
.
  }
 
.
  
 
.
  return rv;
 
.
}
 
.
 
 
.
//--------------------------------------------------------
 
.
// Return localized string 
 
.
static nsresult
 
 
.
GetLocalizedString(nsIStringBundle* aStrBundle, const char* aKey, nsString& oV
al)
{
.
{
  aDriverName = mDriverName;
.
  NS_ENSURE_ARG_POINTER(aStrBundle);
 
.
  NS_ENSURE_ARG_POINTER(aKey);
 
.
 
 
.
  // Determine default label from string bundle
 
.
  nsXPIDLString valUni;
 
.
  nsAutoString key; 
 
.
  key.AssignWithConversion(aKey);
 
 
.
  nsresult rv = aStrBundle->GetStringFromName(key.get(), getter_Copies(valUni)
);
 
.
  if (NS_SUCCEEDED(rv) && valUni) {
 
.
    oVal.Assign(valUni);
 
.
  } else {
 
.
    oVal.Truncate();
 
.
  }
 
.
  return rv;
 
.
}
 
.
 
 
.
//--------------------------------------------------------
 
.
// Set a multi-byte string in the control
 
.
static void SetTextOnWnd(HWND aControl, const nsString& aStr)
 
.
{
 
.
  char* pStr = nsDeviceContextWin::GetACPString(aStr);
 
.
  if (pStr) {
 
.
    ::SetWindowText(aControl, pStr);
 
.
    delete [] pStr;
 
.
  }
 
.
}
 
.
 
 
.
//--------------------------------------------------------
 
.
// Will get the control and localized string by "key"
 
.
static void SetText(HWND             aParent, 
 
.
                    UINT             aId, 
 
.
                    nsIStringBundle* aStrBundle,
 
.
                    const char*      aKey) 
 
.
{
 
.
  HWND wnd = GetDlgItem (aParent, aId);
 
.
  if (!wnd) {
 
.
    return;
 
.
  }
 
.
  nsAutoString str;
 
.
  nsresult rv = GetLocalizedString(aStrBundle, aKey, str);
 
.
  if (NS_SUCCEEDED(rv)) {
 
.
    SetTextOnWnd(wnd, str);
 
.
  }
 
.
}
 
.
 
 
.
//--------------------------------------------------------
 
.
static void SetRadio(HWND         aParent, 
 
.
                     UINT         aId, 
 
.
                     PRBool       aIsSet,
 
.
                     PRBool       isEnabled = PR_TRUE) 
 
.
{
 
.
  HWND wnd = ::GetDlgItem (aParent, aId);
 
.
  if (!wnd) {
 
.
    return;
 
.
  }
 
.
  if (!isEnabled) {
 
.
    ::EnableWindow(wnd, FALSE);
 
.
    return;
 
.
  }
 
.
  ::EnableWindow(wnd, TRUE);
 
.
  ::SendMessage(wnd, BM_SETCHECK, (WPARAM)aIsSet, (LPARAM)0);
 
.
}
 
.
 
 
.
//--------------------------------------------------------
 
.
static void SetRadioOfGroup(HWND aDlg, int aRadId)
 
.
{
 
.
  int radioIds[] = {rad4, rad5, rad6};
 
.
  int numRads = 3;
 
.
 
 
.
  for (int i=0;i<numRads;i++) {
 
.
    HWND radWnd = ::GetDlgItem(aDlg, radioIds[i]);
 
.
    if (radWnd != NULL) {
 
 
.
      ::SendMessage(radWnd, BM_SETCHECK, (WPARAM)(radioIds[i] == aRadId), (LPA
RAM)0);
 
.
    }
 
.
  }
 
.
}
 
.
 
 
.
//--------------------------------------------------------
 
.
typedef struct {
 
.
  char * mKeyStr;
 
.
  long   mKeyId;
 
.
} PropKeyInfo;
 
.
 
 
.
// These are the control ids used in the dialog and 
 
.
// defined by MS-Windows in commdlg.h
 
.
static PropKeyInfo gAllPropKeys[] = {
 
.
    {"PrintFrames", grp3},
 
.
    {"Aslaid", rad4},
 
.
    {"selectedframe", rad5},
 
.
    {"Eachframe", rad6},
 
.
    {NULL, NULL}};
 
.
 
 
.
    // This is a list of other controls Ids in the native dialog
 
.
    // I am leaving these here for documentation purposes
 
.
    //
 
.
    //{"Printer", grp4},
 
.
    //{"Name", stc6},
 
.
    //{"Properties", psh2},
 
.
    //{"Status", stc8},
 
.
    //{"Type", stc7},
 
.
    //{"Where", stc10},
 
.
    //{"Comment", stc9},
 
.
    //{"Printtofile", chx1},
 
.
    //{"Printrange", grp1},
 
.
    //{"All", rad1},
 
.
    //{"Pages", rad3},
 
.
    //{"Selection", rad2},
 
.
    //{"from", stc2},
 
.
    //{"to", stc3},
 
.
    //{"Copies", grp2},
 
.
    //{"Numberofcopies", stc5},
 
.
    //{"Collate", chx2},
 
.
    //{"OK", IDOK},
 
.
    //{"Cancel", IDCANCEL},
 
.
    //{"stc11", stc11},
 
.
    //{"stc12", stc12},
 
.
    //{"stc14", stc14},
 
.
    //{"stc13", stc13},
 
.
 
 
.
//--------------------------------------------------------
 
.
//--------------------------------------------------------
 
.
//--------------------------------------------------------
 
.
//--------------------------------------------------------
 
.
// Get the absolute coords of the child windows relative
 
.
// to its parent window
 
.
static void GetLocalRect(HWND aWnd, RECT& aRect, HWND aParent)
 
.
{
 
.
  RECT wr;
 
.
  ::GetWindowRect(aParent, &wr);
 
.
 
 
.
  RECT cr;
 
.
  ::GetClientRect(aParent, &cr);
 
.
 
 
.
  ::GetWindowRect(aWnd, &aRect);
 
.
 
 
.
  int borderH = (wr.bottom-wr.top+1) - (cr.bottom-cr.top+1);
 
.
  int borderW = ((wr.right-wr.left+1) - (cr.right-cr.left+1))/2;
 
.
  aRect.top    -= wr.top+borderH-borderW;
 
.
  aRect.left   -= wr.left+borderW;
 
.
  aRect.right  -= wr.left+borderW;
 
.
  aRect.bottom -= wr.top+borderH-borderW;
 
.
}
 
.
 
 
.
//--------------------------------------------------------
 
.
// Show or Hide the control
 
.
void Show(HWND aWnd, PRBool bState)
 
.
{
 
.
  if (aWnd) {
 
.
    ::ShowWindow(aWnd, bState?SW_SHOW:SW_HIDE);
 
.
  }
 
.
}
 
.
 
 
.
//--------------------------------------------------------
 
.
// Create a child window "control"
 
.
static HWND CreateControl(LPCTSTR          aType,
 
.
                          DWORD            aStyle,
 
.
                          HINSTANCE        aHInst, 
 
.
                          HWND             aHdlg, 
 
.
                          int              aId, 
 
.
                          const nsAString& aStr, 
 
.
                          const nsRect&    aRect)
 
.
{
 
.
  char* pStr = nsDeviceContextWin::GetACPString(aStr);
 
.
  if (pStr == NULL) return NULL;
 
.
 
 
.
  HWND hWnd = ::CreateWindow (aType, pStr,
 
 
.
                              WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | aStyle
,
 
.
                              aRect.x, aRect.y, aRect.width, aRect.height,
 
.
                              (HWND)aHdlg, (HMENU)aId,
 
.
                              aHInst, NULL);
 
.
  if (hWnd == NULL) return NULL;
 
.
 
 
.
  delete [] pStr;
 
.
 
 
.
  // get the native font for the dialog and 
 
.
  // set it into the new control
 
 
.
  HFONT hFont = (HFONT)::SendMessage(aHdlg, WM_GETFONT, (WPARAM)0, (LPARAM)0);
 
.
  if (hFont != NULL) {
 
.
    ::SendMessage(hWnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0);
 
.
  }
 
.
  return hWnd;
 
.
}
 
.
 
 
.
//--------------------------------------------------------
 
.
// Create a Radio Button
 
.
static HWND CreateRadioBtn(HINSTANCE        aHInst, 
 
.
                           HWND             aHdlg, 
 
.
                           int              aId, 
 
.
                           const nsAString& aStr, 
 
.
                           const nsRect&    aRect)
 
.
{
 
 
.
  return CreateControl("BUTTON", BS_RADIOBUTTON, aHInst, aHdlg, aId, aStr, aRe
ct);
 
.
}
 
.
 
 
.
//--------------------------------------------------------
 
.
// Create a Group Box
 
.
static HWND CreateGroupBox(HINSTANCE        aHInst, 
 
.
                           HWND             aHdlg, 
 
.
                           int              aId, 
 
.
                           const nsAString& aStr, 
 
.
                           const nsRect&    aRect)
 
.
{
 
 
.
  return CreateControl("BUTTON", BS_GROUPBOX, aHInst, aHdlg, aId, aStr, aRect)
;
 
.
}
 
.
 
 
.
//--------------------------------------------------------
 
.
// Special Hook Procedure for handling the print dialog messages
 
 
.
UINT CALLBACK PrintHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lPara
m) 
 
.
{
 
.
 
 
.
  if (uiMsg == WM_COMMAND) {
 
.
    UINT id = LOWORD(wParam);
 
.
    if (id == rad4 || id == rad5 || id == rad6) {
 
.
      gFrameSelectedRadioBtn = id;
 
.
      SetRadioOfGroup(hdlg, id);
 
.
    }
 
.
 
 
.
  } else if (uiMsg == WM_INITDIALOG) {
 
.
    PRINTDLG * printDlg = (PRINTDLG *)lParam;
 
.
    if (printDlg == NULL) return 0L;
 
.
 
 
.
    PRInt16 howToEnableFrameUI = (PRBool)printDlg->lCustData;
 
.
 
 
.
    HINSTANCE hInst = (HINSTANCE)::GetWindowLong(hdlg, GWL_HINSTANCE);
 
.
    if (hInst == NULL) return 0L;
 
.
 
 
.
    // Start by getting the local rects of several of the controls
 
.
    // so we can calculate where the new controls are
 
.
    HWND wnd = ::GetDlgItem(hdlg, grp1);
 
.
    if (wnd == NULL) return 0L;
 
.
    RECT dlgRect;
 
.
    GetLocalRect(wnd, dlgRect, hdlg);
 
.
 
 
.
    wnd = ::GetDlgItem(hdlg, rad1); // this is the top control "All"
 
.
    if (wnd == NULL) return 0L;
 
.
    RECT rad1Rect;
 
.
    GetLocalRect(wnd, rad1Rect, hdlg);
 
.
 
 
.
    wnd = ::GetDlgItem(hdlg, rad2); // this is the bottom control "Selection"
 
.
    if (wnd == NULL) return 0L;
 
.
    RECT rad2Rect;
 
.
    GetLocalRect(wnd, rad2Rect, hdlg);
 
.
 
 
.
    wnd = ::GetDlgItem(hdlg, rad3); // this is the middle control "Pages"
 
.
    if (wnd == NULL) return 0L;
 
.
    RECT rad3Rect;
 
.
    GetLocalRect(wnd, rad3Rect, hdlg);
 
.
 
 
.
    HWND okWnd = ::GetDlgItem(hdlg, IDOK);
 
.
    if (okWnd == NULL) return 0L;
 
.
    RECT okRect;
 
.
    GetLocalRect(okWnd, okRect, hdlg);
 
.
 
 
.
    wnd = ::GetDlgItem(hdlg, grp4); // this is the "Print range" groupbox
 
.
    if (wnd == NULL) return 0L;
 
.
    RECT prtRect;
 
.
    GetLocalRect(wnd, prtRect, hdlg);
 
.
 
 
.
 
 
.
    // calculate various different "gaps" for layout purposes
 
.
 
 
 
.
    int rbGap     = rad3Rect.top - rad1Rect.bottom;     // gap between radiobt
ns
 
 
.
    int grpBotGap = dlgRect.bottom - rad2Rect.bottom;   // gap from bottom rb 
to bottom of grpbox
 
 
.
    int grpGap    = dlgRect.top - prtRect.bottom ;      // gap between group b
oxes
 
.
    int top       = dlgRect.bottom + grpGap;            
 
 
.
    int radHgt    = rad1Rect.bottom - rad1Rect.top + 1; // top of new group bo
x
 
 
.
    int y         = top+(rad1Rect.top-dlgRect.top);     // starting pos of fir
st radio
 
 
.
    int rbWidth   = dlgRect.right - rad1Rect.left - 5;  // measure from rb lef
t to the edge of the groupbox
 
.
                                                        // (5 is arbitrary)
 
.
    nsRect rect;
 
.
 
 
.
    // Create and position the radio buttons
 
.
    //
 
.
    // If any one control cannot be created then 
 
.
    // hide the others and bail out
 
.
    //
 
.
    rect.SetRect(rad1Rect.left, y, rbWidth,radHgt);
 
 
.
    HWND rad4Wnd = CreateRadioBtn(hInst, hdlg, rad4, NS_LITERAL_STRING("As &la
id out on the screen"), rect);
 
.
    if (rad4Wnd == NULL) return 0L;
 
.
    y += radHgt + rbGap;
 
.
 
 
.
    rect.SetRect(rad1Rect.left, y, rbWidth, radHgt);
 
 
.
    HWND rad5Wnd = CreateRadioBtn(hInst, hdlg, rad5, NS_LITERAL_STRING("The se
lected &frame"), rect);
 
.
    if (rad5Wnd == NULL) {
 
.
      Show(rad4Wnd, FALSE); // hide
 
.
      return 0L;
 
.
    }
 
.
    y += radHgt + rbGap;
 
.
 
 
.
    rect.SetRect(rad1Rect.left, y, rbWidth, radHgt);
 
 
.
    HWND rad6Wnd = CreateRadioBtn(hInst, hdlg, rad6, NS_LITERAL_STRING("&Each 
frame separately"), rect);
 
.
    if (rad6Wnd == NULL) {
 
.
      Show(rad4Wnd, FALSE); // hide
 
.
      Show(rad5Wnd, FALSE); // hide
 
.
      return 0L;
 
.
    }
 
.
    y += radHgt + grpBotGap;
 
.
 
 
.
    // Create and position the group box
 
.
    rect.SetRect (dlgRect.left, top, dlgRect.right-dlgRect.left+1, y-top+1);
 
 
.
    HWND grpBoxWnd = CreateGroupBox(hInst, hdlg, grp3, NS_LITERAL_STRING("Prin
t Frame"), rect);
 
.
    if (grpBoxWnd == NULL) {
 
.
      Show(rad4Wnd, FALSE); // hide
 
.
      Show(rad5Wnd, FALSE); // hide
 
.
      Show(rad6Wnd, FALSE); // hide
 
.
      return 0L;
 
.
    }
 
.
 
 
.
    // Here we figure out the old height of the dlg
 
.
    // then figure it's gap from the old grpbx to the bottom
 
.
    // then size the dlg
 
.
    RECT pr, cr; 
 
.
    ::GetWindowRect(hdlg, &pr);
 
.
    ::GetClientRect(hdlg, &cr);
 
.
 
 
.
    int dlgHgt = (cr.bottom - cr.top) + 1;
 
.
    int bottomGap = dlgHgt - okRect.bottom;
 
 
.
    pr.bottom += (dlgRect.bottom-dlgRect.top) + grpGap + 1 - (dlgHgt-dlgRect.b
ottom) + bottomGap;
 
.
 
 
 
.
    ::SetWindowPos(hdlg, NULL, pr.left, pr.top, pr.right-pr.left+1, pr.bottom-
pr.top+1, 
 
.
                   SWP_NOMOVE|SWP_NOREDRAW|SWP_NOZORDER);
 
.
 
 
.
    // figure out the new height of the dialog
 
.
    ::GetClientRect(hdlg, &cr);
 
.
    dlgHgt = (cr.bottom - cr.top) + 1;
 
.
 
 
.
    // Reposition the OK and Cancel btns
 
.
    int okHgt = okRect.bottom - okRect.top + 1;
 
.
    ::SetWindowPos(okWnd, NULL, okRect.left, dlgHgt-bottomGap-okHgt, 0, 0, 
 
.
                   SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER);
 
.
 
 
.
    HWND cancelWnd = ::GetDlgItem(hdlg, IDCANCEL);
 
.
    if (cancelWnd == NULL) return 0L;
 
.
 
 
.
    RECT cancelRect;
 
.
    GetLocalRect(cancelWnd, cancelRect, hdlg);
 
.
    int cancelHgt = cancelRect.bottom - cancelRect.top + 1;
 
 
.
    ::SetWindowPos(cancelWnd, NULL, cancelRect.left, dlgHgt-bottomGap-cancelHg
t, 0, 0, 
 
.
                   SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER);
 
.
 
 
.
    // Localize the new controls in the print dialog
 
.
    nsCOMPtr<nsIStringBundle> strBundle;
 
 
.
    if (NS_SUCCEEDED(GetLocalizedBundle(PRINTDLG_PROPERTIES, getter_AddRefs(st
rBundle)))) {
 
.
      PRInt32 i = 0;
 
.
      while (gAllPropKeys[i].mKeyStr != NULL) {
 
 
.
        SetText(hdlg, gAllPropKeys[i].mKeyId, strBundle, gAllPropKeys[i].mKeyS
tr);
 
.
        i++;
 
.
      }
 
.
    }
 
.
 
 
.
    // Set up radio buttons
 
.
    if (howToEnableFrameUI == nsIPrintSettings::kFrameEnableAll) {
 
.
      SetRadio(hdlg, rad4, PR_FALSE);  
 
.
      SetRadio(hdlg, rad5, PR_TRUE); 
 
.
      SetRadio(hdlg, rad6, PR_FALSE);
 
.
      // set default so user doesn't have to actually press on it
 
.
      gFrameSelectedRadioBtn = rad5;
 
.
 
 
 
.
    } else if (howToEnableFrameUI == nsIPrintSettings::kFrameEnableAsIsAndEach
) {
 
.
      SetRadio(hdlg, rad4, PR_FALSE);  
 
.
      SetRadio(hdlg, rad5, PR_FALSE, PR_FALSE); 
 
.
      SetRadio(hdlg, rad6, PR_TRUE);
 
.
      // set default so user doesn't have to actually press on it
 
.
      gFrameSelectedRadioBtn = rad6;
 
.
 
 
.
 
 
.
    } else {  // nsIPrintSettings::kFrameEnableNone
 
.
      // we are using this function to disabe the group box
 
.
      SetRadio(hdlg, grp3, PR_FALSE, PR_FALSE); 
 
.
      // now disable radiobuttons
 
.
      SetRadio(hdlg, rad4, PR_FALSE, PR_FALSE); 
 
.
      SetRadio(hdlg, rad5, PR_FALSE, PR_FALSE); 
 
.
      SetRadio(hdlg, rad6, PR_FALSE, PR_FALSE); 
 
.
    }
 
.
 
 
.
    // Looks like we were able to extend the dialog
 
.
    gDialogWasExtended = PR_TRUE;
 
.
  }
 
.
  return 0L;
 
.
}
 
.
 
 
.
//------------------------------------------------------------------
 
.
// Displays the native Print Dialog
 
.
nsresult 
 
 
.
nsDeviceContextSpecWin :: ShowNativePrintDialog(nsIWidget *aWidget, PRBool aQu
iet)
 
.
{
 
.
  NS_ENSURE_ARG_POINTER(aWidget);
 
.
 
 
.
  nsresult  rv = NS_ERROR_FAILURE;
 
.
  gDialogWasExtended  = PR_FALSE;
 
.
 
 
.
  PRINTDLG  prntdlg;
 
.
  memset(&prntdlg, 0, sizeof(PRINTDLG));
 
.
 
 
.
  prntdlg.lStructSize = sizeof(prntdlg);
 
.
  prntdlg.hwndOwner   = (HWND)aWidget->GetNativeData(NS_NATIVE_WINDOW);
 
.
  prntdlg.hDevMode    = NULL;
 
.
  prntdlg.hDevNames   = NULL;
 
.
  prntdlg.hDC         = NULL;
 
 
.
  prntdlg.Flags       = PD_ALLPAGES | PD_RETURNIC | PD_HIDEPRINTTOFILE | PD_US
EDEVMODECOPIESANDCOLLATE;
 
.
 
 
.
  // if there is a current selection then enable the "Selection" radio button
 
.
  PRInt16 howToEnableFrameUI = nsIPrintSettings::kFrameEnableNone;
 
.
  if (mPrintSettings != nsnull) {
 
.
    PRBool isOn;
 
 
.
    mPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isO
n);
 
.
    if (!isOn) {
 
.
      prntdlg.Flags |= PD_NOSELECTION;
 
.
    }
 
.
    mPrintSettings->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(strB
undle)))) {
 
.
    nsAutoString doExtendStr;
 
.
    if (NS_SUCCEEDED(GetLocalizedString(strBundle, "extend", doExtendStr))) {
 
.
      doExtend = doExtendStr.EqualsIgnoreCase("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 || aQuiet) {
 
.
    prntdlg.lCustData         = NULL;
 
.
    prntdlg.lpfnPrintHook     = NULL;
 
.
  } else {
 
.
    // Set up print dialog "hook" procedure for extending the dialog
 
.
    prntdlg.lCustData         = (DWORD)howToEnableFrameUI;
 
.
    prntdlg.lpfnPrintHook     = PrintHookProc;
 
.
    prntdlg.Flags            |= PD_ENABLEPRINTHOOK;
 
.
  }
 
.
 
 
.
  if (PR_TRUE == aQuiet){
 
 
.
    prntdlg.Flags = PD_ALLPAGES | PD_RETURNDEFAULT | PD_RETURNIC | PD_USEDEVMO
DECOPIESANDCOLLATE;
 
.
  }
 
.
 
 
.
  BOOL result = ::PrintDlg(&prntdlg);
 
.
 
 
.
  if (TRUE == result) {
 
.
    if (mPrintSettings && prntdlg.hDevMode != NULL) {
 
.
      LPDEVMODE devMode = (LPDEVMODE)::GlobalLock(prntdlg.hDevMode);
 
.
      SetPrintSettingsFromDevMode(mPrintSettings, 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]);
 
.
 
 
.
      // Setup local Data members
 
.
      SetDeviceName(device);
 
.
      SetDriverName(driver);
 
.
 
 
.
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
 
 
.
      printf("printer: driver %s, device %s  flags: %d\n", driver, device, prn
tdlg.Flags);
 
.
#endif
 
.
      ::GlobalUnlock(prntdlg.hDevNames);
 
.
 
 
.
      // fill the print options with the info from the dialog
 
.
      if (mPrintSettings != nsnull) {
 
.
 
 
.
        if (prntdlg.Flags & PD_SELECTION) {
 
.
          mPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSelection);
 
.
 
 
.
        } else if (prntdlg.Flags & PD_PAGENUMS) {
 
 
.
          mPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSpecifiedPageR
ange);
 
.
          mPrintSettings->SetStartPageRange(prntdlg.nFromPage);
 
.
          mPrintSettings->SetEndPageRange( prntdlg.nToPage);
 
.
 
 
.
        } else { // (prntdlg.Flags & PD_ALLPAGES)
 
.
          mPrintSettings->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: 
 
 
.
                mPrintSettings->SetPrintFrameType(nsIPrintSettings::kFramesAsI
s);
 
.
                break;
 
.
              case rad5: 
 
 
.
                mPrintSettings->SetPrintFrameType(nsIPrintSettings::kSelectedF
rame);
 
.
                break;
 
.
              case rad6: 
 
 
.
                mPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrame
Sep);
 
.
                break;
 
.
            } // switch
 
.
          } else {
 
.
            // if it didn't get extended then have it default to printing
 
.
            // each frame separately
 
 
.
            mPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep)
;
 
.
          }
 
.
        } else {
 
.
          mPrintSettings->SetPrintFrameType(nsIPrintSettings::kNoFrames);
 
.
        }
 
.
      }
 
.
 
 
.
 
 
.
#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
 
.
    
 
.
      SetGlobalDevMode(prntdlg.hDevMode);
 
.
 
 
.
      // Set into DevMode Paper Size and Orientation here
 
.
      // remove comment if you want to override the values from
 
.
      // the native setup with those specified in the Page Setup
 
.
      // mainly Paper Size, Orientation
 
.
      // SetupPaperInfoFromSettings();
 
.
 
 
.
    }
 
.
  } else {
 
.
    return NS_ERROR_ABORT;
 
.
  }
 
.
 
 
.
  return NS_OK;
 
.
}
 
.
 
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
// Setup the object's data member with the selected printer's data
 
.
void
 
.
nsDeviceContextSpecWin :: GetDataFromPrinter(PRUnichar * aName)
 
.
{
 
.
  if (!GlobalPrinters::GetInstance()->PrintersAreAllocated()) {
 
.
    return;
 
.
  }
 
.
 
 
 
.
  LPPRINTER_INFO_2 prtInfo = GlobalPrinters::GetInstance()->FindPrinterByName(
aName);
 
.
  if (prtInfo == nsnull) {
 
.
    return;
 
.
  }
 
.
 
 
.
  SetDevMode(prtInfo->pDevMode);
 
.
 
 
.
  SetDeviceName(prtInfo->pPrinterName);
 
.
  
 
.
  // The driver should be NULL for Win95/Win98
 
.
  OSVERSIONINFO os;
 
.
  os.dwOSVersionInfoSize = sizeof(os);
 
.
  ::GetVersionEx(&os);
 
.
  if (VER_PLATFORM_WIN32_NT == os.dwPlatformId) {
 
.
    SetDriverName("WINSPOOL");
 
.
  } else {
 
.
    SetDriverName(NULL);
 
.
  }
 
.
}
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
// Setup Paper Size options into the DevMode
 
.
// 
 
.
// When using a data member it may be a HGLOCAL or LPDEVMODE
 
.
// if it is a HGLOBAL then we need to "lock" it to get the LPDEVMODE
 
.
// and unlock it when we are done.
 
.
void 
 
.
nsDeviceContextSpecWin :: SetupPaperInfoFromSettings()
 
.
{
 
.
  LPDEVMODE devMode;
 
.
 
 
.
  if (mDevMode == NULL && mGlobalDevMode == NULL) {
 
.
    return;
 
.
  }
 
.
  if (mGlobalDevMode != nsnull) {
 
.
    devMode = (DEVMODE *)::GlobalLock(mGlobalDevMode);
 
.
  } else {
 
.
    devMode = mDevMode;
 
.
  }
 
.
 
 
.
  SetupDevModeFromSettings(devMode, mPrintSettings);
 
.
 
 
.
  if (mGlobalDevMode != nsnull) ::GlobalUnlock(mGlobalDevMode);
 
.
}
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
nsresult 
 
.
nsDeviceContextSpecWin :: ShowXPPrintDialog(PRBool aQuiet)
 
.
{
 
.
  nsresult rv = NS_ERROR_FAILURE;
 
.
 
 
.
  NS_ASSERTION(mPrintSettings, "Can't have a null PrintSettings!");
 
.
 
 
.
  // if there is a current selection then enable the "Selection" radio button
 
.
  PRBool isOn;
 
 
.
  mPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn)
;
 
.
  nsCOMPtr<nsIPref> pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv);
 
.
  if (NS_SUCCEEDED(rv)) {
 
.
    (void) pPrefs->SetBoolPref("print.selection_radio_enabled", isOn);
 
.
  }
 
.
 
 
.
  PRBool canPrint = PR_FALSE;
 
.
  if (!aQuiet ) {
 
.
    rv = NS_ERROR_FAILURE;
 
.
 
 
.
    // create a nsISupportsArray of the parameters 
 
.
    // being passed to the window
 
.
    nsCOMPtr<nsISupportsArray> array;
 
.
    NS_NewISupportsArray(getter_AddRefs(array));
 
.
    if (!array) return NS_ERROR_FAILURE;
 
.
 
 
.
    nsCOMPtr<nsISupports> psSupports(do_QueryInterface(mPrintSettings));
 
.
    NS_ASSERTION(psSupports, "PrintSettings must be a supports");
 
.
    array->AppendElement(psSupports);
 
.
 
 
 
.
    nsCOMPtr<nsIDialogParamBlock> ioParamBlock(do_CreateInstance("@mozilla.org
/embedcomp/dialogparam;1"));
 
.
    if (ioParamBlock) {
 
.
      ioParamBlock->SetInt(0, 0);
 
.
      nsCOMPtr<nsISupports> blkSupps(do_QueryInterface(ioParamBlock));
 
.
      NS_ASSERTION(blkSupps, "IOBlk must be a supports");
 
.
 
 
.
      array->AppendElement(blkSupps);
 
.
      nsCOMPtr<nsISupports> arguments(do_QueryInterface(array));
 
.
      NS_ASSERTION(array, "array must be a supports");
 
.
 
 
 
.
      nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService("@mozilla.org/embedcomp/
window-watcher;1"));
 
.
      if (wwatch) {
 
.
        nsCOMPtr<nsIDOMWindow> active;
 
.
        wwatch->GetActiveWindow(getter_AddRefs(active));      
 
.
        nsCOMPtr<nsIDOMWindowInternal> parent = do_QueryInterface(active);
 
.
 
 
.
        nsCOMPtr<nsIDOMWindow> newWindow;
 
 
.
        rv = wwatch->OpenWindow(parent, "chrome://global/content/printdialog.x
ul",
 
.
                      "_blank", "chrome,modal,centerscreen", array,
 
.
                      getter_AddRefs(newWindow));
 
.
      }
 
.
    }
 
.
 
 
.
    if (NS_SUCCEEDED(rv)) {
 
.
      PRInt32 buttonPressed = 0;
 
.
      ioParamBlock->GetInt(0, &buttonPressed);
 
.
      if (buttonPressed == 1) {
 
.
        canPrint = PR_TRUE;
 
.
      } else {
 
.
        rv = NS_ERROR_ABORT;
 
.
      }
 
.
    }
 
.
  } else {
 
.
    canPrint = PR_TRUE;
 
.
  }
 
.
 
 
.
  if (canPrint) {
 
.
    if (mPrintSettings != nsnull) {
 
.
      PRUnichar *printerName = nsnull;
 
.
      mPrintSettings->GetPrinterName(&printerName);
 
.
 
 
.
      if (printerName != nsnull) {
 
.
        // Gets DEVMODE, Device and Driver Names
 
.
        GetDataFromPrinter(printerName);
 
.
 
 
.
        // Set into DevMode Paper Size and Orientation here
 
.
        SetupPaperInfoFromSettings();
 
.
 
 
.
        nsMemory::Free(printerName);
 
.
      } else {
 
.
        rv = NS_ERROR_OUT_OF_MEMORY;
 
.
      }
 
.
    }
 
.
    return NS_OK;
 
.
  }
 
.
 
 
.
  // Free them, we won't need them for a while
 
.
  GlobalPrinters::GetInstance()->FreeGlobalPrinters();
 
.
 
 
.
  return rv;
 
.
}
 
.
 
 
.
//***********************************************************
 
.
//  Printer Enumerator
 
.
//***********************************************************
 
.
nsPrinterEnumeratorWin::nsPrinterEnumeratorWin()
 
.
{
 
.
  NS_INIT_REFCNT();
 
.
}
 
.
 
 
.
nsPrinterEnumeratorWin::~nsPrinterEnumeratorWin()
 
.
{
 
.
  // Do not free printers here
 
.
  // GlobalPrinters::GetInstance()->FreeGlobalPrinters();
 
.
}
 
.
 
 
.
NS_IMPL_ISUPPORTS1(nsPrinterEnumeratorWin, nsIPrinterEnumerator)
 
.
 
 
.
 
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
// Enumerate all the Printers from the global array and pass their
 
.
// names back (usually to script)
 
.
NS_IMETHODIMP 
 
 
.
nsPrinterEnumeratorWin::EnumeratePrinters(PRUint32* aCount, PRUnichar*** aResu
lt)
 
.
{
 
.
  if (NS_FAILED(GlobalPrinters::GetInstance()->EnumeratePrinterList())) {
 
.
    return NS_ERROR_FAILURE;
 
.
  }
 
.
 
 
.
  if (aCount) 
 
.
    *aCount = 0;
 
.
  else 
 
.
    return NS_ERROR_NULL_POINTER;
 
.
  
 
.
  if (aResult) 
 
.
    *aResult = nsnull;
 
.
  else 
 
.
    return NS_ERROR_NULL_POINTER;
 
.
  
 
.
  PRInt32 numPrinters = GlobalPrinters::GetInstance()->GetNumPrinters();
 
.
 
 
.
  PRUnichar** array = (PRUnichar**) nsMemory::Alloc(numPrinters);
 
.
  if (!array) 
 
.
    return NS_ERROR_OUT_OF_MEMORY;
 
.
  
 
.
  PRInt32 count = 0;
 
.
  while( count < numPrinters ) {
 
 
.
    LPPRINTER_INFO_2 prtInfo = (LPPRINTER_INFO_2)GlobalPrinters::GetInstance()
->GetPrinterByIndex(count);
 
.
    nsString newName; 
 
.
    newName.AssignWithConversion(prtInfo->pPrinterName);
 
.
    PRUnichar *str = ToNewUnicode(newName);
 
.
    if (!str) {
 
.
      for (PRInt32 i = count - 1; i >= 0; i--) 
 
.
        nsMemory::Free(array[i]);
 
.
      
 
.
      nsMemory::Free(array);
 
.
      return NS_ERROR_OUT_OF_MEMORY;
 
.
    }
 
.
    array[count++] = str;
 
.
    
 
.
  }
 
.
  *aCount  = count;
 
.
  *aResult = array;
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP nsDeviceContextSpecWin :: GetDeviceName(char *&aDeviceName) cons
t
.
//----------------------------------------------------------------------------
------
 
.
// Display the AdvancedDocumentProperties for the selected Printer
 
 
.
NS_IMETHODIMP nsPrinterEnumeratorWin::DisplayPropertiesDlg(const PRUnichar *aP
rinterName, nsIPrintSettings* aPrintSettings)
 
.
{
 
 
.
  LPPRINTER_INFO_2 prtInfo = GlobalPrinters::GetInstance()->FindPrinterByName(
aPrinterName);
 
.
  if (prtInfo == nsnull) {
 
.
    return NS_ERROR_FAILURE;
 
.
  }
 
.
 
 
.
  nsresult rv = NS_ERROR_FAILURE;
 
.
 
 
.
  LPDEVMODE lpDevMode = prtInfo->pDevMode;
 
.
 
 
.
  // Convert Printer Name from Unicode to char*
 
.
  nsAutoString printerName;
 
.
  printerName = aPrinterName;
 
.
  char* nameCStr = ToNewCString(printerName);
 
.
 
 
.
  if (nameCStr != nsnull) {
 
.
    HANDLE hPrinter = NULL;
 
.
 
 
.
    PRINTER_DEFAULTS printerDefs;
 
.
    printerDefs.pDatatype     = NULL;
 
.
    printerDefs.pDevMode      = lpDevMode;
 
.
    printerDefs.DesiredAccess = PRINTER_ACCESS_USE;
 
.
 
 
.
    BOOL status = ::OpenPrinter(nameCStr, &hPrinter, &printerDefs);
 
.
    if (status) {
 
 
.
      // For some unknown reason calling AdvancedDocumentProperties with the o
utput arg
 
 
.
      // set to NULL doesn't return the number of bytes needed like the MS doc
umentation says
 
 
.
      // it should. So I am calling DocumentProperties to get the number of by
tes for the new DevMode
 
.
      // but calling it with a NULL output arg also causes problems
 
 
.
      // So I am creating a 1K buffer and using that and then if the returned 
size is larger 
 
.
      // reallocate the buffer with the new size.
 
.
      const int kBufferSize = 1024;
 
.
      LPDEVMODE newDevMode = (LPDEVMODE)malloc(kBufferSize);
 
.
      // get the bytes need for the new DevMode
 
.
#if 0 // leave this ifdef'ed for now
 
 
.
      LONG bytesNeeded = DocumentProperties(NULL, hPrinter, printerNameCStr, n
ewDevMode, lpDevMode, 0);
 
.
      if (bytesNeeded > kBufferSize) {
 
.
        free(newDevMode);
 
.
        newDevMode = (LPDEVMODE)malloc(bytesNeeded);
 
.
      }
 
.
#endif
 
.
      if (newDevMode != nsnull) {
 
.
        SetupDevModeFromSettings(lpDevMode, aPrintSettings);
 
.
 
 
.
        // Display the Dialog and get the new DevMode
 
 
.
#if 0 // need more to do more work to see why AdvancedDocumentProperties fails
 
 
.
      // when cancel is pressed
 
 
.
        LONG stat = ::AdvancedDocumentProperties(gParentWnd, hPrinter, prtInfo
->pDriverName, newDevMode, lpDevMode);
 
.
#else
 
 
.
        LONG stat = ::DocumentProperties(gParentWnd, hPrinter, prtInfo->pDrive
rName, newDevMode, lpDevMode, DM_IN_BUFFER|DM_IN_PROMPT|DM_OUT_BUFFER);
 
.
#endif
 
.
        if (stat == IDOK) {
 
.
          LONG size = sizeof(*lpDevMode);
 
.
          memcpy((void*)lpDevMode, (void*)newDevMode, size);
 
.
          // Now set the print options from the native Page Setup
 
.
          SetPrintSettingsFromDevMode(aPrintSettings, lpDevMode);
 
.
        }
 
.
        ::ClosePrinter(hPrinter);
 
.
        free(newDevMode);
 
.
        rv = NS_OK;
 
.
      } else {
 
.
        rv = NS_ERROR_OUT_OF_MEMORY;
 
.
      }
 
.
    }
 
.
  } else {
 
.
    rv = NS_ERROR_OUT_OF_MEMORY;
 
.
  }
 
.
 
 
.
  if (nameCStr != nsnull) nsMemory::Free(nameCStr);
 
.
 
 
.
  return rv;
 
.
}
 
.
 
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
//-- Global Printers
 
 
.
//----------------------------------------------------------------------------
------
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
// mPrinterInfoArray holds the arrays of LPPRINTER_INFO_2 returned 
 
.
// by the native Enumeration call
 
.
void 
 
.
GlobalPrinters::AllocatePrinters()
 
.
{
 
.
  if (PrintersAreAllocated()) {
 
.
    FreeGlobalPrinters();
 
.
  }
 
.
  mPrinters = new nsVoidArray();
 
.
  NS_ASSERTION(mPrinters, "Printers Array is NULL!");
 
.
 
 
.
  mPrinterInfoArray = new nsVoidArray();
 
.
  NS_ASSERTION(mPrinterInfoArray, "Printers Info  Array is NULL!");
 
.
}
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
void 
 
.
GlobalPrinters::FreeGlobalPrinters()
{
.
{
  aDeviceName = mDeviceName;
.
  if (mPrinterInfoArray != nsnull) {
 
.
    for (int i=0;i<mPrinterInfoArray->Count();i++) {
 
 
.
      LPPRINTER_INFO_2 printerInfo = (LPPRINTER_INFO_2)mPrinterInfoArray->Elem
entAt(i);
 
.
      if (printerInfo) {
 
.
        ::HeapFree(GetProcessHeap(), 0, printerInfo);
 
.
      }
 
.
    }
 
.
    delete mPrinterInfoArray;
 
.
    mPrinterInfoArray = nsnull;
 
.
  }
 
.
  if (mPrinters != nsnull) {
 
.
    delete mPrinters;
 
.
    mPrinters = nsnull;
 
.
  }
 
.
}
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
// Find a Printer in the Printer Array by Name
 
.
LPPRINTER_INFO_2 
 
.
GlobalPrinters::FindPrinterByName(const PRUnichar* aPrinterName)
 
.
{
 
.
  NS_ASSERTION(mPrinters, "mPrinters cannot be NULL!");
 
.
 
 
.
  if (mPrinters != nsnull) {
 
.
    for (PRInt32 i=0;i<mPrinters->Count();i++) {
 
.
      LPPRINTER_INFO_2 prtInfo = (LPPRINTER_INFO_2)mPrinters->ElementAt(i);
 
.
      nsString name;
 
.
      name = aPrinterName;
 
.
      if (name.EqualsWithConversion(prtInfo->pPrinterName)) {
 
.
        return prtInfo;
 
.
      }
 
.
    }
 
.
  }
 
.
  return nsnull;
 
.
}
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
nsresult 
 
 
.
GlobalPrinters::EnumerateNativePrinters(DWORD aWhichPrinters, char* aDefPrinte
r)
 
.
{
 
.
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
 
.
  OSVERSIONINFO os;
 
.
  os.dwOSVersionInfoSize = sizeof(os);
 
.
  ::GetVersionEx(&os);
 
.
#endif
 
.
 
 
.
  DWORD dwSizeNeeded;
 
.
  DWORD dwNumItems;
 
.
 
 
.
  // Get buffer size
 
 
.
  ::EnumPrinters ( aWhichPrinters, NULL, 2, NULL, 0, &dwSizeNeeded, &dwNumItem
s );
 
.
 
 
.
  // allocate memory for LPPRINTER_INFO_2 array
 
 
.
  LPPRINTER_INFO_2 printerInfo = (LPPRINTER_INFO_2)HeapAlloc (GetProcessHeap()
, HEAP_ZERO_MEMORY, dwSizeNeeded);
 
.
  if (printerInfo == NULL) {
 
.
    return NS_ERROR_OUT_OF_MEMORY;
 
.
  }
 
.
 
 
.
  // return an array of LPPRINTER_INFO_2 pointers
 
 
.
  if (::EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)printerInfo, dwSize
Needed, &dwSizeNeeded, &dwNumItems) == 0 ) {
 
.
    return NS_ERROR_OUT_OF_MEMORY;
 
.
  }
 
.
 
 
.
  // if we already have them, we need to release 
 
.
  // what we have and go get them again, because 
 
.
  // a printer may have been added in the mean time
 
.
  AllocatePrinters();
 
.
 
 
.
  if (mPrinters == nsnull) {
 
.
    if (mPrinters == nsnull && dwNumItems > 0) {
 
.
      return NS_ERROR_OUT_OF_MEMORY;
 
.
    }
 
.
  }
 
.
 
 
.
  if (mPrinters == nsnull) {
 
.
    if (mPrinters == nsnull && dwNumItems > 0) {
 
.
      return NS_ERROR_OUT_OF_MEMORY;
 
.
    }
 
.
  }
 
.
 
 
.
  for (DWORD i=0;i<dwNumItems;i++ ) {
 
 
.
    PRBool isDef  = aDefPrinter && !PL_strcmp(printerInfo[i].pPrinterName, aDe
fPrinter);
 
.
    // put the default printer at the beginning of list
 
.
    if (isDef) {
 
.
      // shift all the items in the list
 
.
      PRInt32 lastInx = mPrinters->Count()-1;
 
.
      for (PRInt32 inx=lastInx;inx>=0;inx--) {
 
.
        if (inx == lastInx) {
 
.
          mPrinters->AppendElement(mPrinters->ElementAt(inx));
 
.
        } else {
 
.
          mPrinters->ReplaceElementAt(mPrinters->ElementAt(inx), inx-1);
 
.
        }
 
.
      }
 
.
      mPrinters->ReplaceElementAt((void*)&printerInfo[i], 0);
 
.
    } else {
 
.
      mPrinters->AppendElement((void*)&printerInfo[i]);
 
.
    }
 
.
 
 
.
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
 
.
    printf("-------- %d ---------\n", i);
 
.
    printf("Printer Name:    %s\n" , printerInfo[i].pPrinterName);
 
 
.
    printf("Share Name:      %s\n" , printerInfo[i].Attributes & PRINTER_ATTRI
BUTE_SHARED?printerInfo[i].pShareName:"");
 
.
    printf("Ports:           %s\n" , printerInfo[i].pPortName);
 
.
    printf("Driver Name:     %s\n" , printerInfo[i].pDriverName);
 
.
    printf("Comment:         %s\n" , printerInfo[i].pComment);
 
.
    printf("Location:        %s\n" , printerInfo[i].pLocation);
 
.
    if (VER_PLATFORM_WIN32_NT != os.dwPlatformId) {
 
 
.
      printf("Default Printer: %s\n", printerInfo[i].Attributes & PRINTER_ATTR
IBUTE_DEFAULT?"YES":"NO");
 
.
    }
 
.
#endif
 
.
  }
 
.
 
 
.
  // hang onto the pointer until we are done
 
.
  mPrinterInfoArray->AppendElement((void*)printerInfo);
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP nsDeviceContextSpecWin :: GetDEVMODE(HGLOBAL &aDEVMODE) const
.
//------------------------------------------------------------------
 
.
// At this time, it is the only way I can figure out 
 
.
// how to get the default printer name is silently invoking the 
 
.
// native print dialog
 
.
void 
 
.
GlobalPrinters::GetDefaultPrinterName(char*& aDefaultPrinterName)
 
.
{
 
.
  aDefaultPrinterName = nsnull;
 
.
 
 
.
  PRINTDLG  prntdlg;
 
.
  memset(&prntdlg, 0, sizeof(PRINTDLG));
 
.
 
 
.
  prntdlg.lStructSize = sizeof(prntdlg);
 
.
  prntdlg.Flags = PD_RETURNDEFAULT | PD_RETURNIC;
 
.
 
 
.
  BOOL result = ::PrintDlg(&prntdlg);
 
.
 
 
.
  if (TRUE == result) {
 
.
    DEVNAMES *devnames = (DEVNAMES *)::GlobalLock(prntdlg.hDevNames);
 
.
    if ( NULL != devnames ) {
 
.
      char* device = &(((char *)devnames)[devnames->wDeviceOffset]);
 
.
      aDefaultPrinterName = new char[strlen(device)+1];
 
.
      PL_strcpy(aDefaultPrinterName, device);
 
.
      ::GlobalUnlock(prntdlg.hDevNames);
 
.
    }
 
.
  } 
 
.
}
 
.
 
 
 
.
//----------------------------------------------------------------------------
------
 
.
// This goes and gets the list of of avilable printers and puts
 
.
// the default printer at the beginning of the list
 
.
nsresult 
 
.
GlobalPrinters::EnumeratePrinterList()
{
.
{
  aDEVMODE = mDEVMODE;
.
  // reallocate and get a new list each time it is asked for
 
.
  if (PrintersAreAllocated()) {
 
.
    AllocatePrinters();
 
.
  }
 
.
 
 
.
  // get the name of the default printer
 
.
  char* defPrinterName;
 
.
  GetDefaultPrinterName(defPrinterName);
 
.
 
 
.
  // any of these could only fail with an OUT_MEMORY_ERROR
 
.
  nsresult rv = EnumerateNativePrinters(PRINTER_ENUM_LOCAL, defPrinterName);
 
.
  if (NS_SUCCEEDED(rv)) {
 
.
    rv = EnumerateNativePrinters(PRINTER_ENUM_NETWORK, defPrinterName);
 
.
    if (NS_SUCCEEDED(rv)) {
 
.
      rv = EnumerateNativePrinters(PRINTER_ENUM_SHARED, defPrinterName);
 
.
      if (NS_SUCCEEDED(rv)) {
 
.
        rv = EnumerateNativePrinters(PRINTER_ENUM_REMOTE, defPrinterName);
 
.
      }
 
.
    }
 
.
  }
 
.
 
 
.
  if (defPrinterName) delete[] defPrinterName;
 
.
 
 
.
  // make sure we at least tried to get the printers
 
.
  if (!PrintersAreAllocated()) {
 
.
    return NS_ERROR_FAILURE;
 
.
  }
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.