456 lines
8.6 KiB
C
456 lines
8.6 KiB
C
/*++
|
||
|
||
Copyright (c) 1996 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
faxui.c
|
||
|
||
Abstract:
|
||
|
||
Common routines for fax driver user interface
|
||
|
||
Environment:
|
||
|
||
Fax driver user interface
|
||
|
||
Revision History:
|
||
|
||
01/09/96 -davidx-
|
||
Created it.
|
||
|
||
mm/dd/yy -author-
|
||
description
|
||
|
||
--*/
|
||
|
||
#include "faxui.h"
|
||
#include "forms.h"
|
||
#include <shlobj.h>
|
||
|
||
|
||
CRITICAL_SECTION faxuiSemaphore; // Semaphore for protecting critical sections
|
||
HANDLE ghInstance; // DLL instance handle
|
||
PUSERMEM gUserMemList; // Global list of user mode memory structures
|
||
INT _debugLevel = 1; // for debuggping purposes
|
||
|
||
PVOID
|
||
PrMemAlloc(
|
||
DWORD size
|
||
)
|
||
{
|
||
return (PVOID)LocalAlloc(LPTR, size);
|
||
}
|
||
|
||
VOID
|
||
PrMemFree(
|
||
PVOID ptr
|
||
)
|
||
{
|
||
if (ptr) {
|
||
LocalFree((HLOCAL) ptr);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
DllEntryPoint(
|
||
HANDLE hModule,
|
||
ULONG ulReason,
|
||
PCONTEXT pContext
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
DLL initialization procedure.
|
||
|
||
Arguments:
|
||
|
||
hModule - DLL instance handle
|
||
ulReason - Reason for the call
|
||
pContext - Pointer to context (not used by us)
|
||
|
||
Return Value:
|
||
|
||
TRUE if DLL is initialized successfully, FALSE otherwise.
|
||
|
||
--*/
|
||
|
||
{
|
||
WCHAR DllName[MAX_PATH];
|
||
INITCOMMONCONTROLSEX CommonControlsEx = {sizeof(INITCOMMONCONTROLSEX),
|
||
ICC_WIN95_CLASSES|ICC_DATE_CLASSES };
|
||
|
||
switch (ulReason) {
|
||
|
||
case DLL_PROCESS_ATTACH:
|
||
|
||
//
|
||
// Keep our driver UI dll always loaded in memory
|
||
//
|
||
|
||
if (! GetModuleFileName(hModule, DllName, MAX_PATH) ||
|
||
! LoadLibrary(DllName))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
ghInstance = hModule;
|
||
gUserMemList = NULL;
|
||
|
||
HeapInitialize( NULL, PrMemAlloc, PrMemFree, HEAPINIT_NO_VALIDATION | HEAPINIT_NO_STRINGS );
|
||
|
||
InitializeCriticalSection(&faxuiSemaphore);
|
||
InitCommonControlsEx(&CommonControlsEx);
|
||
break;
|
||
|
||
case DLL_PROCESS_DETACH:
|
||
|
||
while (gUserMemList != NULL) {
|
||
|
||
PUSERMEM pUserMem;
|
||
|
||
pUserMem = gUserMemList;
|
||
gUserMemList = gUserMemList->pNext;
|
||
FreePDEVUserMem(pUserMem);
|
||
}
|
||
|
||
DeleteCriticalSection(&faxuiSemaphore);
|
||
break;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
|
||
LONG
|
||
CallCompstui(
|
||
HWND hwndOwner,
|
||
PFNPROPSHEETUI pfnPropSheetUI,
|
||
LPARAM lParam,
|
||
PDWORD pResult
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Calling common UI DLL entry point dynamically
|
||
|
||
Arguments:
|
||
|
||
hwndOwner, pfnPropSheetUI, lParam, pResult - Parameters passed to common UI DLL
|
||
|
||
Return Value:
|
||
|
||
Return value from common UI library
|
||
|
||
--*/
|
||
|
||
{
|
||
HINSTANCE hInstCompstui;
|
||
FARPROC pProc;
|
||
LONG Result = ERR_CPSUI_GETLASTERROR;
|
||
|
||
//
|
||
// Only need to call the ANSI version of LoadLibrary
|
||
//
|
||
|
||
static const CHAR szCompstui[] = "compstui.dll";
|
||
static const CHAR szCommonPropSheetUI[] = "CommonPropertySheetUIW";
|
||
|
||
if ((hInstCompstui = LoadLibraryA(szCompstui)) &&
|
||
(pProc = GetProcAddress(hInstCompstui, szCommonPropSheetUI)))
|
||
{
|
||
Result = (LONG)(*pProc)(hwndOwner, pfnPropSheetUI, lParam, pResult);
|
||
}
|
||
|
||
if (hInstCompstui)
|
||
FreeLibrary(hInstCompstui);
|
||
|
||
return Result;
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
GetCombinedDevmode(
|
||
PDRVDEVMODE pdmOut,
|
||
PDEVMODE pdmIn,
|
||
HANDLE hPrinter,
|
||
PPRINTER_INFO_2 pPrinterInfo2,
|
||
BOOL publicOnly
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Combine DEVMODE information:
|
||
start with the driver default
|
||
then merge with the system default
|
||
then merge with the user default
|
||
finally merge with the input devmode
|
||
|
||
Arguments:
|
||
|
||
pdmOut - Pointer to the output devmode buffer
|
||
pdmIn - Pointer to an input devmode
|
||
hPrinter - Handle to a printer object
|
||
pPrinterInfo2 - Point to a PRINTER_INFO_2 structure or NULL
|
||
publicOnly - Only merge the public portion of the devmode
|
||
|
||
Return Value:
|
||
|
||
TRUE
|
||
|
||
--*/
|
||
|
||
{
|
||
PPRINTER_INFO_2 pAlloced = NULL;
|
||
PDEVMODE pdmUser;
|
||
|
||
//
|
||
// Get a PRINTER_INFO_2 structure if one is not provided
|
||
//
|
||
|
||
if (! pPrinterInfo2)
|
||
pPrinterInfo2 = pAlloced = MyGetPrinter(hPrinter, 2);
|
||
|
||
//
|
||
// Start with driver default devmode
|
||
//
|
||
|
||
if (! publicOnly) {
|
||
|
||
DriverDefaultDevmode(pdmOut,
|
||
pPrinterInfo2 ? pPrinterInfo2->pPrinterName : NULL,
|
||
hPrinter);
|
||
}
|
||
|
||
//
|
||
// Merge with the system default devmode and user default devmode
|
||
//
|
||
|
||
if (pPrinterInfo2) {
|
||
|
||
#if 0
|
||
|
||
//
|
||
// Since we have per-user devmode and there is no way to
|
||
// change the printer's default devmode, there is no need
|
||
// to merge it here.
|
||
//
|
||
|
||
if (! MergeDevmode(pdmOut, pPrinterInfo2->pDevMode, publicOnly))
|
||
Error(("Invalid system default devmode\n"));
|
||
|
||
#endif
|
||
|
||
if (pdmUser = GetPerUserDevmode(pPrinterInfo2->pPrinterName)) {
|
||
|
||
if (! MergeDevmode(pdmOut, pdmUser, publicOnly))
|
||
Error(("Invalid user devmode\n"));
|
||
|
||
MemFree(pdmUser);
|
||
}
|
||
}
|
||
|
||
MemFree(pAlloced);
|
||
|
||
//
|
||
// Merge with the input devmode
|
||
//
|
||
|
||
if (! MergeDevmode(pdmOut, pdmIn, publicOnly))
|
||
Error(("Invalid input devmode\n"));
|
||
}
|
||
|
||
|
||
|
||
PUIDATA
|
||
FillUiData(
|
||
HANDLE hPrinter,
|
||
PDEVMODE pdmInput
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Fill in the data structure used by the fax driver user interface
|
||
|
||
Arguments:
|
||
|
||
hPrinter - Handle to the printer
|
||
pdmInput - Pointer to input devmode, NULL if there is none
|
||
|
||
Return Value:
|
||
|
||
Pointer to UIDATA structure, NULL if error.
|
||
|
||
--*/
|
||
|
||
{
|
||
PRINTER_INFO_2 *pPrinterInfo2 = NULL;
|
||
PUIDATA pUiData = NULL;
|
||
HANDLE hheap = NULL;
|
||
|
||
//
|
||
// Create a heap to manage memory
|
||
// Allocate memory to hold UIDATA structure
|
||
// Get printer info from the spooler
|
||
// Copy the driver name
|
||
//
|
||
|
||
if (! (hheap = HeapCreate(0, 4096, 0)) ||
|
||
! (pUiData = HeapAlloc(hheap, HEAP_ZERO_MEMORY, sizeof(UIDATA))) ||
|
||
! (pPrinterInfo2 = MyGetPrinter(hPrinter, 2)))
|
||
{
|
||
if (hheap)
|
||
HeapDestroy(hheap);
|
||
|
||
MemFree(pPrinterInfo2);
|
||
return NULL;
|
||
}
|
||
|
||
pUiData->startSign = pUiData->endSign = pUiData;
|
||
pUiData->hPrinter = hPrinter;
|
||
pUiData->hheap = hheap;
|
||
|
||
//
|
||
// Combine various devmode information
|
||
//
|
||
|
||
GetCombinedDevmode(&pUiData->devmode, pdmInput, hPrinter, pPrinterInfo2, FALSE);
|
||
|
||
//
|
||
// Validate the form requested by the input devmode
|
||
//
|
||
|
||
if (! ValidDevmodeForm(hPrinter, &pUiData->devmode.dmPublic, NULL))
|
||
Error(("Invalid form specification\n"));
|
||
|
||
MemFree(pPrinterInfo2);
|
||
return pUiData;
|
||
}
|
||
|
||
|
||
|
||
INT
|
||
DisplayMessageDialog(
|
||
HWND hwndParent,
|
||
UINT type,
|
||
INT titleStrId,
|
||
INT formatStrId,
|
||
...
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Display a message dialog box
|
||
|
||
Arguments:
|
||
|
||
hwndParent - Specifies a parent window for the error message dialog
|
||
titleStrId - Title string (could be a string resource ID)
|
||
formatStrId - Message format string (could be a string resource ID)
|
||
...
|
||
|
||
Return Value:
|
||
|
||
NONE
|
||
|
||
--*/
|
||
|
||
{
|
||
LPTSTR pTitle, pFormat, pMessage;
|
||
INT result;
|
||
va_list ap;
|
||
|
||
pTitle = pFormat = pMessage = NULL;
|
||
|
||
if ((pTitle = AllocStringZ(MAX_TITLE_LEN)) &&
|
||
(pFormat = AllocStringZ(MAX_STRING_LEN)) &&
|
||
(pMessage = AllocStringZ(MAX_MESSAGE_LEN)))
|
||
{
|
||
//
|
||
// Load dialog box title string resource
|
||
//
|
||
|
||
if (titleStrId == 0)
|
||
titleStrId = IDS_ERROR_DLGTITLE;
|
||
|
||
LoadString(ghInstance, titleStrId, pTitle, MAX_TITLE_LEN);
|
||
|
||
//
|
||
// Load message format string resource
|
||
//
|
||
|
||
LoadString(ghInstance, formatStrId, pFormat, MAX_STRING_LEN);
|
||
|
||
//
|
||
// Compose the message string
|
||
//
|
||
|
||
va_start(ap, formatStrId);
|
||
wvsprintf(pMessage, pFormat, ap);
|
||
va_end(ap);
|
||
|
||
//
|
||
// Display the message box
|
||
//
|
||
|
||
if (type == 0)
|
||
type = MB_OK | MB_ICONERROR;
|
||
|
||
result = MessageBox(hwndParent, pMessage, pTitle, type);
|
||
|
||
} else {
|
||
|
||
MessageBeep(MB_ICONHAND);
|
||
result = 0;
|
||
}
|
||
|
||
MemFree(pTitle);
|
||
MemFree(pFormat);
|
||
MemFree(pMessage);
|
||
return result;
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
DevQueryPrintEx(
|
||
PDEVQUERYPRINT_INFO pDQPInfo
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Implementation of DDI entry point DevQueryPrintEx. Even though we don't
|
||
really need this entry point, we must export it so that the spooler
|
||
will load our driver UI.
|
||
|
||
Arguments:
|
||
|
||
pDQPInfo - Points to a DEVQUERYPRINT_INFO structure
|
||
|
||
Return Value:
|
||
|
||
TRUE if there is no conflicts, FALSE otherwise
|
||
|
||
--*/
|
||
|
||
{
|
||
return TRUE;
|
||
}
|
||
|