windows-nt/Source/XPSP1/NT/printscan/fax/print/faxprint/sendnote/sendnote.c
2020-09-26 16:20:57 +08:00

793 lines
17 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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;
}