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.
1808 lines
35 KiB
1808 lines
35 KiB
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Report.c
|
|
|
|
Abstract:
|
|
|
|
This module contains support for displaying the Hardware dialog.
|
|
|
|
Author:
|
|
|
|
Gregg R. Acheson (GreggA) 1-Oct-1993
|
|
|
|
Environment:
|
|
|
|
User Mode
|
|
|
|
--*/
|
|
|
|
//
|
|
// Hardware.h must be included first because it includes <nt.h>
|
|
//
|
|
|
|
#include "hardware.h"
|
|
|
|
#include "dialogs.h"
|
|
#include "report.h"
|
|
#include "msg.h"
|
|
#include "winmsd.h"
|
|
#include "strresid.h"
|
|
#include "dlgprint.h"
|
|
#include "Printer.h"
|
|
|
|
#include "osver.h"
|
|
#include "mem.h"
|
|
#include "service.h"
|
|
#include "drives.h"
|
|
#include "resprint.h"
|
|
#include "environ.h"
|
|
#include "network.h"
|
|
|
|
#include <commdlg.h>
|
|
|
|
#include <string.h>
|
|
#include <tchar.h>
|
|
#include <lmerr.h>
|
|
|
|
//
|
|
// Global Variables
|
|
//
|
|
|
|
LPREPORT_LINE lpReportHeadg;
|
|
LPREPORT_LINE lpReportLastg = NULL;
|
|
|
|
BOOL bAbortReport;
|
|
|
|
HWND volatile hdlgProgress;
|
|
|
|
LRESULT
|
|
CALLBACK
|
|
ProgressDialogProc(
|
|
HWND hwndDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
);
|
|
|
|
|
|
long WINAPI
|
|
ProgressThread(
|
|
VOID
|
|
);
|
|
|
|
|
|
BOOL
|
|
ReportDlgProc(
|
|
IN HWND hWnd,
|
|
IN UINT message,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
ReportDlgProc allows the selection of report options.
|
|
|
|
Arguments:
|
|
|
|
Standard DLGPROC entry.
|
|
|
|
Return Value:
|
|
|
|
BOOL - Depending on input message and processing options.
|
|
|
|
--*/
|
|
|
|
{
|
|
static
|
|
UINT ReportType;
|
|
BOOL Success;
|
|
int i;
|
|
|
|
static
|
|
UINT iScope = IDC_ALL_TABS;
|
|
|
|
static
|
|
UINT iDetailLevel = IDC_SUMMARY_REPORT;
|
|
|
|
static
|
|
UINT iDestination = IDC_SEND_TO_PRINTER;
|
|
|
|
switch( message ) {
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
//
|
|
// The report type is passed in lParam
|
|
//
|
|
|
|
ReportType = ( DWORD ) lParam;
|
|
|
|
//
|
|
// Validate the report type
|
|
//
|
|
|
|
Success = ( ReportType == IDM_FILE_PRINT ) ||
|
|
( ReportType == IDC_PUSH_PRINT ) ||
|
|
( ReportType == IDM_FILE_SAVE );
|
|
|
|
DbgAssert( Success );
|
|
|
|
if( Success == FALSE ) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Initial settings.
|
|
//
|
|
|
|
SetDlgItemText( hWnd, IDC_SYSTEM_NAME, _lpszSelectedComputer);
|
|
|
|
Success = CheckRadioButton(
|
|
hWnd,
|
|
IDC_CURRENT_TAB,
|
|
IDC_ALL_TABS,
|
|
iScope
|
|
);
|
|
DbgAssert( Success );
|
|
|
|
Success = CheckRadioButton(
|
|
hWnd,
|
|
IDC_SUMMARY_REPORT,
|
|
IDC_COMPLETE_REPORT,
|
|
iDetailLevel
|
|
);
|
|
DbgAssert( Success );
|
|
|
|
|
|
if ( ReportType == IDM_FILE_SAVE ) {
|
|
|
|
Success = CheckRadioButton(
|
|
hWnd,
|
|
IDC_SEND_TO_FILE,
|
|
IDC_SEND_TO_PRINTER,
|
|
IDC_SEND_TO_FILE
|
|
);
|
|
DbgAssert( Success );
|
|
iDestination = IDC_SEND_TO_FILE;
|
|
|
|
} else {
|
|
|
|
Success = CheckRadioButton(
|
|
hWnd,
|
|
IDC_SEND_TO_FILE,
|
|
IDC_SEND_TO_PRINTER,
|
|
IDC_SEND_TO_PRINTER
|
|
);
|
|
DbgAssert( Success );
|
|
iDestination = IDC_SEND_TO_PRINTER;
|
|
|
|
}
|
|
|
|
if( Success == FALSE ) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
|
|
switch( LOWORD( wParam )) {
|
|
|
|
case IDOK: {
|
|
|
|
EndDialog ( hWnd, 1 ) ;
|
|
|
|
//
|
|
// Generate the report.
|
|
//
|
|
|
|
Success = GenerateReport ( GetParent( hWnd ), iDestination, iScope, iDetailLevel, FALSE );
|
|
|
|
if( Success == FALSE ) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
case IDC_CURRENT_TAB:
|
|
case IDC_ALL_TABS:
|
|
Success = CheckRadioButton(
|
|
hWnd,
|
|
IDC_CURRENT_TAB,
|
|
IDC_ALL_TABS,
|
|
LOWORD( wParam )
|
|
);
|
|
DbgAssert( Success );
|
|
iScope = LOWORD( wParam );
|
|
break;
|
|
|
|
case IDC_SUMMARY_REPORT:
|
|
case IDC_COMPLETE_REPORT:
|
|
Success = CheckRadioButton(
|
|
hWnd,
|
|
IDC_SUMMARY_REPORT,
|
|
IDC_COMPLETE_REPORT,
|
|
LOWORD( wParam )
|
|
);
|
|
DbgAssert( Success );
|
|
iDetailLevel = LOWORD( wParam );
|
|
break;
|
|
|
|
case IDC_SEND_TO_FILE:
|
|
case IDC_CLIPBOARD:
|
|
case IDC_SEND_TO_PRINTER:
|
|
Success = CheckRadioButton(
|
|
hWnd,
|
|
IDC_SEND_TO_FILE,
|
|
IDC_SEND_TO_PRINTER,
|
|
LOWORD( wParam )
|
|
);
|
|
DbgAssert( Success );
|
|
iDestination = LOWORD( wParam );
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
|
|
EndDialog( hWnd, 1 );
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
GenerateReport(
|
|
IN HWND hWnd,
|
|
IN UINT iDestination,
|
|
IN UINT iScope,
|
|
IN UINT iDetailLevel,
|
|
IN BOOL bCallFromCommandLine
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
GenerateReport prints the selected items.
|
|
|
|
Arguments:
|
|
|
|
IN HWND hWnd - handle of main window
|
|
IN UINT iDestination - report desitination
|
|
IN UINT iScope - single tab or all tabs?
|
|
IN UINT iDetailLevel - summary or all details
|
|
IN BOOL bCallFromCommandLine - Was this function called because of command line options?
|
|
|
|
Return Value:
|
|
|
|
BOOL - TRUE if report was generated, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
BOOL Success;
|
|
TCHAR Title [ MAX_PATH*2 ];
|
|
TCHAR RptFileName[ MAX_PATH*2 ];
|
|
HDC PrinterDC;
|
|
int i;
|
|
DLGHDR *pHdr = (DLGHDR *) GetWindowLong( hWnd, GWL_USERDATA );
|
|
HANDLE hProgressThread;
|
|
HCURSOR hSaveCursor;
|
|
TC_ITEM tci;
|
|
|
|
//
|
|
// Initialize the abort flag
|
|
//
|
|
|
|
bAbortReport = FALSE;
|
|
|
|
//
|
|
// Make sure we get a valid filename or hPrinter
|
|
//
|
|
|
|
if ( iDestination == IDC_SEND_TO_FILE ) {
|
|
|
|
if (bCallFromCommandLine) {
|
|
lstrcpy( RptFileName, _lpszSelectedComputer+2 );
|
|
lstrcat( RptFileName, L".TXT" );
|
|
|
|
} else {
|
|
Success = GetReportFileName ( hWnd, RptFileName );
|
|
|
|
if ( ! Success )
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
if ( iDestination == IDC_SEND_TO_PRINTER ) {
|
|
|
|
//
|
|
// If its a printed report, get the default printer DC
|
|
//
|
|
|
|
Success = GetPrinterDC( hWnd, &PrinterDC );
|
|
|
|
if ( ! Success )
|
|
return FALSE;
|
|
}
|
|
|
|
UpdateWindow( hWnd );
|
|
|
|
//
|
|
// Display the modeless progress / cancel dialog
|
|
//
|
|
|
|
hdlgProgress = 0;
|
|
|
|
hProgressThread = CreateThread( NULL,
|
|
0,
|
|
(LPTHREAD_START_ROUTINE) ProgressThread,
|
|
NULL,
|
|
0,
|
|
&i);
|
|
|
|
//
|
|
// Disable the application's window.
|
|
//
|
|
|
|
EnableWindow( hWnd, FALSE );
|
|
|
|
//
|
|
// Wait until dialog appears
|
|
//
|
|
while(!hdlgProgress);
|
|
|
|
//
|
|
// Initialize the report head pointer.
|
|
//
|
|
|
|
Success = InitializeReport( );
|
|
DbgAssert( Success );
|
|
|
|
DbgPointerAssert( lpReportHeadg );
|
|
|
|
//
|
|
// Set the last node to the head
|
|
//
|
|
|
|
lpReportLastg = lpReportHeadg;
|
|
|
|
//
|
|
// Set up the title for the report
|
|
//
|
|
|
|
lstrcpy( Title, GetString( IDS_REPORT_TITLE ) );
|
|
lstrcat( Title, _lpszSelectedComputer );
|
|
|
|
//
|
|
// Add 2 blank lines.
|
|
//
|
|
|
|
Success = AddLineToReport( 2, RFO_SKIPLINE, NULL, NULL );
|
|
|
|
DbgAssert( Success );
|
|
|
|
//
|
|
// Add the title.
|
|
//
|
|
|
|
Success = AddLineToReport( 0, RFO_SINGLELINE, Title, NULL );
|
|
|
|
DbgAssert( Success );
|
|
|
|
//
|
|
// Add a separator.
|
|
//
|
|
|
|
Success = AddLineToReport( 0, RFO_SEPARATOR, NULL, NULL );
|
|
|
|
DbgAssert( Success );
|
|
|
|
//
|
|
// Call selected report functions
|
|
//
|
|
|
|
if (iScope == IDC_CURRENT_TAB) {
|
|
//
|
|
//get the proper index to the appropriate procs
|
|
//that were set in MakeTabs
|
|
//
|
|
tci.mask = TCIF_PARAM;
|
|
i = TabCtrl_GetCurSel( pHdr->hwndTab );
|
|
TabCtrl_GetItem(pHdr->hwndTab, i, &tci);
|
|
|
|
pHdr->TabPrintProc[ tci.lParam ]( GetParent( hWnd ), iDetailLevel);
|
|
|
|
}
|
|
else
|
|
{
|
|
// cycle through all the active tabs
|
|
|
|
for (i = 0; i < TabCtrl_GetItemCount(pHdr->hwndTab); i++)
|
|
{
|
|
tci.mask = TCIF_PARAM;
|
|
TabCtrl_GetItem(pHdr->hwndTab, i, &tci);
|
|
|
|
SendMessage(GetDlgItem(hdlgProgress, IDD_REPORT_PROGRESS), PBM_STEPIT, 0, 0);
|
|
|
|
pHdr->TabPrintProc[ tci.lParam ]( GetParent( hWnd ), iDetailLevel);
|
|
|
|
//
|
|
// Check to see if we need to abort
|
|
//
|
|
if (bAbortReport)
|
|
{
|
|
goto AbortReport;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check to see if we need to abort
|
|
//
|
|
|
|
if (bAbortReport)
|
|
{
|
|
goto AbortReport;
|
|
}
|
|
|
|
//
|
|
// See if there is anything to report.
|
|
// The title and header take up 4 lines.
|
|
//
|
|
|
|
if ( NumReportLines( lpReportHeadg ) < 5 )
|
|
{
|
|
Success = FALSE;
|
|
goto AbortReport;
|
|
}
|
|
|
|
//
|
|
// Set up to save report to a file
|
|
//
|
|
|
|
switch (iDestination) {
|
|
|
|
case IDC_SEND_TO_FILE:
|
|
Success = SaveReportToFile( hWnd, lpReportHeadg, RptFileName );
|
|
break;
|
|
|
|
case IDC_SEND_TO_PRINTER:
|
|
Success = PrintReportToPrinter( hWnd, lpReportHeadg, PrinterDC );
|
|
break;
|
|
|
|
case IDC_CLIPBOARD:
|
|
Success = CopyReportToClipboard( hWnd, lpReportHeadg );
|
|
break;
|
|
|
|
default:
|
|
Success = FALSE;
|
|
break;
|
|
}
|
|
|
|
AbortReport:
|
|
|
|
//
|
|
// Re-enable the application's window.
|
|
//
|
|
|
|
EnableWindow( hWnd, TRUE );
|
|
|
|
//
|
|
// Remove the Progress window and thread.
|
|
//
|
|
SendMessage( hdlgProgress, WM_CLOSE, 0, 0 );
|
|
TerminateThread( hProgressThread, 0 );
|
|
|
|
//
|
|
// Set the focus on the OK button on main window
|
|
//
|
|
SetFocus( GetDlgItem( _hWndMain, IDOK) );
|
|
|
|
return Success;
|
|
}
|
|
|
|
|
|
BOOL
|
|
SaveReportToFile(
|
|
IN HWND hWnd,
|
|
IN LPREPORT_LINE lpReportHead,
|
|
IN LPTSTR RptFileName
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
SaveReportToFile formats the report data and writes it to a file.
|
|
|
|
Arguments:
|
|
|
|
hWnd - Handle to window
|
|
ReportFileName - Name of file to save report to.
|
|
|
|
Return Value:
|
|
|
|
BOOL - True if report was saved to file successfully, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
HANDLE hReportFile;
|
|
TCHAR Buffer [ MAX_PATH*2 ];
|
|
DWORD dwLastError;
|
|
BOOL Success;
|
|
|
|
//
|
|
// Create or OpenAndTruncate file.
|
|
//
|
|
|
|
hReportFile = CreateFile( RptFileName,
|
|
GENERIC_WRITE,
|
|
0,
|
|
(LPSECURITY_ATTRIBUTES) NULL,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
(HANDLE) NULL);
|
|
|
|
//
|
|
// Check Handle
|
|
//
|
|
|
|
if ( hReportFile == INVALID_HANDLE_VALUE ) {
|
|
|
|
//
|
|
// Get the error SCODE
|
|
//
|
|
|
|
dwLastError = GetLastError( );
|
|
|
|
//
|
|
// Format an error message and report the error
|
|
//
|
|
|
|
wsprintf( Buffer, GetString( IDS_FILE_OPEN_ERROR ), dwLastError );
|
|
MessageBox( hWnd, Buffer, GetString( IDS_APPLICATION_FULLNAME ), MB_OK | MB_ICONSTOP );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
Success = OutputReportLines( hWnd, hReportFile, IDC_SEND_TO_FILE, lpReportHead );
|
|
|
|
//
|
|
// See if the write succeded.
|
|
//
|
|
|
|
if ( ! Success ) {
|
|
|
|
//
|
|
// Get the error SCODE.
|
|
//
|
|
|
|
dwLastError = GetLastError( );
|
|
|
|
//
|
|
// Format an error message and report the error.
|
|
//
|
|
|
|
wsprintf( Buffer, GetString( IDS_FILE_WRITE_ERROR ), dwLastError );
|
|
MessageBox( hWnd, Buffer, GetString( IDS_APPLICATION_FULLNAME ), MB_OK | MB_ICONSTOP );
|
|
|
|
|
|
CloseHandle( hReportFile );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Close the file.
|
|
//
|
|
|
|
CloseHandle( hReportFile );
|
|
|
|
//
|
|
// Saving report was successful.
|
|
//
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CopyReportToClipboard(
|
|
IN HWND hWnd,
|
|
IN LPREPORT_LINE lpReportHead
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
CopyReportToClipboard formats the report data and copies it to the clipboard.
|
|
|
|
Arguments:
|
|
|
|
hWnd - Handle to window
|
|
ReportFileName - Name of file to save report to.
|
|
|
|
Return Value:
|
|
|
|
BOOL - True if report was copied to the clipboard successfully, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
HANDLE hReportFile;
|
|
TCHAR szBuffer [ MAX_PATH*2 ];
|
|
DWORD dwLastError;
|
|
BOOL Success;
|
|
LPTSTR lptstrCopy;
|
|
HGLOBAL hglbCopy;
|
|
UINT nLines = NumReportLines( lpReportHead );
|
|
|
|
|
|
|
|
//
|
|
// Open the clipboard, and empty it.
|
|
//
|
|
if (!OpenClipboard(hWnd))
|
|
return FALSE;
|
|
EmptyClipboard();
|
|
|
|
//
|
|
// Allocate a global memory object for the text.
|
|
//
|
|
hglbCopy = GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT, 1024 * nLines );
|
|
|
|
if (hglbCopy == NULL) {
|
|
CloseClipboard();
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Lock the handle and copy the text to the buffer.
|
|
//
|
|
lptstrCopy = GlobalLock(hglbCopy);
|
|
|
|
Success = OutputReportLines( hWnd, lptstrCopy, IDC_CLIPBOARD, lpReportHead );
|
|
|
|
GlobalUnlock(hglbCopy);
|
|
|
|
//
|
|
// Place the handle on the clipboard.
|
|
//
|
|
SetClipboardData(CF_UNICODETEXT, hglbCopy);
|
|
|
|
//
|
|
// Close the clipboard.
|
|
//
|
|
CloseClipboard();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
GetReportFileName(
|
|
IN HWND hWnd,
|
|
IN OUT LPTSTR ReportFileName
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
GetReportFileName calls the save file comdlg.
|
|
|
|
Arguments:
|
|
|
|
ReportFileName - pointer to string to return filename.
|
|
|
|
Return Value:
|
|
|
|
BOOL - True if we get a valid filename, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
// User wants to save a reoport
|
|
//
|
|
|
|
OPENFILENAME Ofn;
|
|
TCHAR FileName[ MAX_PATH*2 ];
|
|
LPCTSTR FilterString;
|
|
TCHAR ReplaceChar;
|
|
int Length;
|
|
int i;
|
|
|
|
static BOOL MakeFilterString = TRUE;
|
|
static TCHAR FilterStringBuffer[ MAX_CHARS ];
|
|
|
|
//
|
|
// Validate _hModule and the string we were passed
|
|
//
|
|
|
|
DbgHandleAssert( _hModule );
|
|
|
|
if ( _hModule == NULL || _hModule == INVALID_HANDLE_VALUE ) {
|
|
return FALSE;
|
|
}
|
|
|
|
DbgPointerAssert( ReportFileName );
|
|
|
|
if ( ReportFileName == NULL ) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If the filter string was never made before, get it and scan
|
|
// it replacing each replacement character with a NUL
|
|
// character. This is necessary since there is no way of
|
|
// entering a NUL character in the resource file.
|
|
//
|
|
|
|
if( MakeFilterString == TRUE ) {
|
|
|
|
MakeFilterString = FALSE;
|
|
|
|
//
|
|
// Load the filter string
|
|
//
|
|
|
|
FilterString = GetString( IDS_FILE_REPORT_FILTER );
|
|
|
|
DbgPointerAssert( FilterString );
|
|
|
|
if ( FilterString == NULL ) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Copy the FilterString into the FilterStringBuffer
|
|
//
|
|
|
|
_tcscpy( FilterStringBuffer, FilterString );
|
|
|
|
//
|
|
// Get the length of the filter string
|
|
//
|
|
|
|
Length = _tcslen( FilterString );
|
|
|
|
ReplaceChar = GetString( IDS_FILE_REPORT_FILTER )[ Length - 1 ];
|
|
|
|
for( i = 0; FilterStringBuffer[ i ] != TEXT( '\0' ); i++ ) {
|
|
|
|
if( FilterStringBuffer[ i ] == ReplaceChar ) {
|
|
|
|
FilterStringBuffer[ i ] = TEXT( '\0' );
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Get the default filename
|
|
//
|
|
|
|
lstrcpy ( FileName, GetString( IDS_DEFAULT_FILENAME ) );
|
|
|
|
//
|
|
// Fill in the Ofn structure for the OpenFile CommDlg
|
|
//
|
|
|
|
Ofn.lStructSize = sizeof( OPENFILENAMEW );
|
|
Ofn.hwndOwner = hWnd;
|
|
Ofn.hInstance = NULL;
|
|
Ofn.lpstrFilter = FilterStringBuffer;
|
|
Ofn.lpstrCustomFilter = NULL;
|
|
Ofn.nMaxCustFilter = 0;
|
|
Ofn.nFilterIndex = 1;
|
|
Ofn.lpstrFile = FileName;
|
|
Ofn.nMaxFile = NumberOfCharacters( FileName );
|
|
Ofn.lpstrFileTitle = NULL;
|
|
Ofn.nMaxFileTitle = 0;
|
|
Ofn.lpstrInitialDir = NULL;
|
|
Ofn.lpstrTitle = GetString( IDS_FILE_REPORT_TITLE );
|
|
Ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
|
|
Ofn.nFileOffset = 0;
|
|
Ofn.nFileExtension = 0;
|
|
Ofn.lpstrDefExt = NULL;
|
|
Ofn.lCustData = 0;
|
|
Ofn.lpfnHook = NULL;
|
|
Ofn.lpTemplateName = NULL;
|
|
|
|
//
|
|
// Let the user choose files.
|
|
//
|
|
|
|
if( GetSaveFileName( &Ofn )) {
|
|
|
|
//
|
|
// The user pressed OK so set the path and file to search
|
|
// for to what was browsed.
|
|
//
|
|
|
|
lstrcpy( ReportFileName, Ofn.lpstrFile );
|
|
|
|
} else {
|
|
|
|
//
|
|
// The user pressed Cancel or closed the dialog.
|
|
//
|
|
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
OutputReportLines(
|
|
IN HWND hWnd,
|
|
IN HANDLE hDevice,
|
|
IN UINT Destination,
|
|
IN LPREPORT_LINE lpReportHead
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
OutputReportLines - walks the report list and hands the line to the device.
|
|
|
|
Arguments:
|
|
|
|
hWnd - Handle to window.
|
|
Device - Handle to device to write to (hFile or hPrinterDC or pointer to clipboard data).
|
|
Destination - Indicates file or printer.
|
|
ReportHead - Head pointer to report.
|
|
|
|
Return Value:
|
|
|
|
BOOL - True if report was saved to file successfully, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
LPREPORT_LINE lpNode, lpNext;
|
|
TCHAR LineBuffer [ MAX_PATH*2+4];
|
|
UINT LinesToPrint;
|
|
UINT u;
|
|
BOOL Success = TRUE;
|
|
|
|
//
|
|
// Prepare to walk the ReportLine linked list.
|
|
//
|
|
|
|
lpNode = lpReportHead;
|
|
|
|
//
|
|
// Validate the node.
|
|
//
|
|
|
|
DbgPointerAssert( lpNode );
|
|
DbgAssert( CheckSignature ( lpNode ));
|
|
|
|
if( lpNode == NULL )
|
|
return FALSE;
|
|
|
|
//
|
|
// While the node is valid...
|
|
//
|
|
|
|
while ( lpNode ) {
|
|
|
|
//
|
|
// Validate the node.
|
|
//
|
|
|
|
DbgAssert( CheckSignature ( lpNode ));
|
|
|
|
//
|
|
// Build the report line
|
|
//
|
|
|
|
BuildReportLine( lpNode, LineBuffer );
|
|
|
|
//
|
|
// See if we have multiple RFO_SKIPLINE's
|
|
//
|
|
|
|
if ( lpNode->FormatOpt == RFO_SKIPLINE && lpNode->Indent > 1 ) {
|
|
|
|
//
|
|
// If we are skipping lines, see how many to skip.
|
|
//
|
|
|
|
LinesToPrint = lpNode->Indent;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Only one line to print.
|
|
//
|
|
|
|
LinesToPrint = 1;
|
|
}
|
|
|
|
//
|
|
// Loop through LinesToPrint times.
|
|
//
|
|
|
|
for( u = 1; u <= LinesToPrint; ++u ) {
|
|
|
|
//
|
|
// Send the line to the device
|
|
//
|
|
switch( Destination ) {
|
|
|
|
case IDC_SEND_TO_PRINTER:
|
|
Success = PrintLine( hDevice, LineBuffer );
|
|
DbgAssert( Success );
|
|
break;
|
|
|
|
case IDC_SEND_TO_FILE:
|
|
//
|
|
// Append a newline onto the end of the LineBuffer.
|
|
//
|
|
lstrcat( LineBuffer, L"\r\n" );
|
|
|
|
//
|
|
// Save it to the file.
|
|
//
|
|
Success = AnsiWriteFile( hDevice, (LPTSTR) LineBuffer );
|
|
|
|
DbgAssert( Success );
|
|
|
|
break;
|
|
|
|
case IDC_CLIPBOARD:
|
|
//
|
|
// Append a newline onto the end of the LineBuffer.
|
|
//
|
|
lstrcat( LineBuffer, L"\r\n" );
|
|
|
|
if (lstrlen( (LPTSTR) hDevice ) ) {
|
|
lstrcat( (LPTSTR) hDevice, LineBuffer );
|
|
} else {
|
|
lstrcpy( (LPTSTR) hDevice, LineBuffer );
|
|
}
|
|
|
|
break;
|
|
|
|
defualt:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
//
|
|
// Get the next node in the list.
|
|
//
|
|
|
|
lpNext = lpNode->NextLine;
|
|
|
|
//
|
|
// Free the Label and Value strings.
|
|
//
|
|
|
|
FreeMemory( lpNode->Label );
|
|
FreeMemory( lpNode->Value );
|
|
|
|
//
|
|
// Free the ReportLine node.
|
|
//
|
|
|
|
FreeMemory( lpNode );
|
|
|
|
//
|
|
// Make the next node the current node.
|
|
//
|
|
|
|
lpNode = lpNext;
|
|
}
|
|
|
|
return Success;
|
|
}
|
|
|
|
|
|
BOOL
|
|
AddLineToReport(
|
|
IN UINT Indent,
|
|
IN DWORD FormatOpt,
|
|
IN LPTSTR Label,
|
|
IN LPTSTR Value
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Add a line of text to the report buffer.
|
|
|
|
Arguments:
|
|
|
|
Indent - Number of spaces to indent.
|
|
FormatOpt - Formatting options.
|
|
Label - Pointer to the Label string.
|
|
Value - Pointer to the Value string.
|
|
|
|
Return Value:
|
|
|
|
BOOL - TRUE if the line was successfully added. FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
LPREPORT_LINE ReportNew;
|
|
LPTSTR lpszNextValue;
|
|
BOOL bMultilineValue = FALSE;
|
|
|
|
|
|
//
|
|
// Check to see if the value is multi-line
|
|
//
|
|
if ( FormatOpt & (RFO_RPTLINE | RFO_RPTVALUE) ) {
|
|
|
|
lpszNextValue = wcschr( Value, '\r');
|
|
if (lpszNextValue) {
|
|
bMultilineValue = TRUE;
|
|
*lpszNextValue++ = UNICODE_NULL;
|
|
lpszNextValue++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate Head (Global)
|
|
//
|
|
|
|
DbgPointerAssert( lpReportHeadg );
|
|
|
|
if( lpReportHeadg == NULL )
|
|
return FALSE;
|
|
|
|
//
|
|
// Check Last Pointer
|
|
//
|
|
|
|
DbgPointerAssert( lpReportLastg );
|
|
|
|
if( lpReportLastg == NULL )
|
|
return FALSE;
|
|
|
|
//
|
|
// Allocate a new report line
|
|
//
|
|
|
|
ReportNew = AllocateObject( REPORT_LINE, 1 );
|
|
|
|
//
|
|
// Validate new report line.
|
|
//
|
|
|
|
DbgPointerAssert ( ReportNew );
|
|
if( ReportNew == NULL )
|
|
return FALSE;
|
|
|
|
//
|
|
// Set the signature on the report line
|
|
//
|
|
|
|
SetSignature( ReportNew );
|
|
|
|
//
|
|
// Link it into the list
|
|
//
|
|
|
|
lpReportLastg->NextLine = ReportNew;
|
|
lpReportLastg = ReportNew;
|
|
|
|
//
|
|
// Add the passed information
|
|
//
|
|
|
|
ReportNew->Indent = Indent;
|
|
ReportNew->FormatOpt = FormatOpt;
|
|
|
|
//
|
|
// See if we need to help with the formatting...
|
|
//
|
|
|
|
if ( (FormatOpt == RFO_SKIPLINE) ||
|
|
(FormatOpt & RFO_SEPARATOR) ) {
|
|
|
|
//
|
|
// RFO_SKIPLINE or RFO_SEPARATOR - Nothing to add.
|
|
//
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
if ( FormatOpt & RFO_SINGLELINE ) {
|
|
|
|
//
|
|
// RFO_SINGLELINE - Add line to Label.
|
|
//
|
|
|
|
if( Label )
|
|
{
|
|
|
|
ReportNew->Label = (LPTSTR) LocalAlloc(LPTR, (lstrlen(Label)*sizeof(TCHAR)) + 2);
|
|
lstrcpyn( ReportNew->Label, Label,(lstrlen(Label)*sizeof(TCHAR)) );
|
|
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
if ( FormatOpt & RFO_RPTVALUE ) {
|
|
|
|
//
|
|
// RFO_RPTVALUE - Add line to Value.
|
|
//
|
|
|
|
if( Value )
|
|
{
|
|
ReportNew->Value = (LPTSTR) LocalAlloc( LPTR, (lstrlen(Value)*sizeof(TCHAR)) + 2);
|
|
lstrcpyn( ReportNew->Value, Value, (lstrlen(Value)*sizeof(TCHAR)) );
|
|
}
|
|
|
|
//
|
|
// if this was a multi-line value, call function again with next line
|
|
//
|
|
if (bMultilineValue)
|
|
{
|
|
AddLineToReport(Indent, FormatOpt, Label, lpszNextValue);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
if ( FormatOpt & RFO_RPTLINE ) {
|
|
|
|
//
|
|
// RFO_RPTLINE - Add both Label and Value.
|
|
//
|
|
if( Label )
|
|
{
|
|
ReportNew->Label = (LPTSTR) LocalAlloc(LPTR, (lstrlen(Label)*sizeof(TCHAR)) + 2);
|
|
lstrcpyn( ReportNew->Label, Label,(lstrlen(Label)*sizeof(TCHAR)) );
|
|
}
|
|
|
|
if( Value )
|
|
{
|
|
ReportNew->Value = (LPTSTR) LocalAlloc( LPTR, (lstrlen(Value)*sizeof(TCHAR)) + 2);
|
|
lstrcpyn( ReportNew->Value, Value, (lstrlen(Value)*sizeof(TCHAR)) );
|
|
}
|
|
|
|
//
|
|
// if this was a multi-line value, call function again with next line
|
|
//
|
|
if (bMultilineValue) {
|
|
|
|
_wcsset( Label, ' ');
|
|
AddLineToReport(Indent, FormatOpt, Label, lpszNextValue);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
UINT
|
|
NumReportLines(
|
|
IN LPREPORT_LINE lpReportHead
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Count the number of lines in the ReportBuffer.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
UINT - Number of entries in the Report Buffer.
|
|
|
|
--*/
|
|
|
|
{
|
|
UINT Count = 0;
|
|
LPREPORT_LINE Node;
|
|
|
|
//
|
|
// Validate ReportHead
|
|
//
|
|
|
|
DbgPointerAssert( lpReportHead );
|
|
|
|
if( lpReportHead == NULL )
|
|
return 0;
|
|
|
|
Node = lpReportHead;
|
|
|
|
//
|
|
// Walk the report list and incrment count for each node;
|
|
//
|
|
|
|
while( Node ) {
|
|
|
|
//
|
|
// Make sure the node is valid.
|
|
//
|
|
|
|
|
|
DbgAssert( CheckSignature( Node ) );
|
|
|
|
//
|
|
// Get the next node and increment the count.
|
|
//
|
|
|
|
Node=Node->NextLine;
|
|
++Count;
|
|
}
|
|
|
|
return Count;
|
|
}
|
|
|
|
|
|
BOOL
|
|
AnsiWriteFile (
|
|
IN HANDLE hFile,
|
|
IN LPTSTR lpBuffer
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Converts a UNICODE string to ASCII and writes it to a file.
|
|
|
|
Arguments:
|
|
|
|
hFile - Handle to file where data is going to be written.
|
|
lpBuffer - Unicode string to convert and write to file.
|
|
|
|
Return Value:
|
|
|
|
BOOL - TRUE if write succeeds, FALSE otherwise.
|
|
|
|
--*/
|
|
{
|
|
|
|
LPSTR lpAnsi;
|
|
int nBytes;
|
|
BOOL Success;
|
|
BOOL fDefCharUsed;
|
|
DWORD dwBytesWritten;
|
|
DWORD nChars;
|
|
|
|
//
|
|
// Get the length of the Unicode string.
|
|
//
|
|
|
|
DbgPointerAssert( lpBuffer );
|
|
|
|
if ( lpBuffer == NULL ) {
|
|
|
|
CloseHandle( hFile );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
nChars = lstrlen( lpBuffer );
|
|
|
|
//
|
|
// Convert string to MultiByte.
|
|
//
|
|
|
|
nBytes = WideCharToMultiByte ( CP_ACP,
|
|
0,
|
|
(LPWSTR) lpBuffer,
|
|
nChars,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
&fDefCharUsed
|
|
);
|
|
|
|
//
|
|
// Allocate a new string
|
|
//
|
|
|
|
lpAnsi = (LPSTR) LocalAlloc (LPTR, nBytes + 1);
|
|
|
|
DbgPointerAssert( lpAnsi );
|
|
|
|
if ( lpAnsi == NULL ) {
|
|
|
|
CloseHandle( hFile );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Convert new string to ANSI.
|
|
//
|
|
|
|
WideCharToMultiByte ( CP_ACP,
|
|
0,
|
|
(LPWSTR) lpBuffer,
|
|
nChars,
|
|
lpAnsi,
|
|
nBytes,
|
|
NULL,
|
|
&fDefCharUsed
|
|
);
|
|
|
|
//
|
|
// Write the ANSI string to the file.
|
|
//
|
|
|
|
Success = WriteFile( hFile,
|
|
(LPSTR) lpAnsi,
|
|
(DWORD) nBytes,
|
|
&dwBytesWritten,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// Free the ANSI buffer.
|
|
//
|
|
|
|
LocalFree ( lpAnsi );
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
|
BOOL
|
|
BuildReportLine (
|
|
IN LPREPORT_LINE lpNode,
|
|
IN LPTSTR LineBuffer
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
BuildReportLine
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
BOOL - TRUE if build succeeds, FALSE otherwise.
|
|
|
|
--*/
|
|
{
|
|
|
|
int i, iLen;
|
|
UINT u;
|
|
TCHAR Buffer [ MAX_PATH*2 ];
|
|
|
|
//
|
|
// Validate the node and the buffer
|
|
//
|
|
|
|
DbgPointerAssert( lpNode );
|
|
DbgPointerAssert( LineBuffer );
|
|
|
|
DbgAssert( CheckSignature( lpNode ) );
|
|
|
|
if( !(lpNode) || !(LineBuffer) ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Clear the line buffer.
|
|
//
|
|
|
|
lstrcpy( LineBuffer, L"\0" );
|
|
|
|
//
|
|
// Check the node formatting information.
|
|
//
|
|
|
|
if ( lpNode->FormatOpt & RFO_SINGLELINE ) {
|
|
|
|
//
|
|
// RFO_SINGLELINE - Copy only the Label into the LineBuffer.
|
|
//
|
|
|
|
DbgPointerAssert( lpNode->Label );
|
|
|
|
if ( lpNode->Label == NULL ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
lstrcpy( LineBuffer, lpNode->Label );
|
|
|
|
}
|
|
|
|
if ( lpNode->FormatOpt & RFO_RPTVALUE ) {
|
|
|
|
//
|
|
// RFO_RPTVALUE - Justify and copy the Value into the LineBuffer.
|
|
//
|
|
|
|
DbgPointerAssert( lpNode->Value );
|
|
|
|
if ( lpNode->Value == NULL ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Append the string to the LineBuffer.
|
|
//
|
|
|
|
if ( lpNode->Value )
|
|
|
|
lstrcat( LineBuffer, lpNode->Value );
|
|
|
|
}
|
|
|
|
if ( lpNode->FormatOpt & RFO_RPTLINE ) {
|
|
|
|
//
|
|
// RFO_RPTLINE - Copy the label and append the value to the LineBuffer.
|
|
//
|
|
|
|
//
|
|
// Center justify the buffer around the separator.
|
|
//
|
|
|
|
DbgPointerAssert( lpNode->Label );
|
|
|
|
if ( lpNode->Label == NULL ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Append the string to the padded LineBuffer.
|
|
//
|
|
|
|
lstrcat( LineBuffer, lpNode->Label );
|
|
|
|
//
|
|
// Insert a space between the strings.
|
|
//
|
|
|
|
lstrcat( LineBuffer, L" " );
|
|
|
|
//
|
|
// Append the string to the LineBuffer.
|
|
//
|
|
|
|
if ( lpNode->Value )
|
|
|
|
lstrcat( LineBuffer, lpNode->Value );
|
|
|
|
}
|
|
if ( lpNode->FormatOpt & RFO_SEPARATOR ) {
|
|
|
|
//
|
|
// RFO_SEPARATOR - Copy a line of dashes into the LineBuf.
|
|
//
|
|
|
|
for( i = 0; i < 5; ++i )
|
|
lstrcat( LineBuffer, L"--------------" );
|
|
|
|
}
|
|
if ( lpNode->FormatOpt & RFO_CENTER ) {
|
|
|
|
//
|
|
// RFO_CENTER - Center the line on the page.
|
|
//
|
|
|
|
//
|
|
// Assume a file 'width' of 78 chars and calculate the number
|
|
// of spaces needed to pad the line.
|
|
//
|
|
|
|
// BUGBUG: #define FILE_WIDTH
|
|
|
|
#if defined(DBCS) && defined(UNICODE)
|
|
// Get number of bytes, not number of characters
|
|
iLen = 35 - (WideCharToMultiByte(CP_ACP,
|
|
WC_COMPOSITECHECK,
|
|
LineBuffer, -1,
|
|
NULL, 0,
|
|
NULL, NULL) / 2);
|
|
#else
|
|
iLen = 35 - (lstrlen( LineBuffer ) / 2);
|
|
#endif
|
|
|
|
//
|
|
// Save a copy of the LineBuffer in Buffer.
|
|
//
|
|
|
|
lstrcpy( Buffer, LineBuffer );
|
|
|
|
//
|
|
// Clear the Line Buffer.
|
|
//
|
|
|
|
lstrcpy( LineBuffer, L"\0" );
|
|
|
|
//
|
|
// Append spaces to LineBuffer to pad for centering.
|
|
//
|
|
|
|
for( i = 0; i < iLen; ++i )
|
|
lstrcat( LineBuffer, L" " );
|
|
|
|
//
|
|
// Append the string to the padded LineBuffer.
|
|
//
|
|
|
|
lstrcat( LineBuffer, Buffer );
|
|
}
|
|
|
|
if ( lpNode->Indent ) {
|
|
|
|
//
|
|
// Indent the line on the page.
|
|
//
|
|
|
|
//
|
|
// Save a copy of the LineBuffer in Buffer.
|
|
//
|
|
|
|
lstrcpy( Buffer, LineBuffer );
|
|
|
|
//
|
|
// Clear the Line Buffer.
|
|
//
|
|
|
|
lstrcpy( LineBuffer, L"\0" );
|
|
|
|
//
|
|
// Append spaces to LineBuffer to indent.
|
|
//
|
|
|
|
for( u = 0; u < lpNode->Indent; ++u )
|
|
lstrcat( LineBuffer, L" " );
|
|
|
|
//
|
|
// Append the string to the padded LineBuffer.
|
|
//
|
|
|
|
lstrcat( LineBuffer, Buffer );
|
|
}
|
|
|
|
//
|
|
// Check to make sure we have a string, unless it was a RPT_SKIPLINE.
|
|
//
|
|
|
|
if ( (!lstrlen( LineBuffer )) && (lpNode->FormatOpt != RFO_SKIPLINE) ) {
|
|
|
|
DbgAssert( FALSE );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
BOOL
|
|
InitializeReport(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Prepare the report head pointer for use.
|
|
|
|
Arguments:
|
|
|
|
lpReportHead - Head pointer of the list.
|
|
|
|
Return Value:
|
|
|
|
BOOL - TRUE if the node was successfully initialized. FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
|
|
//
|
|
// Allocate a new report line
|
|
//
|
|
|
|
lpReportHeadg = AllocateObject( REPORT_LINE, 1 );
|
|
|
|
//
|
|
// Validate new report line.
|
|
//
|
|
|
|
DbgPointerAssert ( lpReportHeadg );
|
|
if( lpReportHeadg == NULL )
|
|
return FALSE;
|
|
|
|
//
|
|
// Set the signature on the report line
|
|
//
|
|
|
|
SetSignature( lpReportHeadg );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
long WINAPI
|
|
ProgressThread(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
ProgressThread - entry point for thread tracking progress of report generation.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
MSG msg;
|
|
|
|
hdlgProgress = CreateDialog( _hModule,
|
|
(LPTSTR) L"AbortDlg",
|
|
NULL,
|
|
(DLGPROC) ProgressDialogProc );
|
|
|
|
SetForegroundWindow( hdlgProgress );
|
|
|
|
//
|
|
// Retrieve and remove messages from the thread's message queue.
|
|
//
|
|
|
|
while( GetMessage( &msg, hdlgProgress, 0, 0 )) {
|
|
|
|
if( ! IsDialogMessage( hdlgProgress, &msg ) ) {
|
|
|
|
TranslateMessage( &msg );
|
|
DispatchMessage( &msg );
|
|
}
|
|
|
|
}
|
|
|
|
return msg.wParam;
|
|
|
|
}
|
|
|
|
|
|
LRESULT
|
|
CALLBACK
|
|
ProgressDialogProc(
|
|
HWND hwndDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
ProgressDialogProc - handles the Progress dialog.
|
|
|
|
Arguments:
|
|
|
|
Standard dialog entry
|
|
|
|
Return Value:
|
|
|
|
BOOL - Depending on input message and processing options.
|
|
|
|
--*/
|
|
|
|
{
|
|
int Success;
|
|
|
|
switch (message) {
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
RECT rc;
|
|
|
|
GetWindowRect( _hWndMain, &rc);
|
|
|
|
Success = SetWindowPos(
|
|
hwndDlg,
|
|
_hWndMain,
|
|
( rc.left + 60 ),
|
|
( rc.top + 95 ),
|
|
0,
|
|
0,
|
|
SWP_NOSIZE | SWP_SHOWWINDOW
|
|
);
|
|
|
|
DbgAssert( Success );
|
|
|
|
//
|
|
// Initialize the static text control.
|
|
//
|
|
|
|
//SetDlgItemText( hwndDlg, IDD_FILE, GetString( IDS_DOC_TITLE ) );
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
|
|
if (wParam == IDD_CANCEL) {
|
|
|
|
//
|
|
// If we have hit the cancel button, flip the global flag to cancel,
|
|
// but do not close this dialog yet. A message will be sent to kill
|
|
// this thread.
|
|
//
|
|
|
|
bAbortReport = TRUE;
|
|
|
|
SetDlgItemText( hwndDlg, IDD_FILE, GetString( IDS_CANCEL_REPORT ) );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
PostQuitMessage(0);
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|