//---------------------------------------------------------------------------------- // 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; }
//---------------------------------------------------------------------------------- // 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(); }