alex 714dd74636 Archive Library versione 2.00
git-svn-id: svn://10.65.10.50/trunk@5350 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-10-09 16:09:54 +00:00

562 lines
16 KiB
C++
Executable File

//
// WINMON.CPP
//
// Source file for ArchiveLib 2.0
//
// Copyright (c) Greenleaf Software, Inc. 1994-1996
// All Rights Reserved
//
// CONTENTS
//
// ALWindowsMessage::operator new()
// ALWindowsMessage::ALWindowsMessage()
// newALWindowsMessage()
// ALWindowsMessage::Progress()
// ALWindowsMessage::ArchiveOperation()
// ALWindowsMessage::~ALWindowsMessage()
//
// DESCRIPTION
//
// This file contains all the code to support the ALWindowsMessage
// monitor class. This monitor class is good for updating progress
// bars and things like that.
//
// REVISION HISTORY
//
// May 21, 1994 1.0A : First release
//
// February 14, 1996 2.0A : New release
//
#include "arclib.h"
#if !defined( AL_IBM )
#pragma hdrstop
#endif
#include "glengn.h"
#include "winmon.h"
#include "wildcard.h"
//
// NAME
//
// ALWindowsMessage::operator new()
//
// PLATFORMS/ENVIRONMENTS
//
// Windows
// C++
//
// SHORT DESCRIPTION
//
// Memory allocator used when ArchiveLib resides in a 16 bit DLL.
//
// C++ SYNOPSIS
//
// #include "arclib.h"
// #include "winmon.h"
//
// void * ALWindowsMessage::operator new( size_t size )
//
// C SYNOPSIS
//
// None.
//
// VB SYNOPSIS
//
// None.
//
// DELPHI SYNOPSIS
//
// None.
//
// ARGUMENTS
//
// size : The number of bytes that the compiler has decided will be
// necessary to construct a new ALWindowsMessage object.
//
// DESCRIPTION
//
// When using a DLL, it is easy to get into a dangerous situation when
// creating objects whose ctor and dtor are both in the DLL. The problem
// arises because when you create an object using new, the memory for
// the object will be allocated from the EXE. However, when you destroy
// the object using delete, the memory is freed inside the DLL. Since
// the DLL doesn't really own that memory, bad things can happen.
//
// But, you say, won't the space just go back to the Windows heap regardless
// of who tries to free it? Maybe, but maybe not. If the DLL is using
// a subsegment allocation scheme, it might do some sort of local free
// before returning the space to the windows heap. That is the point where
// you could conceivably cook your heap.
//
// By providing our own version of operator new inside this class, we
// ensure that all memory allocation for the class will be done from
// inside the DLL, not the EXE calling the DLL.
//
// RETURNS
//
// A pointer to some memory that should have been pulled out of the
// heap for the DLL.
//
// EXAMPLE
//
// SEE ALSO
//
// REVISION HISTORY
//
// February 14, 1996 2.0A : New release
//
#if defined( AL_BUILDING_DLL )
void AL_DLL_FAR * AL_PROTO
ALWindowsMessage::operator new( size_t size ) /* Tag protected function */
{
return ::new char[ size ];
}
#endif
//
// NAME
//
// ALWindowsMessage::ALWindowsMessage()
//
// PLATFORMS/ENVIRONMENTS
//
// Windows
// C++ C VB Delphi
//
// SHORT DESCRIPTION
//
// Create a new ALWindowsMessage monitor.
//
// C++ SYNOPSIS
//
// #include "arclib.h"
// #include "winmon.h"
//
// ALWindowsMessage::ALWindowsMessage( ALMonitorType monitor_type,
// HWND progress_text_window,
// ALWindowsMessageType message_type,
// HWND progress_number_window,
// UINT windows_message = 0 );
//
// C SYNOPSIS
//
// #include "arclib.h"
// #include "winmon.h"
//
// hALMonitor newALWindowsMessage( enum ALMonitorType monitor_type,
// HWND progress_text_window,
// enum ALWindowsMessageType message_type,
// HWND progress_number_window,
// UINT windows_message );
//
// VB SYNOPSIS
//
// Declare Function newALWindowsMessage Lib "AL20LW"
// (ByVal monitor_type%,
// ByVal progress_text_window%,
// ByVal message_type%,
// ByVal progress_number_window%,
// ByVal windows_message%) As Long
//
// DELPHI SYNOPSIS
//
// function newALWindowsMessage( monitor_type : Integer;
// progress_text_window : HWnd;
// message_type : Integer;
// progress_number_window : HWnd;
// windows_message : Integer ) : hALMonitor;
//
// ARGUMENTS
//
// monitor_type : AL_MONITOR_OBJECTS or AL_MONITOR_JOBS
//
// progress_text_window : The handle of the window that is going to
// receive text messages during the archiving
// process.
//
// message_type : AL_SEND_RATIO or AL_SEND_BYTE_COUNT
//
// progress_number_window : The window that is going to receive the
// number, which will either be the byte
// count or the percent complete ratio.
//
// windows_message : The message that will be sent to the
// progress number window. When the message
// is sent, the number is sent in LPARAM
// and WPARAM, so take your pick. If this
// number is set to 0, the message is instead
// sent as test using the set text call.
//
// DESCRIPTION
//
// This constructor has an easy job. It accepts five parameters.
// Four of them just get copied into data members, the fifth gets
// passed up to the constructor for the base class.
//
// This type of monitor is used in Windows programs. Our examples
// make use of it frequently. It sends text messages to edit or static
// text controls, and sends numbers to either text controls or custom
// controls. We use it to dink with our ALGauge control.
//
// RETURNS
//
// When this function is called from C/VB/Delphi it returns an ALMonitor
// handle, which is actually a pointer to the object. In C++, a pointer
// is returned when the object is allocated using new.
//
// EXAMPLE
//
// SEE ALSO
//
// REVISION HISTORY
//
// February 14, 1996 2.0A : New release
//
AL_PROTO
ALWindowsMessage::ALWindowsMessage( ALMonitorType monitor_type, /* Tag public function */
HWND progress_text_window,
ALWindowsMessageType message_type,
HWND progress_number_window,
UINT windows_message /* = 0 */ )
: ALMonitor( monitor_type )
{
mhMessageWindowHandle = progress_text_window;
mhNumberWindowHandle = progress_number_window;
miMessage = windows_message;
mMessageType = message_type;
}
#if !defined( AL_NO_C )
extern "C" AL_LINKAGE hALMonitor AL_FUNCTION
newALWindowsMessage( enum ALMonitorType monitor_type, /* Tag public function */
HWND progress_text_window,
enum ALWindowsMessageType message_type,
HWND progress_number_window,
UINT windows_message )
{
ALWindowsMessage *monitor;
monitor = new ALWindowsMessage( monitor_type,
progress_text_window,
message_type,
progress_number_window,
windows_message );
return (hALMonitor) monitor;
}
#endif
//
// NAME
//
// ALWindows::Progress()
//
// PLATFORMS/ENVIRONMENTS
//
// Windows
// C++
//
// SHORT DESCRIPTION
//
// The progress routine for the Windows message monitor.
//
// C++ SYNOPSIS
//
// #include "arclib.h"
// #include "winmon.h"
//
// void ALWindowsMessage::Progress( long object_tell,
// ALStorage &object );
//
// C SYNOPSIS
//
// None, this is a protected member function for internal use.
//
// VB SYNOPSIS
//
// None, this is a protected member function for internal use.
//
// DELPHI SYNOPSIS
//
// None, this is a protected member function for internal use.
//
// ARGUMENTS
//
// object_tell : The current offset within the object being processed.
// Since this function is always called from inside
// ALStorage::Yield(), the location will always be known.
//
// object : The object being compressed, extracted, copied, or
// whatever.
//
//
// DESCRIPTION
//
// While an archiving operation is in progress, this monitor function
// will get called sometimes. It gets called by the Yield() function
// inside the ALStorage object. The Yield function figures out what
// the current offset is inside the storage object, and passes that
// as a parameter.
//
// Taking that all into account, this routine has to figure out what
// sort of message to send to the window that is getting the progress
// update. Basically, there are two options we have to consider. First,
// we have to figure out whether we are sending the byte count or
// the ratio (the percent of the job/object that we have done.) Second,
// we have to see if there is a windows message or not. If there is
// a windows message, we send the number with SendMessage(). Otherwise
// we format it into ASCII text and send it using SetWindowText().
// SetWindowText() works good for edit controls and the like.
//
// In case you are wondering, we don't have to take into account whether
// we are monitoring individual objects or an entire job. That is because
// that is figured out in the Progress() function in the base class,
// which we call at the start of this function. It calculates the correct
// values of mlByteCount and miRatio based on which type of monitoring
// we are doing, then leaves it up to us here to figure out how and where
// to send the data.
//
//
// RETURNS
//
// Nothing.
//
// EXAMPLE
//
// SEE ALSO
//
// REVISION HISTORY
//
// February 14, 1996 2.0A : New release
//
void AL_PROTO
ALWindowsMessage::Progress( long object_tell, /* Tag public function */
ALStorage AL_DLL_FAR & object )
{
char buf[ 18 ];
//
// This guy figures out what the current byte count and ratio are
//
ALMonitor::Progress( object_tell, object );
if ( mhNumberWindowHandle == 0 )
return;
switch ( mMessageType ) {
case AL_SEND_BYTE_COUNT :
//
// Send the byte count using either SendMessage() or SetWindowText()
//
if ( miMessage == 0 ) {
wsprintf( buf, "%ld", mlByteCount );
SetWindowText( mhNumberWindowHandle, buf );
} else
SendMessage( mhNumberWindowHandle,
(short int) miMessage,
0,
mlByteCount );
break;
case AL_SEND_RATIO :
//
// Send the progress ratio using SendMessage() or SetWindowText()
//
if ( miMessage == 0 ) {
wsprintf( buf, "%d%%", miRatio );
SetWindowText( mhNumberWindowHandle, buf );
} else
SendMessage( mhNumberWindowHandle,
(short int) miMessage,
(short int) miRatio,
miRatio );
default :
break;
}
}
//
// NAME
//
// ALWindowsMessage::ArchiveOperation()
//
// PLATFORMS/ENVIRONMENTS
//
// Windows
// C++
//
// SHORT DESCRIPTION
//
// Update user interface elements after an archiving operation.
//
// C++ SYNOPSIS
//
// #include "arclib.h"
// #include "winmon.h"
//
// void ALWindowsMessage::ArchiveOperation( ALArchiveOperation operation,
// ALArchive *archive,
// ALEntry *job );
//
// C SYNOPSIS
//
// None, this is a protected member function for internal use.
//
// VB SYNOPSIS
//
// None, this is a protected member function for internal use.
//
// DELPHI SYNOPSIS
//
// None, this is a protected member function for internal use.
//
// ARGUMENTS
//
// operation : One of the values from the enumerated type ALArchiveOperation.
// It is simply a list of possible operations that the archive
// operation might take, such as opening a file, closing a
// file, etc.
//
// archive : A pointer to the archive object currently being worked on.
//
// job : A pointer to an ALEntry object that defines the ALStorage
// object presently being worked on.
//
// DESCRIPTION
//
// During the course of an Archiving operation, the functions in
// ALArchive will get the urge to spit out a message. They do
// so by calling this member function. All of the messages should
// be self-explanatory.
//
// It would make a lot of sense to move the message formatting up into
// the base class so I didn't have to duplicate this effort in every
// derived class.
//
// RETURNS
//
// Nothing.
//
// EXAMPLE
//
// SEE ALSO
//
// REVISION HISTORY
//
// February 14, 1996 2.0A : New release
//
#ifdef AL_FLAT_MODEL
#define CHAR_PTR char *
#else
#define CHAR_PTR char _far *
#endif
void AL_PROTO
ALWindowsMessage::ArchiveOperation( ALArchiveOperation operation, /* Tag public function */
ALArchive AL_DLL_FAR *archive,
ALEntry AL_DLL_FAR *job )
{
if ( mhMessageWindowHandle == 0 )
return;
char buf[ 81 ];
switch ( operation ) {
case AL_ARCHIVE_OPEN :
wsprintf( buf, "Opening %s", (CHAR_PTR) archive->GetStorageObject()->mName.GetSafeName() );
break;
case AL_ARCHIVE_CLOSE :
wsprintf( buf, "Closing %s", (CHAR_PTR) archive->GetStorageObject()->mName.GetSafeName() );
break;
case AL_EXTRACTION_OPEN :
wsprintf( buf, "Extracting %s", (CHAR_PTR) job->mpStorageObject->mName.GetSafeName() );
break;
case AL_INSERTION_OPEN :
wsprintf( buf, "Inserting %s", (CHAR_PTR) job->mpStorageObject->mName.GetSafeName() );
break;
case AL_COPY_OPEN :
wsprintf( buf, "Copying %s", (CHAR_PTR) job->mpStorageObject->mName.GetSafeName() );
break;
case AL_EXTRACTION_CLOSE :
case AL_INSERTION_CLOSE :
case AL_COPY_CLOSE :
case AL_END_DIRECTORY_WRITE :
case AL_END_DIRECTORY_READ :
strcpy( buf, "Done" );
break;
case AL_START_DIRECTORY_WRITE :
strcpy( buf, "Writing directory" );
break;
case AL_START_DIRECTORY_READ :
strcpy( buf, "Reading directory" );
break;
}
SetWindowText( mhMessageWindowHandle, buf );
}
//
// NAME
//
// ALWindowsMessage::~ALWindowsMessage()
//
// PLATFORMS/ENVIRONMENTS
//
// Windows
// C++
//
// SHORT DESCRIPTION
//
// The Windows monitor object destructor.
//
// C++ SYNOPSIS
//
// #include "arclib.h"
// #include "winmon.h"
//
// ALWindowsMessage::~ALWindowsMessage();
//
// C SYNOPSIS
//
// None, C programmers should call the base class dtor, deleteALMonitor().
//
// VB SYNOPSIS
//
// None, C programmers should call the base class dtor, deleteALMonitor().
//
// DELPHI SYNOPSIS
//
// None, C programmers should call the base class dtor, deleteALMonitor().
//
// ARGUMENTS
//
// None.
//
// DESCRIPTION
//
// An examination of the code shown here should satisfy you that this
// destructor has nothing to do.
//
// RETURNS
//
// Nothing.
//
// EXAMPLE
//
// SEE ALSO
//
// REVISION HISTORY
//
// February 14, 1996 2.0A : New release
//
AL_PROTO
ALWindowsMessage::~ALWindowsMessage() /* Tag public function */
{
AL_ASSERT( GoodTag(), "~ALWindowsMessage: attempt to delete invalid object" );
}