Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1181 lines
25 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
All rights reserved.
Module Name:
F:\nt\private\windows\spooler\printui.pri\jobprop.cxx
Abstract:
Job Properties
Author:
Steve Kiraly (SteveKi) 10/19/95
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
#include "time.hxx"
#include "docdata.hxx"
#include "propmgr.hxx"
#include "docprop.hxx"
/*++
Routine Name:
vDocPropSelections
Routine Description:
Displays Document property sheets for multiple selections.
Arguments:
TSelection - pointer to a list of document selections.
Return Value:
Nothing.
--*/
VOID
vDocumentPropSelections(
IN HWND hWnd,
IN LPCTSTR pszPrinterName,
IN TSelection *pSelection
)
{
//
// Get the selection information. We are in a loop to
// handle the selection of multiple jobs.
//
for( UINT i = 0; i < pSelection->_cSelected; ++i ){
//
// Display the document property pages.
//
vDocumentPropPages(
hWnd,
pszPrinterName,
pSelection->_pid[i],
SW_SHOWNORMAL,
0 );
}
}
/*++
Routine Description:
This function opens the property sheet of specified document.
We can't guarentee that this propset will perform all lengthy
operations in a worker thread (we synchronously call things like
ConfigurePort). Therefore, we spawn off a separate thread to
handle document properties.
Arguments:
hWnd - Specifies the parent window (optional).
pszPrinter - Specifies the printer name
nCmdShow - Initial show state
lParam - May spcify a sheet specifc index to directly open.
Return Value:
--*/
VOID
vDocumentPropPages(
IN HWND hWnd,
IN LPCTSTR pszPrinterName,
IN IDENT JobId,
IN INT iCmdShow,
IN LPARAM lParam
)
{
HANDLE hThread;
//
// Create the document specific data
//
TDocumentData* pDocumentData = new TDocumentData( pszPrinterName,
JobId,
iCmdShow,
lParam );
//
// If errors were encountered creating document data.
//
if( !VALID_PTR( pDocumentData )){
goto Fail;
}
//
// Create the thread which handles the UI. vPrinterPropPages adopts
// pPrinterData, therefore only on thread creation failure do we
// releae the document data back to the heap.
//
DWORD dwIgnore;
hThread = CreateThread( NULL,
0,
(LPTHREAD_START_ROUTINE)iDocumentPropPagesProc,
pDocumentData,
0,
&dwIgnore );
//
// Check thread creation.
//
if( !hThread ){
//
// Display error message, and release document data.
//
vShowResourceError( hWnd );
delete pDocumentData;
} else {
CloseHandle( hThread );
}
return;
Fail:
//
// Display the error message.
//
iMessage( hWnd,
IDS_ERR_DOC_JOB_PROPERTY_TITLE,
IDS_ERR_DOC_JOB_PROPERTY_JOB_NA,
MB_OK|MB_ICONSTOP,
kMsgGetLastError,
NULL );
delete pDocumentData;
}
/*++
Routine Name:
iDocumentPropPagesProc
Routine Description:
This is the routine called by the create thread call to display the
document property sheets.
Arguments:
pDocumentData - Pointer to the document data needed for all property sheets.
Return Value:
TRUE - if the property sheets were displayed.
FALSE - error creating and displaying property sheets.
--*/
INT
iDocumentPropPagesProc(
IN TDocumentData *pDocumentData ADOPT
)
{
DBGMSG( DBG_TRACE, ( "iDocumentPropPagesProc\n") );
BOOL bStatus;
bStatus = pDocumentData->bRegisterWindow( PRINTER_PIDL_TYPE_JOBID |
pDocumentData->JobId( ));
if( bStatus ){
//
// Check if the window is already present. If it is, then
// exit immediately.
//
if( !pDocumentData->hwnd( )){
delete pDocumentData;
return 0;
}
bStatus = pDocumentData->bLoad();
}
if( !bStatus ){
iMessage( pDocumentData->hwnd(),
IDS_ERR_DOC_JOB_PROPERTY_TITLE,
IDS_ERR_DOC_JOB_PROPERTY_JOB_NA,
MB_OK|MB_ICONSTOP|MB_SETFOREGROUND,
kMsgGetLastError,
NULL );
delete pDocumentData;
return 0;
}
//
// Create the ducument property sheet windows.
//
TDocumentWindows DocumentWindows( pDocumentData );
//
// Were the document windows create
//
if( !VALID_OBJ( DocumentWindows ) ){
vShowResourceError( pDocumentData->hwnd() );
bStatus = FALSE;
}
//
// Display the property pages.
//
if( bStatus ){
if( !DocumentWindows.bDisplayPages( pDocumentData->hwnd() ) ){
vShowResourceError( pDocumentData->hwnd() );
bStatus = FALSE;
}
}
//
// If there was an error saving the document data.
//
if( !pDocumentData->bErrorSaving() ){
//
// Display the error message.
//
iMessage( pDocumentData->hwnd(),
IDS_ERR_DOC_JOB_PROPERTY_TITLE,
pDocumentData->iErrorMsgId(),
MB_OK|MB_ICONSTOP|MB_SETFOREGROUND,
kMsgNone,
NULL );
bStatus = FALSE;
}
//
// Ensure we release the document data.
// We have adopted pPrinterData, so we must free it.
//
delete pDocumentData;
return bStatus;
}
/********************************************************************
Document Prop Base Class
********************************************************************/
/*++
Routine Name:
TDocumentProp
Routine Description:
Initialized the document property sheet base class
Arguments:
pDocumentData - Pointer to the document data needed for all property sheets.
Return Value:
None.
--*/
TDocumentProp::
TDocumentProp(
TDocumentData* pDocumentData
) : _pDocumentData( pDocumentData ),
_bApplyData( FALSE )
{
}
/*++
Routine Name:
~TDocumentProp
Routine Description:
Base class desctuctor.
Arguments:
None.
Return Value:
Nothing.
--*/
TDocumentProp::
~TDocumentProp(
)
{
}
/*++
Routine Name:
bHandleMessage
Routine Description:
Base class message handler. This routine is called by
derived classes who do not want to handle the message.
Arguments:
uMsg - Windows message
wParam - Word parameter
lParam - Long parameter
Return Value:
TRUE if message was handled, FALSE if message not handled.
--*/
BOOL
TDocumentProp::
bHandleMessage(
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam
)
{
BOOL bStatus = FALSE;
UNREFERENCED_PARAMETER( wParam );
switch( uMsg ){
//
// Set the values on the UI.
//
case WM_INITDIALOG:
bStatus = bSetUI();
break;
//
// Handle help and context help.
//
case WM_HELP:
case WM_CONTEXTMENU:
bStatus = PrintUIHelp( uMsg, _hDlg, wParam, lParam );
break;
//
// Save the data.
//
case WM_DESTROY:
bStatus = ( _bApplyData ) ? bSaveUI() : FALSE;
break;
case WM_NOTIFY:
switch( ((LPNMHDR)lParam)->code ){
//
// User switched to the next page.
//
case PSN_KILLACTIVE:
bStatus = bReadUI();
vSetDlgMsgResult( !bStatus ? TRUE : FALSE );
break;
//
// User chiose the apply button.
//
case PSN_APPLY:
_bApplyData = TRUE;
break;
//
// Indicate the data is to be applied when dismissed.
//
case PSN_QUERYCANCEL:
_bApplyData = FALSE;
break;
}
break;
}
return bStatus;
}
/********************************************************************
General Document Property Sheet.
********************************************************************/
/*++
Routine Name:
TDocumentGeneral
Routine Description:
Document property sheet derived class.
Arguments:
None.
Return Value:
Nothing.
--*/
TDocumentGeneral::
TDocumentGeneral(
IN TDocumentData* pDocumentData
) : TDocumentProp( pDocumentData )
{
}
/*++
Routine Name:
~TDocumentGeneral
Routine Description:
Document derived class destructor.
Arguments:
None.
Return Value:
Nothing.
--*/
TDocumentGeneral::
~TDocumentGeneral(
)
{
}
/*++
Routine Name:
bValid
Routine Description:
Document property sheet derived class valid object indicator.
Arguments:
None.
Return Value:
Returns the status of the base class.
--*/
BOOL
TDocumentGeneral::
bValid(
VOID
)
{
return TDocumentProp::bValid();
}
/*++
Routine Name:
bSetUI
Routine Description:
Loads the property sheet dialog with the document data
information.
Arguments:
None.
Return Value:
TRUE if data loaded successfully, FALSE if error occurred.
--*/
BOOL
TDocumentGeneral::
bSetUI(
VOID
)
{
//
// Get the flag if always availble.
//
BOOL bAlways = ( _pDocumentData->pJobInfo()->StartTime ==
_pDocumentData->pJobInfo()->UntilTime );
//
// Load and init the start and until time controls.
//
if( !_StartTime.bLoad( _hDlg,
IDC_DOC_JOB_START_FRAME,
IDC_DOC_JOB_START_HOUR,
IDC_DOC_JOB_START_MIN,
IDC_NONE, // IDC_DOC_JOB_START_SEC,
IDC_DOC_JOB_START_SEP1,
IDC_NONE, // IDC_DOC_JOB_START_SEP2,
IDC_DOC_JOB_START_PREFIX,
IDC_DOC_JOB_START_SPIN,
_pDocumentData->bAdministrator( )) ||
!_UntilTime.bLoad( _hDlg,
IDC_DOC_JOB_UNTIL_FRAME,
IDC_DOC_JOB_UNTIL_HOUR,
IDC_DOC_JOB_UNTIL_MIN,
IDC_NONE, // IDC_DOC_JOB_UNTIL_SEC,
IDC_DOC_JOB_UNTIL_SEP1,
IDC_NONE, // IDC_DOC_JOB_UNTIL_SEP2,
IDC_DOC_JOB_UNTIL_PREFIX,
IDC_DOC_JOB_UNTIL_SPIN,
_pDocumentData->bAdministrator( ))){
DBGMSG( DBG_ERROR, ( "TDocumentGeneral::bLoad: Time initialization failed %d\n", GetLastError( )));
return FALSE;
} else {
//
// Convert from minutes to system time.
//
SYSTEMTIME StartTime;
DWORD dwLocalStartTime;
ZeroMemory( &StartTime, sizeof( StartTime ));
if( !bAlways )
dwLocalStartTime = SystemTimeToLocalTime( _pDocumentData->pJobInfo()->StartTime );
else
dwLocalStartTime = 0;
StartTime.wHour = (WORD)(dwLocalStartTime / 60);
StartTime.wMinute = (WORD)(dwLocalStartTime % 60);
//
// Convert from minutes to system time.
//
SYSTEMTIME UntilTime;
DWORD dwLocalUntilTime;
ZeroMemory( &UntilTime, sizeof( UntilTime ));
if( !bAlways )
dwLocalUntilTime = SystemTimeToLocalTime( _pDocumentData->pJobInfo()->UntilTime );
else
dwLocalUntilTime = 0;
UntilTime.wHour = (WORD)(dwLocalUntilTime / 60);
UntilTime.wMinute = (WORD)(dwLocalUntilTime % 60);
//
// Set the start and until to the specified time.
//
if( !_StartTime.bSetTime( &StartTime ) ||
!_UntilTime.bSetTime( &UntilTime )){
DBGMSG( DBG_ERROR, ( "DocumentGeneral.bSetTime failed.\n" ) );
return FALSE;
}
}
//
// Read the job size format string.
//
TString strFormat;
if( strFormat.bLoadString( ghInst, IDS_JOB_SIZE ) ){
//
// Set the size in byes of the job.
//
bSetEditTextFormat( _hDlg,
IDC_DOC_JOB_SIZE,
strFormat,
_pDocumentData->pJobInfo()->Size );
}
//
// Set the Number of pages in the job.
//
bSetEditTextFormat( _hDlg,
IDC_DOC_JOB_PAGES,
TEXT( "%d" ),
_pDocumentData->pJobInfo()->TotalPages );
//
// Set the document text.
//
bSetEditText( _hDlg, IDC_DOC_JOB_TITLE, _pDocumentData->pJobInfo()->pDocument );
bSetEditText( _hDlg, IDC_DOC_JOB_DATATYPE, _pDocumentData->pJobInfo()->pDatatype );
bSetEditText( _hDlg, IDC_DOC_JOB_PROCCESSOR, _pDocumentData->pJobInfo()->pPrintProcessor );
bSetEditText( _hDlg, IDC_DOC_JOB_OWNER, _pDocumentData->pJobInfo()->pUserName );
bSetEditText( _hDlg, IDC_DOC_JOB_NOTIFY, _pDocumentData->pJobInfo()->pNotifyName );
//
// Set the Priority indicator.
//
bSetEditTextFormat( _hDlg,
IDC_DOC_JOB_PRIORITY,
TEXT( "%d" ),
_pDocumentData->pJobInfo()->Priority );
SendDlgItemMessage( _hDlg,
IDC_DOC_JOB_PRIORITY_CONTROL,
TBM_SETPOS,
TRUE,
_pDocumentData->pJobInfo()->Priority );
SendDlgItemMessage( _hDlg,
IDC_DOC_JOB_PRIORITY_CONTROL,
TBM_SETRANGE,
FALSE,
MAKELONG( TDocumentData::kPriorityLowerBound, TDocumentData::kPriorityUpperBound ));
SendDlgItemMessage( _hDlg,
IDC_DOC_JOB_PRIORITY_CONTROL,
TBM_SETPOS,
TRUE,
_pDocumentData->pJobInfo()->Priority );
//
// Format the submitted time field.
//
TStatusB bStatus = FALSE;
TCHAR szBuff[kStrMax];
SYSTEMTIME LocalTime;
//
// Null terminate buffer.
//
szBuff[0] = 0;
//
// Convert to local time.
//
bStatus DBGCHK = SystemTimeToTzSpecificLocalTime(
NULL,
&_pDocumentData->pJobInfo()->Submitted,
&LocalTime );
if( !bStatus ){
DBGMSG( DBG_MIN, ( "SysTimeToTzSpecLocalTime failed %d\n", GetLastError( )));
}
if( bStatus ){
//
// Convert using local format information.
//
bStatus DBGCHK = GetTimeFormat( LOCALE_USER_DEFAULT,
0,
&LocalTime,
NULL,
szBuff,
COUNTOF( szBuff ));
if( !bStatus ){
DBGMSG( DBG_MIN, ( "No Time %d, ", GetLastError( )));
}
}
if( bStatus ){
//
// Tack on space between time and date.
//
lstrcat( szBuff, TEXT(" ") );
//
// Get data format.
//
bStatus DBGCHK = GetDateFormat( LOCALE_USER_DEFAULT,
0,
&LocalTime,
NULL,
szBuff + lstrlen( szBuff ),
COUNTOF( szBuff ) - lstrlen( szBuff ) );
if( !bStatus ){
DBGMSG( DBG_MIN, ( "No Date %d\n", GetLastError( )));
}
}
//
// Set the submitted field
//
bStatus DBGCHK = bSetEditText( _hDlg, IDC_DOC_JOB_AT, szBuff );
//
// Set schedule radio buttons.
//
vSetCheck( _hDlg, bAlways ? IDC_DOC_JOB_ALWAYS : IDC_DOC_JOB_START, TRUE );
vEnableAvailable( !bAlways );
//
// Disable all the controls if not an administrator.
//
if( !_pDocumentData->bAdministrator( )){
//
// Disable the time controls.
//
vEnableAvailable( FALSE );
//
// Disable things if not administrator.
//
static UINT auAvailable[] = {
IDC_DOC_JOB_NOTIFY,
IDC_DOC_JOB_PRIORITY_CONTROL,
IDC_DOC_JOB_ALWAYS,
IDC_DOC_JOB_START,
};
COUNT i;
for( i = 0; i < COUNTOF( auAvailable ); ++i ){
vEnableCtl( _hDlg, auAvailable[i], FALSE );
}
}
return TRUE;
}
/*++
Routine Name:
bReadUI
Routine Description:
Stores the property information to the print server.
Arguments:
Nothing data is contained with in the class.
Return Value:
TRUE if data is stores successfully, FALSE if error occurred.
--*/
BOOL
TDocumentGeneral::
bReadUI(
VOID
)
{
DBGMSG( DBG_TRACE, ( "TDocumentGeneral::bReadUI\n") );
//
// Attempt to validate any UI changeable data.
// Currently not much can be validated, since all the
// controls have set constraints.
//
//
// Extract the UI and save it into the Document Data.
//
_pDocumentData->pJobInfo()->Priority = SendDlgItemMessage( _hDlg,
IDC_DOC_JOB_PRIORITY_CONTROL,
TBM_GETPOS,
0,
0 );
//
// Get the notify name.
//
bGetEditText( _hDlg, IDC_DOC_JOB_NOTIFY, _pDocumentData->strNotifyName() );
_pDocumentData->pJobInfo()->pNotifyName = (LPTSTR)(LPCTSTR)_pDocumentData->strNotifyName();
//
// If the Job always is set then indicate
// not time restriction in the start time and until time.
//
if( bGetCheck( _hDlg, IDC_DOC_JOB_ALWAYS ) ){
_pDocumentData->pJobInfo()->StartTime = 0;
_pDocumentData->pJobInfo()->UntilTime = 0;
} else {
//
// Get the Start time.
//
SYSTEMTIME StartTime;
_StartTime.bGetTime( &StartTime );
_pDocumentData->pJobInfo()->StartTime = LocalTimeToSystemTime( StartTime.wHour * 60 + StartTime.wMinute );
//
// Get the Until time.
//
SYSTEMTIME UntilTime;
_UntilTime.bGetTime( &UntilTime );
_pDocumentData->pJobInfo()->UntilTime = LocalTimeToSystemTime( UntilTime.wHour * 60 + UntilTime.wMinute );
}
return TRUE;
}
/*++
Routine Name:
bSaveUI
Routine Description:
Saves the UI data to some API call or print server.
Arguments:
Nothing data is contained with in the class.
Return Value:
TRUE if data is stores successfully, FALSE if error occurred.
--*/
BOOL
TDocumentGeneral::
bSaveUI(
VOID
)
{
DBGMSG( DBG_TRACE, ( "TDocumentGeneral::bSaveUI\n") );
//
// If we do not have administrator privilages then
// this routine should not do any work.
//
if( !_pDocumentData->bAdministrator( ) )
return TRUE;
if( !_pDocumentData->bStore() ){
DWORD dwLastError = GetLastError ();
if( dwLastError == ERROR_INVALID_TIME ){
_pDocumentData->iErrorMsgId() = IDS_ERR_DOC_JOB_PROPERTY_TIME;
} else {
_pDocumentData->iErrorMsgId() = IDS_ERR_DOC_JOB_PROPERTY_MODIFY;
}
_pDocumentData->bErrorSaving() = FALSE;
}
return TRUE;
}
/*++
Routine Name:
vEanbleAvailablity
Routine Description:
Enables the time availabilty of the job
Arguments:
TRUE enable the availablity, FALSE disable time availablity.
Return Value:
Nothing.
--*/
VOID
TDocumentGeneral::
vEnableAvailable(
IN BOOL bEnable
)
{
_StartTime.vEnable( bEnable );
_UntilTime.vEnable( bEnable );
}
/*++
Routine Name:
bHandleMessage
Routine Description:
Document property sheet message handler. This handler only
handles events it wants and the base class handle will do the
standard message handling.
Arguments:
uMsg - Windows message
wParam - Word parameter
lParam - Long parameter
Return Value:
TRUE if message was handled, FALSE if message not handled.
--*/
BOOL
TDocumentGeneral::
bHandleMessage(
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam
)
{
BOOL bStatus = FALSE;
switch( uMsg ){
case WM_HSCROLL:
//
// Check for slider notification.
//
if( GET_WM_HSCROLL_HWND( wParam, lParam ) == GetDlgItem(_hDlg, IDC_DOC_JOB_PRIORITY_CONTROL ) ){
bSetEditTextFormat( _hDlg,
IDC_DOC_JOB_PRIORITY,
TEXT("%d"),
SendDlgItemMessage( _hDlg,
IDC_DOC_JOB_PRIORITY_CONTROL,
TBM_GETPOS,
0,
0 ) );
bStatus = TRUE;
}
break;
case WM_COMMAND:
switch( GET_WM_COMMAND_ID( wParam, lParam )){
case IDC_DOC_JOB_ALWAYS:
vEnableAvailable( FALSE );
bStatus = TRUE;
break;
case IDC_DOC_JOB_START:
vEnableAvailable( TRUE );
bStatus = TRUE;
break;
default:
break;
}
}
//
// If a message was handled.
//
if( bStatus != FALSE )
return bStatus;
//
// Allow the start time to handle any messages.
//
bStatus = _StartTime.bHandleMessage( uMsg, wParam, lParam );
if( bStatus != FALSE )
return bStatus;
//
// Allow the until time to handle any message.
//
bStatus = _UntilTime.bHandleMessage( uMsg, wParam, lParam );
if( bStatus != FALSE )
return bStatus;
//
// If message not handled pass it on to the derrived base class.
//
if( bStatus == FALSE )
bStatus = TDocumentProp::bHandleMessage( uMsg, wParam, lParam );
return bStatus;
}
/********************************************************************
Document property windows.
********************************************************************/
/*++
Routine Description:
Document property windows.
Arguments:
pDocumentData - Document data to display.
Return Value:
TRUE - Success, FALSE - failure.
--*/
TDocumentWindows::
TDocumentWindows(
TDocumentData* pDocumentData
) : _pDocumentData( pDocumentData ),
_General( pDocumentData )
{
}
TDocumentWindows::
~TDocumentWindows(
)
{
DBGMSG( DBG_TRACE, ( "TDocumentWindows dtor\n") );
}
/*++
Routine Name:
bBuildPages
Routine Description:
Builds the document property windows.
Arguments:
None - class specific.
Return Value:
TRUE pages built ok, FALSE failure building pages.
--*/
BOOL
TDocumentWindows::
bBuildPages(
IN PPROPSHEETUI_INFO pCPSUIInfo
)
{
DBGMSG( DBG_TRACE, ( "TDocumentWindows bBuildPages\n") );
PROPSHEETPAGE psp;
ZeroMemory( &psp, sizeof( psp ) );
psp.dwSize = sizeof( psp );
psp.dwFlags = PSP_DEFAULT;
psp.hInstance = ghInst;
psp.pfnDlgProc = MGenericProp::SetupDlgProc;
psp.pszTemplate = MAKEINTRESOURCE( DLG_DOC_JOB_GENERAL );
psp.lParam = (LPARAM)(MGenericProp*)&_General;
if( pCPSUIInfo->pfnComPropSheet( pCPSUIInfo->hComPropSheet,
CPSFUNC_ADD_PROPSHEETPAGE,
(LPARAM)&psp,
NULL ) <= 0 ) {
DBGMSG( DBG_TRACE, ( "CPSFUNC_ADD_PROPSHEETPAGE failed.\n") );
return FALSE;
}
//
// If the dev mode is null don't display the
// device property sheets.
//
if( _pDocumentData->pJobInfo()->pDevMode ){
ZeroMemory( &_dph, sizeof( _dph ) );
_dph.cbSize = sizeof( _dph );
_dph.hPrinter = _pDocumentData->hPrinter();
_dph.pszPrinterName = (LPTSTR)(LPCTSTR)_pDocumentData->strPrinterName();
_dph.pdmOut = _pDocumentData->pJobInfo()->pDevMode;
_dph.pdmIn = _pDocumentData->pJobInfo()->pDevMode;
_dph.fMode = DM_IN_BUFFER | DM_PROMPT | DM_NOPERMISSION;
if( pCPSUIInfo->pfnComPropSheet( pCPSUIInfo->hComPropSheet,
CPSFUNC_ADD_PFNPROPSHEETUI,
(LPARAM)DocumentPropertySheets,
(LPARAM)&_dph ) <= 0 ){
DBGMSG( DBG_TRACE, ( "CPSFUNC_ADD_PFNPROPSHEETUI failed.\n") );
return FALSE;
}
}
return TRUE;
}
BOOL
TDocumentWindows::
bSetHeader(
IN PPROPSHEETUI_INFO pCPSUIInfo,
IN PPROPSHEETUI_INFO_HEADER pPSUIInfoHdr
)
{
DBGMSG( DBG_TRACE, ( "TDocumentWindows bSetHeader\n") );
UNREFERENCED_PARAMETER( pCPSUIInfo );
pPSUIInfoHdr->pTitle = _pDocumentData->pJobInfo()->pDocument;
pPSUIInfoHdr->Flags = PSUIHDRF_PROPTITLE | PSUIHDRF_NOAPPLYNOW;
pPSUIInfoHdr->hWndParent = _pDocumentData->hwnd();
pPSUIInfoHdr->hInst = ghInst;
pPSUIInfoHdr->IconID = IDI_DOCUMENT;
return TRUE;
}
BOOL
TDocumentWindows::
bValid(
VOID
)
{
return _General.bValid();
}