예제 #1
0
//----------------------------------------------------------------------------------
// Returns a Global Moveable Memory Handle to a DevMode
// from the Printer by the name of aPrintName
//
// NOTE:
//   This function assumes that aPrintName has already been converted from 
//   unicode
//
HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS)
{
  HGLOBAL hGlobalDevMode = nullptr;

  HANDLE hPrinter = nullptr;
  // const cast kludge for silly Win32 api's
  LPWSTR printName = const_cast<wchar_t*>(static_cast<const wchar_t*>(aPrintName.get()));
  BOOL status = ::OpenPrinterW(printName, &hPrinter, nullptr);
  if (status) {

    LPDEVMODEW  pNewDevMode;
    DWORD       dwNeeded, dwRet;

    // Get the buffer size
    dwNeeded = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, nullptr, nullptr, 0);
    if (dwNeeded == 0) {
      return nullptr;
    }

    // Allocate a buffer of the correct size.
    pNewDevMode = (LPDEVMODEW)::HeapAlloc (::GetProcessHeap(), HEAP_ZERO_MEMORY, dwNeeded);
    if (!pNewDevMode) return nullptr;

    hGlobalDevMode = (HGLOBAL)::GlobalAlloc(GHND, dwNeeded);
    if (!hGlobalDevMode) {
      ::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
      return nullptr;
    }

    dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, pNewDevMode, nullptr, DM_OUT_BUFFER);

    if (dwRet != IDOK) {
      ::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
      ::GlobalFree(hGlobalDevMode);
      ::ClosePrinter(hPrinter);
      return nullptr;
    }

    // Lock memory and copy contents from DEVMODE (current printer)
    // to Global Memory DEVMODE
    LPDEVMODEW devMode = (DEVMODEW *)::GlobalLock(hGlobalDevMode);
    if (devMode) {
      memcpy(devMode, pNewDevMode, dwNeeded);
      // Initialize values from the PrintSettings
      nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPS);
      MOZ_ASSERT(psWin);
      psWin->CopyToNative(devMode);

      // Sets back the changes we made to the DevMode into the Printer Driver
      dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode, DM_IN_BUFFER | DM_OUT_BUFFER);
      if (dwRet != IDOK) {
        ::GlobalUnlock(hGlobalDevMode);
        ::GlobalFree(hGlobalDevMode);
        ::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
        ::ClosePrinter(hPrinter);
        return nullptr;
      }

      ::GlobalUnlock(hGlobalDevMode);
    } else {
      ::GlobalFree(hGlobalDevMode);
      hGlobalDevMode = nullptr;
    }

    ::HeapFree(::GetProcessHeap(), 0, pNewDevMode);

    ::ClosePrinter(hPrinter);

  } else {
    return nullptr;
  }

  return hGlobalDevMode;
}
예제 #2
0
//----------------------------------------------------------------------------------
// Returns a Global Moveable Memory Handle to a DevMode
// from the Printer by the name of aPrintName
//
// NOTE:
//   This function assumes that aPrintName has already been converted from 
//   unicode
//
static nsReturnRef<nsHGLOBAL>
CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName,
                           nsIPrintSettings* aPS)
{
  nsHPRINTER hPrinter = nullptr;
  // const cast kludge for silly Win32 api's
  LPWSTR printName = const_cast<wchar_t*>(static_cast<const wchar_t*>(aPrintName.get()));
  BOOL status = ::OpenPrinterW(printName, &hPrinter, nullptr);
  if (!status) {
    return nsReturnRef<nsHGLOBAL>();
  }

  // Make sure hPrinter is closed on all paths
  nsAutoPrinter autoPrinter(hPrinter);

  // Get the buffer size
  DWORD dwNeeded = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, nullptr,
                                         nullptr, 0);
  if (dwNeeded == 0) {
    return nsReturnRef<nsHGLOBAL>();
  }

  // Allocate a buffer of the correct size.
  nsAutoDevMode newDevMode((LPDEVMODEW)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY,
                                                   dwNeeded));
  if (!newDevMode) {
    return nsReturnRef<nsHGLOBAL>();
  }

  nsHGLOBAL hDevMode = ::GlobalAlloc(GHND, dwNeeded);
  nsAutoGlobalMem globalDevMode(hDevMode);
  if (!hDevMode) {
    return nsReturnRef<nsHGLOBAL>();
  }

  DWORD dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, newDevMode,
                                      nullptr, DM_OUT_BUFFER);
  if (dwRet != IDOK) {
    return nsReturnRef<nsHGLOBAL>();
  }

  // Lock memory and copy contents from DEVMODE (current printer)
  // to Global Memory DEVMODE
  LPDEVMODEW devMode = (DEVMODEW *)::GlobalLock(hDevMode);
  if (!devMode) {
    return nsReturnRef<nsHGLOBAL>();
  }

  memcpy(devMode, newDevMode.get(), dwNeeded);
  // Initialize values from the PrintSettings
  nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPS);
  MOZ_ASSERT(psWin);
  psWin->CopyToNative(devMode);

  // Sets back the changes we made to the DevMode into the Printer Driver
  dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode,
                                DM_IN_BUFFER | DM_OUT_BUFFER);
  if (dwRet != IDOK) {
    ::GlobalUnlock(hDevMode);
    return nsReturnRef<nsHGLOBAL>();
  }

  ::GlobalUnlock(hDevMode);

  return globalDevMode.out();
}