mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
587 lines
16 KiB
587 lines
16 KiB
//---------------------------------------------------------------------------
|
|
// FILE: PRTDC.C
|
|
//
|
|
// DESCRIPTION: This file contains functions that deal with the device
|
|
// context or devicemode.
|
|
//
|
|
// FUNCTIONS: PrtGetDC
|
|
// PrtRemoveDC
|
|
// GetPrtDevMode
|
|
// ChangePaperOrientation
|
|
//
|
|
/* $Log: S:\products\wangview\oiwh\print\prtdc.c_v $
|
|
*
|
|
* Rev 1.18 29 Feb 1996 14:49:24 RAR61941
|
|
* Find the default printer in a different location in the registry for
|
|
* Windows NT.
|
|
*
|
|
* Rev 1.17 15 Feb 1996 18:36:02 RAR61941
|
|
* Removed code (for NT builds only) that changes printer settings to finish
|
|
* spooling before printing starts.
|
|
*
|
|
* Rev 1.16 28 Sep 1995 17:10:54 RAR
|
|
* Added code to change the spooler settings to start printing after the last
|
|
* page of a job has been spooled. This is done to match what the MS fax viewer
|
|
* is doing so we can match their performance.
|
|
*
|
|
* Rev 1.15 14 Jul 1995 15:34:12 RAR
|
|
* Changed #include of display.h to engdisp.h.
|
|
*
|
|
* Rev 1.14 28 Jun 1995 14:23:54 RAR
|
|
* Fixed print error codes.
|
|
*
|
|
* Rev 1.13 23 Jun 1995 16:21:04 RAR
|
|
* Added include of engadm.h.
|
|
*
|
|
* Rev 1.12 23 Jun 1995 09:45:20 RAR
|
|
* Protection against simultaneous access of shared data by multiple threads and
|
|
* multiple processes.
|
|
*
|
|
* Rev 1.11 21 Jun 1995 16:17:50 RAR
|
|
* Moved all global vars to prtintl.h.
|
|
*
|
|
* Rev 1.10 20 Jun 1995 16:53:26 RAR
|
|
* Use thread local storage to store print prop.
|
|
*
|
|
* Rev 1.9 16 Jun 1995 14:10:32 RAR
|
|
* Changed MAXFILESPECLENGTH to MAX_PATH.
|
|
*
|
|
* Rev 1.8 15 Jun 1995 10:00:40 RAR
|
|
* Implemented passed in printer through DESTPRINTER struct.
|
|
*
|
|
* Rev 1.7 13 Jun 1995 16:46:28 RAR
|
|
* Print options are now stored in static mem rather than associated with window
|
|
* handle.
|
|
*
|
|
* Rev 1.6 31 May 1995 16:12:08 RAR
|
|
* Initialized to zero the 2 mystery DOCINFO members.
|
|
*
|
|
* Rev 1.5 22 May 1995 14:43:08 RAR
|
|
* Cleaned up the string resources. Also, made changes to successfully compile
|
|
* after integrating with new O/i include files.
|
|
*
|
|
* Rev 1.4 16 May 1995 16:18:56 RAR
|
|
* Added support for printing annotated images without the annotations.
|
|
*
|
|
* Rev 1.3 11 May 1995 13:38:02 RAR
|
|
* Added support for user supplied DC.
|
|
*
|
|
* Rev 1.2 08 May 1995 16:43:36 RAR
|
|
* Get default printer from registry instead of win.ini.
|
|
*
|
|
* Rev 1.1 04 May 1995 17:17:56 RAR
|
|
* Changed functions GetPrtDevMode and ChangePaperOrientation to use Windows 95
|
|
* function DocumentProperties instead of obsolete Windows 3.1 function
|
|
* GetDeviceMode.
|
|
*
|
|
* Rev 1.0 25 Apr 1995 17:00:30 RAR
|
|
* Initial entry
|
|
*/
|
|
//---------------------------------------------------------------------------
|
|
|
|
#include <windows.h>
|
|
|
|
#include "oiprt.h"
|
|
#include "prtintl.h"
|
|
#include "prtdlgs.h"
|
|
#include "prtstr.h"
|
|
|
|
#include "oiadm.h"
|
|
#include "engdisp.h"
|
|
#include "privapis.h"
|
|
#include "engadm.h"
|
|
|
|
|
|
|
|
#define MAX_SUBKEYSTRSIZE 32
|
|
#define HKEY_BASEKEY HKEY_CURRENT_USER
|
|
#define VALUENAME "Device"
|
|
|
|
char szSubKeys[][MAX_SUBKEYSTRSIZE] =
|
|
{
|
|
"Software",
|
|
"Microsoft",
|
|
"Windows NT",
|
|
"CurrentVersion",
|
|
"Windows"
|
|
};
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// FUNCTION: PrtGetDC
|
|
//
|
|
// DESCRIPTION: Sets the device context of the currently selected printer.
|
|
//---------------------------------------------------------------------------
|
|
|
|
int __stdcall PrtGetDC(HWND hWnd, LPHANDLE lpHnd, BOOL bSetAbort,
|
|
LPSTR lpOutMsg, PDESTPRINTER pPrinter, PPRTOPTS pPrtOpts)
|
|
{
|
|
int nStatus = 0;
|
|
HANDLE hPrtProp = NULL;
|
|
LPPRTPROP lpPrtProp = NULL;
|
|
DOCINFO DocInfo;
|
|
HANDLE hPrinterName = NULL;
|
|
PSTR pPrinterName = NULL;
|
|
int nPrinterNameSize;
|
|
HDC hErrTestDC;
|
|
HANDLE hPrt = NULL;
|
|
|
|
|
|
*lpHnd = 0;
|
|
|
|
if (!(hPrtProp = TlsGetValue(dwTlsIndex)))
|
|
{
|
|
// If property list not already setup, then set it up.
|
|
if (!(hPrtProp = GlobalAlloc(GHND, sizeof (PRTPROP))))
|
|
{
|
|
nStatus = PrtError(OIPRT_OUTOFMEMORY);
|
|
goto Exit;
|
|
}
|
|
if (!(lpPrtProp = (PRTPROP*)GlobalLock(hPrtProp)))
|
|
{
|
|
nStatus = PrtError(OIPRT_OUTOFMEMORY);
|
|
goto Exit;
|
|
}
|
|
|
|
if (!TlsSetValue(dwTlsIndex, hPrtProp))
|
|
{
|
|
nStatus = PrtError(OIPRT_TLSFAILURE);
|
|
goto Exit;
|
|
}
|
|
|
|
if (pPrinter)
|
|
{
|
|
if (!(lpPrtProp->hPrintDC = CreateDC(pPrinter->lpszDriver,
|
|
pPrinter->lpszDevice, pPrinter->lpszOutput, NULL)))
|
|
{
|
|
// Try to create a DC with valid params to test if system
|
|
// resources are exhausted.
|
|
if (!(hErrTestDC = CreateDC("DISPLAY", NULL, NULL, NULL)))
|
|
{
|
|
nStatus = PrtError(OIPRT_CANTCREATEDC);
|
|
}
|
|
// If its not the system, the passed in printer params must
|
|
// be invalid.
|
|
else
|
|
{
|
|
DeleteDC(hErrTestDC);
|
|
nStatus = PrtError(OIPRT_BADPRINTER);
|
|
}
|
|
goto Exit;
|
|
}
|
|
|
|
strncpy(lpPrtProp->szPrintName, pPrinter->lpszDevice, MAX_PRINTERNAMESIZE - 1);
|
|
}
|
|
else if (pPrtOpts->hPrtDC)
|
|
{
|
|
lpPrtProp->hPrintDC = pPrtOpts->hPrtDC;
|
|
|
|
if (pPrtOpts->szPrtName[0])
|
|
strcpy(lpPrtProp->szPrintName, pPrtOpts->szPrtName);
|
|
}
|
|
else
|
|
{
|
|
if (!(hPrinterName = GlobalAlloc(GHND, MAX_PRINTERNAMESIZE)))
|
|
{
|
|
nStatus = PrtError(OIPRT_OUTOFMEMORY);
|
|
goto Exit;
|
|
}
|
|
if (!(pPrinterName = (PSTR)GlobalLock(hPrinterName)))
|
|
{
|
|
nStatus = PrtError(OIPRT_OUTOFMEMORY);
|
|
goto Exit;
|
|
}
|
|
|
|
nPrinterNameSize = GlobalSize(hPrinterName);
|
|
|
|
if (nStatus = GetDefaultPrinter(pPrinterName, &nPrinterNameSize))
|
|
{
|
|
PrtError(nStatus);
|
|
goto Exit;
|
|
}
|
|
|
|
if (!(lpPrtProp->hPrintDC = CreateDC(NULL, pPrinterName, NULL,
|
|
NULL)))
|
|
{
|
|
nStatus = PrtError(OIPRT_CANTCREATEDC);
|
|
goto Exit;
|
|
}
|
|
|
|
strcpy(lpPrtProp->szPrintName, pPrinterName);
|
|
}
|
|
|
|
|
|
if (!(RC_BITBLT & GetDeviceCaps(lpPrtProp->hPrintDC, RASTERCAPS)))
|
|
{
|
|
nStatus = PrtError(OIPRT_PRINTERNOTSUPPORTED);
|
|
goto Exit;
|
|
}
|
|
|
|
if (bSetAbort)
|
|
{
|
|
lpPrtProp->lpAbortProc = GetProcAddress(hInst,
|
|
MAKEINTRESOURCE(ORD_PRTABORTPROC));
|
|
lpPrtProp->lpAbortDlgProc = GetProcAddress(hInst,
|
|
MAKEINTRESOURCE(ORD_PRTABORTDLGPROC));
|
|
EnableParents(hWnd, FALSE);
|
|
lpPrtProp->hAbortDlgWnd = IMGCreateDialog(hInst, "AbortDlg", hWnd,
|
|
lpPrtProp->lpAbortDlgProc);
|
|
|
|
if (SetAbortProc(lpPrtProp->hPrintDC,
|
|
lpPrtProp->lpAbortProc) <= 0)
|
|
{
|
|
nStatus = PrtError(OIPRT_CANTSETABORTPROC);
|
|
goto Exit;
|
|
}
|
|
SetDlgItemText(lpPrtProp->hAbortDlgWnd, ID_TITLE, lpOutMsg);
|
|
}
|
|
else
|
|
{
|
|
lpPrtProp->lpAbortProc = GetProcAddress(hInst,
|
|
MAKEINTRESOURCE(ORD_PRTABORTPROC));
|
|
EnableParents(hWnd, FALSE);
|
|
|
|
if (SetAbortProc(lpPrtProp->hPrintDC,
|
|
lpPrtProp->lpAbortProc) <= 0)
|
|
{
|
|
nStatus = PrtError(OIPRT_CANTSETABORTPROC);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
DocInfo.cbSize = sizeof (DOCINFO);
|
|
DocInfo.lpszDocName = lpOutMsg;
|
|
DocInfo.lpszOutput = NULL;
|
|
DocInfo.lpszDatatype = NULL; // undocumented param - 5/26/95
|
|
DocInfo.fwType = 0; // undocumented param - 5/26/95
|
|
|
|
if (StartDoc(lpPrtProp->hPrintDC, &DocInfo) <= 0)
|
|
{
|
|
nStatus = PrtError(OIPRT_CANTINITIATEJOB);
|
|
goto Exit;
|
|
}
|
|
GlobalUnlock(hPrtProp);
|
|
}
|
|
*lpHnd = hPrtProp;
|
|
|
|
Exit:
|
|
if (hPrt)
|
|
{
|
|
ClosePrinter(hPrt);
|
|
hPrt = NULL;
|
|
}
|
|
|
|
if (nStatus)
|
|
PrtRemoveDC(hWnd, nStatus, pPrtOpts);
|
|
|
|
if (hPrinterName)
|
|
{
|
|
GlobalUnlock(hPrinterName);
|
|
GlobalFree(hPrinterName);
|
|
}
|
|
|
|
return nStatus;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// FUNCTION: PrtRemoveDC
|
|
//
|
|
// DESCRIPTION: Delete the printer device context.
|
|
//---------------------------------------------------------------------------
|
|
|
|
int __stdcall PrtRemoveDC(HWND hWnd, int nStatusIn, PPRTOPTS pPrtOpts)
|
|
{
|
|
int nStatus = 0;
|
|
HANDLE hPrtProp = NULL;
|
|
PRTPROP* lpPrtProp = NULL;
|
|
HANDLE hPrt = NULL;
|
|
|
|
|
|
// Has property list already been set?
|
|
if (hPrtProp = TlsGetValue(dwTlsIndex))
|
|
{
|
|
// If property list present, delete the printDC, abort DLG and abort
|
|
// proc.
|
|
if (!(lpPrtProp = (PRTPROP*)GlobalLock(hPrtProp)))
|
|
{
|
|
nStatus = PrtError(OIPRT_OUTOFMEMORY);
|
|
goto Exit;
|
|
}
|
|
|
|
if (lpPrtProp->hPrintDC) // local/redirect printing
|
|
{
|
|
if ((nStatusIn) || (lpPrtProp->Abort))
|
|
{
|
|
// Escape(lpPrtProp->hPrintDC, FLUSHOUTPUT, 0, NULL, NULL);
|
|
AbortDoc(lpPrtProp->hPrintDC);
|
|
}
|
|
else
|
|
EndDoc(lpPrtProp->hPrintDC);
|
|
|
|
if (pPrtOpts->hPrtDC != lpPrtProp->hPrintDC)
|
|
DeleteDC(lpPrtProp->hPrintDC);
|
|
|
|
lpPrtProp->hPrintDC = 0;
|
|
}
|
|
|
|
|
|
memset(lpPrtProp->szPrintName, 0, MAX_PRINTERNAMESIZE);
|
|
|
|
#ifdef NOT_SUPPORTED_NORWAY
|
|
|
|
else // print server printing
|
|
{
|
|
LPPRIVJOB lpPrivJob;
|
|
char lpTempFileName[MAX_PATH];
|
|
LPSTR lpTemp2;
|
|
int nIndex = 0;
|
|
|
|
if (lpPrivJob = (LPPRIVJOB)lpPrtProp->dwReserved)
|
|
{
|
|
if (nStatus = IMGFileBinaryClose(hWnd, lpPrivJob->nFileID,
|
|
&nStatus))
|
|
PrtError(nStatus); // report error but go on
|
|
|
|
lstrcpy(lpTempFileName, (LPSTR)lpPrtProp->dwReserved);
|
|
lpTemp2 = &lpTempFileName[0];
|
|
while (lpTempFileName[nIndex])
|
|
{
|
|
if (IsDBCSLeadByte(lpTempFileName[nIndex]))
|
|
nIndex++;
|
|
else if (lpTempFileName[nIndex] == '\\' ||
|
|
lpTempFileName[nIndex] == ':')
|
|
lpTemp2 = &lpTempFileName[nIndex+1];
|
|
nIndex++;
|
|
}
|
|
*lpTemp2 = 'Q';
|
|
/* End DBCS Enable */
|
|
|
|
if (nStatus = IMGFileRenameFile(hWnd,
|
|
(LPSTR)lpPrtProp->dwReserved, lpTempFileName))
|
|
PrtError(nStatus); // report error but go on
|
|
|
|
// clean up memory holding queue name
|
|
GlobalUnlock(lpPrivJob->hJobName);
|
|
GlobalFree(lpPrivJob->hJobName);
|
|
}
|
|
}
|
|
|
|
#endif // #ifdef NOT_SUPPORTED_NORWAY
|
|
|
|
EnableParents(hWnd, TRUE);
|
|
|
|
if (lpPrtProp->hAbortDlgWnd)
|
|
DestroyWindow(lpPrtProp->hAbortDlgWnd);
|
|
}
|
|
|
|
Exit:
|
|
if (hPrt)
|
|
{
|
|
ClosePrinter(hPrt);
|
|
hPrt = NULL;
|
|
}
|
|
|
|
if (hPrtProp)
|
|
{
|
|
GlobalUnlock(hPrtProp);
|
|
GlobalFree(hPrtProp);
|
|
TlsSetValue(dwTlsIndex, 0);
|
|
}
|
|
|
|
if (nStatusIn)
|
|
return nStatusIn;
|
|
else
|
|
return nStatus;
|
|
} // end of PrtRemoveDC
|
|
|
|
//---------------------------------------------------------------------------
|
|
// FUNCTION: GetPrtDevMode
|
|
//
|
|
// DESCRIPTION: Gets a DEVMODE structure.
|
|
//---------------------------------------------------------------------------
|
|
|
|
PDEVMODE __stdcall GetPrtDevMode(HWND hWnd, HDC hDC, PPRTOPTS pPrtOpts)
|
|
{
|
|
int nStatus = 0;
|
|
HANDLE hPrinterName = NULL;
|
|
PSTR pPrinterName = NULL;
|
|
int nPrinterNameSize;
|
|
HANDLE hPrinter = NULL;
|
|
HANDLE hDevMode = NULL;
|
|
PDEVMODE pDevMode = NULL;
|
|
int nRc;
|
|
|
|
|
|
if (!(hPrinterName = GlobalAlloc(GHND, MAX_PRINTERNAMESIZE)))
|
|
{
|
|
nStatus = PrtError(OIPRT_OUTOFMEMORY);
|
|
goto Exit;
|
|
}
|
|
if (!(pPrinterName = (PSTR)GlobalLock(hPrinterName)))
|
|
{
|
|
nStatus = PrtError(OIPRT_OUTOFMEMORY);
|
|
goto Exit;
|
|
}
|
|
|
|
nPrinterNameSize = GlobalSize(hPrinterName);
|
|
|
|
if (pPrtOpts->hPrtDC == hDC)
|
|
{
|
|
if ( pPrtOpts->szPrtName[0] &&
|
|
strlen(pPrtOpts->szPrtName) < (UINT)nPrinterNameSize)
|
|
strcpy(pPrinterName, pPrtOpts->szPrtName);
|
|
else
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
if (nStatus = GetDefaultPrinter(pPrinterName, &nPrinterNameSize))
|
|
{
|
|
PrtError(nStatus);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
if (!OpenPrinter(pPrinterName, &hPrinter, NULL))
|
|
goto Exit;
|
|
|
|
if ((nRc = DocumentProperties(hWnd, hPrinter, pPrinterName, NULL,
|
|
NULL, 0)) <= 0)
|
|
goto Exit;
|
|
|
|
if (!(hDevMode = GlobalAlloc(GHND, nRc)))
|
|
{
|
|
nStatus = PrtError(OIPRT_OUTOFMEMORY);
|
|
goto Exit;
|
|
}
|
|
if (!(pDevMode = (PDEVMODE)GlobalLock(hDevMode)))
|
|
{
|
|
nStatus = PrtError(OIPRT_OUTOFMEMORY);
|
|
goto Exit;
|
|
}
|
|
|
|
if ((nRc = DocumentProperties(hWnd, hPrinter, pPrinterName, pDevMode,
|
|
NULL, DM_OUT_BUFFER)) < 0)
|
|
{
|
|
nStatus = PrtError(OIPRT_PRTDRVRFAILURE);
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
if (nStatus)
|
|
{
|
|
if (hDevMode)
|
|
{
|
|
GlobalUnlock(hDevMode);
|
|
GlobalFree(hDevMode);
|
|
pDevMode = NULL;
|
|
}
|
|
}
|
|
|
|
if (hPrinterName)
|
|
{
|
|
GlobalUnlock(hPrinterName);
|
|
GlobalFree(hPrinterName);
|
|
}
|
|
|
|
if (hPrinter)
|
|
ClosePrinter(hPrinter);
|
|
|
|
return pDevMode;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// FUNCTION: ChangePaperOrientation
|
|
//
|
|
// DESCRIPTION: Changes the paper orientation of the printer.
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __stdcall ChangePaperOrientation(HDC hDC, PDEVMODE pDevMode)
|
|
{
|
|
if (hDC && pDevMode)
|
|
ResetDC(hDC, pDevMode);
|
|
|
|
return;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// FUNCTION: GetDefaultPrinter
|
|
//
|
|
// DESCRIPTION: Gets the name of the default printer and its driver.
|
|
//---------------------------------------------------------------------------
|
|
|
|
int __stdcall GetDefaultPrinter(PSTR pPrinter, PINT pnPrinterSize)
|
|
{
|
|
int nStatus = SUCCESS;
|
|
HKEY hkArray[sizeof szSubKeys / MAX_SUBKEYSTRSIZE + 1];
|
|
int nOpenKeys = 0;
|
|
int i;
|
|
DWORD dwType;
|
|
long lReturn = 0;
|
|
PSTR pTmpStr = NULL;
|
|
int nNumNameChars = 0;
|
|
PSTR pCommaAddr = NULL;
|
|
|
|
if (IsBadWritePtr(pPrinter, *pnPrinterSize))
|
|
{
|
|
nStatus = PrtError(OIPRT_INTERNALERROR);
|
|
goto Exit;
|
|
}
|
|
|
|
for (i = 0; i < sizeof hkArray / sizeof (HKEY); i++)
|
|
hkArray[i] = 0;
|
|
|
|
hkArray[0] = HKEY_BASEKEY;
|
|
|
|
for (nOpenKeys = 0; nOpenKeys < sizeof szSubKeys / MAX_SUBKEYSTRSIZE;
|
|
nOpenKeys++)
|
|
{
|
|
if ((lReturn = RegOpenKeyEx(hkArray[nOpenKeys], szSubKeys[nOpenKeys],
|
|
0, KEY_ALL_ACCESS, &hkArray[nOpenKeys + 1])) != ERROR_SUCCESS)
|
|
{
|
|
nStatus = PrtError(OIPRT_NODEFAULTPRINTER);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
if ((lReturn = RegQueryValueEx(hkArray[nOpenKeys], VALUENAME, 0,
|
|
&dwType, pPrinter, pnPrinterSize)) != ERROR_SUCCESS)
|
|
{
|
|
nStatus = PrtError(OIPRT_NODEFAULTPRINTER);
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
if ((pCommaAddr = strchr(pPrinter, ',')) != NULL)
|
|
{
|
|
nNumNameChars = pCommaAddr - pPrinter;
|
|
|
|
if (!(pTmpStr = malloc(nNumNameChars + 1)))
|
|
{
|
|
nStatus = PrtError(OIPRT_OUTOFMEMORY);
|
|
goto Exit;
|
|
}
|
|
|
|
memset(pTmpStr, 0, nNumNameChars + 1);
|
|
strncpy(pTmpStr, pPrinter, nNumNameChars);
|
|
strcpy(pPrinter, pTmpStr);
|
|
}
|
|
else
|
|
{
|
|
nStatus = PrtError(OIPRT_NODEFAULTPRINTER);
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
Exit:
|
|
for (i = nOpenKeys; i > 0; i--)
|
|
{
|
|
RegCloseKey(hkArray[i]);
|
|
hkArray[i] = 0;
|
|
}
|
|
|
|
if (pTmpStr)
|
|
free(pTmpStr);
|
|
|
|
return nStatus;
|
|
}
|