793 lines
17 KiB
C
793 lines
17 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1996 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
sendnote.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Utility program to send fax notes
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Windows NT fax driver
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
02/15/96 -davidx-
|
|||
|
Created it.
|
|||
|
|
|||
|
mm/dd/yy -author-
|
|||
|
description
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "sendnote.h"
|
|||
|
#include "tiff.h"
|
|||
|
#include "tifflib.h"
|
|||
|
|
|||
|
#define Align(p, x) (((x) & ((p)-1)) ? (((x) & ~((p)-1)) + p) : (x))
|
|||
|
|
|||
|
//
|
|||
|
// Data structure used to pass parameters to "Select Fax Printer" dialog
|
|||
|
//
|
|||
|
|
|||
|
typedef struct {
|
|||
|
|
|||
|
LPTSTR pPrinterName;
|
|||
|
INT cPrinters;
|
|||
|
PRINTER_INFO_2 *pPrinterInfo2;
|
|||
|
|
|||
|
} DLGPARAM, *PDLGPARAM;
|
|||
|
|
|||
|
//
|
|||
|
// Global instance handle
|
|||
|
//
|
|||
|
|
|||
|
HMODULE ghInstance = NULL;
|
|||
|
INT _debugLevel = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Maximum length of message strings
|
|||
|
//
|
|||
|
|
|||
|
#define MAX_MESSAGE_LEN 256
|
|||
|
|
|||
|
//
|
|||
|
// Maximum length for a printer name
|
|||
|
//
|
|||
|
|
|||
|
#define MAX_PRINTER_NAME MAX_PATH
|
|||
|
|
|||
|
//
|
|||
|
// Window NT fax driver name - currently printer driver name cannot be localized
|
|||
|
// so it shouldn't be put into the string resource.
|
|||
|
//
|
|||
|
|
|||
|
static TCHAR faxDriverName[] = TEXT("Windows NT Fax Driver");
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
InitSelectFaxPrinter(
|
|||
|
HWND hDlg,
|
|||
|
PDLGPARAM pDlgParam
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Initialize the "Select Fax Printer" dialog
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hDlg - Handle to the print setup dialog window
|
|||
|
pDlgParam - Points to print setup dialog parameters
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NONE
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
HWND hwndList;
|
|||
|
INT selIndex, printerIndex;
|
|||
|
|
|||
|
//
|
|||
|
// Insert all fax printers into a listbox. Note that we've already filtered
|
|||
|
// out non-fax printers earlier by setting their pDriverName field to NULL.
|
|||
|
//
|
|||
|
|
|||
|
if (! (hwndList = GetDlgItem(hDlg, IDC_FAXPRINTER_LIST)))
|
|||
|
return;
|
|||
|
|
|||
|
for (printerIndex=0; printerIndex < pDlgParam->cPrinters; printerIndex++) {
|
|||
|
|
|||
|
if (pDlgParam->pPrinterInfo2[printerIndex].pDriverName) {
|
|||
|
|
|||
|
selIndex = (INT)SendMessage(hwndList,
|
|||
|
LB_ADDSTRING,
|
|||
|
0,
|
|||
|
(LPARAM) pDlgParam->pPrinterInfo2[printerIndex].pPrinterName);
|
|||
|
|
|||
|
if (selIndex != LB_ERR) {
|
|||
|
|
|||
|
if (SendMessage(hwndList, LB_SETITEMDATA, selIndex, printerIndex) == LB_ERR)
|
|||
|
SendMessage(hwndList, LB_DELETESTRING, selIndex, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Select the first fax printer in the list by default
|
|||
|
//
|
|||
|
|
|||
|
SendMessage(hwndList, LB_SETCURSEL, 0, 0);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
GetSelectedFaxPrinter(
|
|||
|
HWND hDlg,
|
|||
|
PDLGPARAM pDlgParam
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Remember the name of currently selected fax printer
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hDlg - Handle to the print setup dialog window
|
|||
|
pDlgParam - Points to print setup dialog parameters
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if successful, FALSE otherwise
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
HWND hwndList;
|
|||
|
INT selIndex, printerIndex;
|
|||
|
|
|||
|
//
|
|||
|
// Get current selection index
|
|||
|
//
|
|||
|
|
|||
|
if ((hwndList = GetDlgItem(hDlg, IDC_FAXPRINTER_LIST)) == NULL ||
|
|||
|
(selIndex = (INT)SendMessage(hwndList, LB_GETCURSEL, 0, 0)) == LB_ERR)
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Retrieve the selected printer index
|
|||
|
//
|
|||
|
|
|||
|
printerIndex = (INT)SendMessage(hwndList, LB_GETITEMDATA, selIndex, 0);
|
|||
|
|
|||
|
if (printerIndex < 0 || printerIndex >= pDlgParam->cPrinters)
|
|||
|
return FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// Remember the selected fax printer name
|
|||
|
//
|
|||
|
|
|||
|
_tcsncpy(pDlgParam->pPrinterName,
|
|||
|
pDlgParam->pPrinterInfo2[printerIndex].pPrinterName,
|
|||
|
MAX_PRINTER_NAME);
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
CenterWindowOnScreen(
|
|||
|
HWND hwnd
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Place the specified windows in the center of the screen
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hwnd - Specifies a window to be centered
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NONE
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
HWND hwndDesktop;
|
|||
|
RECT windowRect, screenRect;
|
|||
|
INT windowWidth, windowHeight, screenWidth, screenHeight;
|
|||
|
|
|||
|
//
|
|||
|
// Get screen dimension
|
|||
|
//
|
|||
|
|
|||
|
hwndDesktop = GetDesktopWindow();
|
|||
|
GetWindowRect(hwndDesktop, &screenRect);
|
|||
|
screenWidth = screenRect.right - screenRect.left;
|
|||
|
screenHeight = screenRect.bottom - screenRect.top;
|
|||
|
|
|||
|
//
|
|||
|
// Get window position
|
|||
|
//
|
|||
|
|
|||
|
GetWindowRect(hwnd, &windowRect);
|
|||
|
windowWidth = windowRect.right - windowRect.left;
|
|||
|
windowHeight = windowRect.bottom - windowRect.top;
|
|||
|
|
|||
|
//
|
|||
|
// Center the window on screen
|
|||
|
//
|
|||
|
|
|||
|
MoveWindow(hwnd,
|
|||
|
screenRect.left + (screenWidth - windowWidth) / 2,
|
|||
|
screenRect.top + (screenHeight - windowHeight) / 2,
|
|||
|
windowWidth,
|
|||
|
windowHeight,
|
|||
|
FALSE);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
INT_PTR CALLBACK
|
|||
|
SelectPrinterDlgProc(
|
|||
|
HWND hDlg,
|
|||
|
UINT uMsg,
|
|||
|
WPARAM wParam,
|
|||
|
LPARAM lParam
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Dialog procedure for handling "Select Fax Printer" dialog
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hDlg - Handle to the dialog window
|
|||
|
uMsg, wParam, lParam - Dialog message and message parameters
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Depends on dialog message
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PDLGPARAM pDlgParam;
|
|||
|
|
|||
|
switch (uMsg) {
|
|||
|
|
|||
|
case WM_INITDIALOG:
|
|||
|
|
|||
|
//
|
|||
|
// Remember the pointer to DLGPARAM structure
|
|||
|
//
|
|||
|
|
|||
|
pDlgParam = (PDLGPARAM) lParam;
|
|||
|
Assert(pDlgParam != NULL);
|
|||
|
SetWindowLongPtr(hDlg, DWLP_USER, lParam);
|
|||
|
|
|||
|
CenterWindowOnScreen(hDlg);
|
|||
|
InitSelectFaxPrinter(hDlg, pDlgParam);
|
|||
|
return TRUE;
|
|||
|
|
|||
|
case WM_COMMAND:
|
|||
|
|
|||
|
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
|
|||
|
|
|||
|
case IDC_FAXPRINTER_LIST:
|
|||
|
|
|||
|
if (GET_WM_COMMAND_CMD(wParam, lParam) != LBN_DBLCLK)
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// Fall through - double-clicking in the fax printer list
|
|||
|
// is treated the same as clicking OK button
|
|||
|
//
|
|||
|
|
|||
|
case IDOK:
|
|||
|
|
|||
|
//
|
|||
|
// User pressed OK to proceed
|
|||
|
//
|
|||
|
|
|||
|
pDlgParam = (PDLGPARAM) GetWindowLongPtr(hDlg, DWLP_USER);
|
|||
|
Assert(pDlgParam != NULL);
|
|||
|
|
|||
|
if (GetSelectedFaxPrinter(hDlg, pDlgParam))
|
|||
|
EndDialog(hDlg, IDOK);
|
|||
|
else
|
|||
|
MessageBeep(MB_OK);
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
case IDCANCEL:
|
|||
|
|
|||
|
//
|
|||
|
// User pressed Cancel to dismiss the dialog
|
|||
|
//
|
|||
|
|
|||
|
EndDialog(hDlg, IDCANCEL);
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
DisplayErrorMessage(
|
|||
|
INT errId
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Display an error message dialog
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
errId - Specifies the resource ID of the error message string
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NONE
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
TCHAR errMsg[MAX_MESSAGE_LEN];
|
|||
|
|
|||
|
LoadString(ghInstance, errId, errMsg, MAX_MESSAGE_LEN);
|
|||
|
MessageBox(NULL, errMsg, NULL, MB_OK | MB_ICONERROR);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
SelectFaxPrinter(
|
|||
|
LPTSTR pPrinterName
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Select a fax printer to send note to
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pPrinterName - Points to a buffer for storing selected printer name
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if successful, FALSE if there is an error
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PRINTER_INFO_2 *pPrinterInfo2;
|
|||
|
DWORD index, cPrinters, cFaxPrinters;
|
|||
|
DLGPARAM dlgParam;
|
|||
|
|
|||
|
//
|
|||
|
// Enumerate the list of printers available on the system
|
|||
|
//
|
|||
|
|
|||
|
pPrinterInfo2 = MyEnumPrinters(NULL, 2, &cPrinters, PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS);
|
|||
|
|
|||
|
if (pPrinterInfo2 == NULL || cPrinters == 0) {
|
|||
|
|
|||
|
MemFree(pPrinterInfo2);
|
|||
|
DisplayErrorMessage(IDS_NO_FAX_PRINTER);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Find out how many fax printers there are:
|
|||
|
// case 1: no fax printer at all - display an error message
|
|||
|
// case 2: only one fax printer - use it
|
|||
|
// case 3: more than one fax printer - display a dialog to let user choose one
|
|||
|
//
|
|||
|
|
|||
|
cFaxPrinters = 0;
|
|||
|
|
|||
|
for (index=0; index < cPrinters; index++) {
|
|||
|
|
|||
|
if (_tcscmp(pPrinterInfo2[index].pDriverName, faxDriverName) != EQUAL_STRING)
|
|||
|
pPrinterInfo2[index].pDriverName = NULL;
|
|||
|
else if (cFaxPrinters++ == 0)
|
|||
|
_tcsncpy(pPrinterName, pPrinterInfo2[index].pPrinterName, MAX_PRINTER_NAME);
|
|||
|
}
|
|||
|
|
|||
|
switch (cFaxPrinters) {
|
|||
|
|
|||
|
case 0:
|
|||
|
|
|||
|
//
|
|||
|
// No fax printer is installed - display an error message
|
|||
|
//
|
|||
|
|
|||
|
DisplayErrorMessage(IDS_NO_FAX_PRINTER);
|
|||
|
break;
|
|||
|
|
|||
|
case 1:
|
|||
|
|
|||
|
//
|
|||
|
// Exactly one fax printer is installed - use it
|
|||
|
//
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
//
|
|||
|
// More than one fax printer is available - let use choose one
|
|||
|
//
|
|||
|
|
|||
|
dlgParam.pPrinterInfo2 = pPrinterInfo2;
|
|||
|
dlgParam.cPrinters = cPrinters;
|
|||
|
dlgParam.pPrinterName = pPrinterName;
|
|||
|
|
|||
|
if (DialogBoxParam(ghInstance,
|
|||
|
MAKEINTRESOURCE(IDD_SELECT_FAXPRINTER),
|
|||
|
NULL,
|
|||
|
SelectPrinterDlgProc,
|
|||
|
(LPARAM) &dlgParam) != IDOK)
|
|||
|
{
|
|||
|
cFaxPrinters = 0;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
pPrinterName[MAX_PRINTER_NAME-1] = NUL;
|
|||
|
MemFree(pPrinterInfo2);
|
|||
|
return cFaxPrinters > 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#ifdef FAX_SCAN_ENABLED
|
|||
|
|
|||
|
#if 0
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
PrintTifFile(
|
|||
|
HDC PrinterDC,
|
|||
|
LPWSTR FileName
|
|||
|
)
|
|||
|
{
|
|||
|
BOOL Rval = TRUE;
|
|||
|
HANDLE hFile;
|
|||
|
HANDLE hMap;
|
|||
|
DWORD i,j;
|
|||
|
INT HorzRes;
|
|||
|
INT VertRes;
|
|||
|
BOOL Result = FALSE;
|
|||
|
DWORD VertResFactor = 1;
|
|||
|
PTIFF_HEADER TiffHdr;
|
|||
|
DWORD NextIfdSeekPoint;
|
|||
|
WORD NumDirEntries = 0;
|
|||
|
PTIFF_TAG TiffTags = NULL;
|
|||
|
DWORD ImageWidth = 0;
|
|||
|
DWORD ImageHeight = 0;
|
|||
|
DWORD DataSize = 0;
|
|||
|
DWORD DataOffset = 0;
|
|||
|
DWORD XRes = 0;
|
|||
|
DWORD YRes = 0;
|
|||
|
LPBYTE FileBytes;
|
|||
|
LPBYTE Bitmap;
|
|||
|
LPBYTE dPtr;
|
|||
|
LPBYTE sPtr;
|
|||
|
INT DestWidth;
|
|||
|
INT DestHeight;
|
|||
|
FLOAT ScaleX;
|
|||
|
FLOAT ScaleY;
|
|||
|
FLOAT Scale;
|
|||
|
DWORD LineSize;
|
|||
|
DWORD dontcare;
|
|||
|
PBITMAPINFO SrcBitmapInfo;
|
|||
|
|
|||
|
|
|||
|
SrcBitmapInfo = (PBITMAPINFO) MemAlloc( sizeof(BITMAPINFO) + (sizeof(RGBQUAD)*32) );
|
|||
|
if (SrcBitmapInfo == NULL) {
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
SrcBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|||
|
SrcBitmapInfo->bmiHeader.biWidth = 0;
|
|||
|
SrcBitmapInfo->bmiHeader.biHeight = 0;
|
|||
|
SrcBitmapInfo->bmiHeader.biPlanes = 1;
|
|||
|
SrcBitmapInfo->bmiHeader.biBitCount = 1;
|
|||
|
SrcBitmapInfo->bmiHeader.biCompression = BI_RGB;
|
|||
|
SrcBitmapInfo->bmiHeader.biSizeImage = 0;
|
|||
|
SrcBitmapInfo->bmiHeader.biXPelsPerMeter = 7874;
|
|||
|
SrcBitmapInfo->bmiHeader.biYPelsPerMeter = 7874;
|
|||
|
SrcBitmapInfo->bmiHeader.biClrUsed = 0;
|
|||
|
SrcBitmapInfo->bmiHeader.biClrImportant = 0;
|
|||
|
|
|||
|
SrcBitmapInfo->bmiColors[0].rgbBlue = 255;
|
|||
|
SrcBitmapInfo->bmiColors[0].rgbGreen = 255;
|
|||
|
SrcBitmapInfo->bmiColors[0].rgbRed = 255;
|
|||
|
SrcBitmapInfo->bmiColors[0].rgbReserved = 0;
|
|||
|
SrcBitmapInfo->bmiColors[1].rgbBlue = 0;
|
|||
|
SrcBitmapInfo->bmiColors[1].rgbGreen = 0;
|
|||
|
SrcBitmapInfo->bmiColors[1].rgbRed = 0;
|
|||
|
SrcBitmapInfo->bmiColors[1].rgbReserved = 0;
|
|||
|
|
|||
|
HorzRes = GetDeviceCaps( PrinterDC, HORZRES );
|
|||
|
VertRes = GetDeviceCaps( PrinterDC, VERTRES );
|
|||
|
|
|||
|
hFile = CreateFile(
|
|||
|
FileName,
|
|||
|
GENERIC_READ,
|
|||
|
0,
|
|||
|
NULL,
|
|||
|
OPEN_EXISTING,
|
|||
|
0,
|
|||
|
NULL
|
|||
|
);
|
|||
|
if (hFile == INVALID_HANDLE_VALUE) {
|
|||
|
Rval = FALSE;
|
|||
|
goto exit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// make sure the file is non-zero length
|
|||
|
//
|
|||
|
if (GetFileSize(hFile,&dontcare) == 0) {
|
|||
|
Rval = FALSE;
|
|||
|
goto exit;
|
|||
|
}
|
|||
|
|
|||
|
hMap = CreateFileMapping(
|
|||
|
hFile,
|
|||
|
NULL,
|
|||
|
PAGE_READONLY,
|
|||
|
0,
|
|||
|
0,
|
|||
|
NULL
|
|||
|
);
|
|||
|
if (hMap == NULL) {
|
|||
|
Rval = FALSE;
|
|||
|
goto exit;
|
|||
|
}
|
|||
|
|
|||
|
FileBytes = MapViewOfFile(
|
|||
|
hMap,
|
|||
|
FILE_MAP_READ,
|
|||
|
0,
|
|||
|
0,
|
|||
|
0
|
|||
|
);
|
|||
|
if (FileBytes == NULL) {
|
|||
|
Rval = FALSE;
|
|||
|
goto exit;
|
|||
|
}
|
|||
|
|
|||
|
TiffHdr = (PTIFF_HEADER) FileBytes;
|
|||
|
|
|||
|
NextIfdSeekPoint = TiffHdr->IFDOffset;
|
|||
|
while (NextIfdSeekPoint) {
|
|||
|
NumDirEntries = *(LPWORD)(FileBytes+NextIfdSeekPoint);
|
|||
|
TiffTags = (PTIFF_TAG)(FileBytes+NextIfdSeekPoint+sizeof(WORD));
|
|||
|
NextIfdSeekPoint = *(LPDWORD)(TiffTags+NumDirEntries);
|
|||
|
for (i=0; i<NumDirEntries; i++) {
|
|||
|
switch (TiffTags[i].TagId) {
|
|||
|
case TIFFTAG_IMAGEWIDTH:
|
|||
|
ImageWidth = TiffTags[i].DataOffset;
|
|||
|
break;
|
|||
|
|
|||
|
case TIFFTAG_IMAGELENGTH:
|
|||
|
ImageHeight = TiffTags[i].DataOffset;
|
|||
|
break;
|
|||
|
|
|||
|
case TIFFTAG_STRIPBYTECOUNTS:
|
|||
|
DataSize = TiffTags[i].DataOffset;
|
|||
|
break;
|
|||
|
|
|||
|
case TIFFTAG_STRIPOFFSETS:
|
|||
|
DataOffset = TiffTags[i].DataOffset;
|
|||
|
break;
|
|||
|
|
|||
|
case TIFFTAG_XRESOLUTION:
|
|||
|
XRes = *(LPDWORD)(FileBytes+TiffTags[i].DataOffset);
|
|||
|
break;
|
|||
|
|
|||
|
case TIFFTAG_YRESOLUTION:
|
|||
|
YRes = *(LPDWORD)(FileBytes+TiffTags[i].DataOffset);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (YRes <= 100) {
|
|||
|
SrcBitmapInfo->bmiHeader.biYPelsPerMeter /= 2;
|
|||
|
VertResFactor = 2;
|
|||
|
}
|
|||
|
LineSize = ImageWidth / 8;
|
|||
|
LineSize += (ImageWidth % 8) ? 1 : 0;
|
|||
|
Bitmap = (LPBYTE) VirtualAlloc( NULL, DataSize+(ImageHeight*sizeof(DWORD)), MEM_COMMIT, PAGE_READWRITE );
|
|||
|
if (Bitmap) {
|
|||
|
sPtr = FileBytes + DataOffset;
|
|||
|
dPtr = Bitmap;
|
|||
|
for (j=0; j<ImageHeight; j++) {
|
|||
|
CopyMemory( dPtr, sPtr, LineSize );
|
|||
|
sPtr += LineSize;
|
|||
|
dPtr = (LPBYTE) Align( 4, (ULONG_PTR)dPtr+LineSize );
|
|||
|
}
|
|||
|
StartPage( PrinterDC );
|
|||
|
ScaleX = (FLOAT) ImageWidth / (FLOAT) HorzRes;
|
|||
|
ScaleY = ((FLOAT) ImageHeight * VertResFactor) / (FLOAT) VertRes;
|
|||
|
Scale = ScaleX > ScaleY ? ScaleX : ScaleY;
|
|||
|
DestWidth = (int) ((FLOAT) ImageWidth / Scale);
|
|||
|
DestHeight = (int) (((FLOAT) ImageHeight * VertResFactor) / Scale);
|
|||
|
SrcBitmapInfo->bmiHeader.biWidth = ImageWidth;
|
|||
|
SrcBitmapInfo->bmiHeader.biHeight = - (INT) ImageHeight;
|
|||
|
StretchDIBits(
|
|||
|
PrinterDC,
|
|||
|
0,
|
|||
|
0,
|
|||
|
DestWidth,
|
|||
|
DestHeight,
|
|||
|
0,
|
|||
|
0,
|
|||
|
ImageWidth,
|
|||
|
ImageHeight,
|
|||
|
Bitmap,
|
|||
|
(BITMAPINFO *) &SrcBitmapInfo,
|
|||
|
DIB_RGB_COLORS,
|
|||
|
SRCCOPY
|
|||
|
);
|
|||
|
EndPage( PrinterDC );
|
|||
|
VirtualFree( Bitmap, 0, MEM_RELEASE );
|
|||
|
} else {
|
|||
|
Rval = FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
exit:
|
|||
|
if (FileBytes) {
|
|||
|
UnmapViewOfFile( FileBytes );
|
|||
|
}
|
|||
|
if (hMap) {
|
|||
|
CloseHandle( hMap );
|
|||
|
}
|
|||
|
if (hFile) {
|
|||
|
CloseHandle( hFile );
|
|||
|
}
|
|||
|
if (SrcBitmapInfo) {
|
|||
|
MemFree( SrcBitmapInfo );
|
|||
|
}
|
|||
|
|
|||
|
return Rval;
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
INT
|
|||
|
wWinMain(
|
|||
|
HINSTANCE hInstance,
|
|||
|
HINSTANCE hPrevInstance,
|
|||
|
LPTSTR lpCmdLine,
|
|||
|
INT nCmdShow
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Application entry point
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hInstance - Identifies the current instance of the application
|
|||
|
hPrevInstance - Identifies the previous instance of the application
|
|||
|
lpCmdLine - Specifies the command line for the application.
|
|||
|
nCmdShow - Specifies how the window is to be shown
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
0
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
TCHAR printerName[MAX_PRINTER_NAME];
|
|||
|
HDC hdc;
|
|||
|
TCHAR sendNote[100];
|
|||
|
DOCINFO docInfo = {
|
|||
|
|
|||
|
sizeof(DOCINFO),
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
0,
|
|||
|
};
|
|||
|
|
|||
|
ghInstance = hInstance;
|
|||
|
sendNote[0] = TEXT(' ');
|
|||
|
LoadString( ghInstance, IDS_SENDNOTE, sendNote, sizeof(sendNote)/sizeof(TCHAR) );
|
|||
|
docInfo.lpszDocName = sendNote ;
|
|||
|
|
|||
|
//
|
|||
|
// Check if a printer name is specified on the command line
|
|||
|
//
|
|||
|
|
|||
|
ZeroMemory(printerName, sizeof(printerName));
|
|||
|
|
|||
|
if (lpCmdLine) {
|
|||
|
|
|||
|
_tcsncpy(printerName, lpCmdLine, MAX_PRINTER_NAME);
|
|||
|
printerName[MAX_PRINTER_NAME-1] = NUL;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Select a fax printer to send note to if necessary
|
|||
|
//
|
|||
|
|
|||
|
if (IsEmptyString(printerName) && !SelectFaxPrinter(printerName))
|
|||
|
return 0;
|
|||
|
|
|||
|
Verbose(("Send note to fax printer: %ws\n", printerName));
|
|||
|
|
|||
|
//
|
|||
|
// Set an environment variable so that the driver knows
|
|||
|
// the current application is "Send Note" utility.
|
|||
|
//
|
|||
|
|
|||
|
SetEnvironmentVariable(TEXT("NTFaxSendNote"), TEXT("1"));
|
|||
|
|
|||
|
//
|
|||
|
// Create a printer DC and print an empty job
|
|||
|
//
|
|||
|
|
|||
|
if (! (hdc = CreateDC(NULL, printerName, NULL, NULL))) {
|
|||
|
|
|||
|
DisplayErrorMessage(IDS_CREATEDC_FAILED);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
if (StartDoc(hdc, &docInfo) > 0) {
|
|||
|
#ifdef FAX_SCAN_ENABLED
|
|||
|
TCHAR FileName[MAX_PATH];
|
|||
|
if (GetEnvironmentVariable( TEXT("ScanTifName"), FileName, sizeof(FileName)/sizeof(TCHAR) )) {
|
|||
|
PrintTiffFile( hdc, FileName );
|
|||
|
DeleteFile( FileName );
|
|||
|
}
|
|||
|
#endif
|
|||
|
EndDoc(hdc);
|
|||
|
}
|
|||
|
|
|||
|
DeleteDC(hdc);
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|