714dd74636
git-svn-id: svn://10.65.10.50/trunk@5350 c028cbd2-c16b-5b4b-a496-9718f37d4682
237 lines
8.2 KiB
C
Executable File
237 lines
8.2 KiB
C
Executable File
/*
|
|
* EX05WIN.C
|
|
*
|
|
* C/Windows Example program for ArchiveLib 2.0
|
|
*
|
|
* Copyright (c) Greenleaf Software, Inc. 1994 - 1996
|
|
* All Rights Reserved
|
|
*
|
|
* MEMBERS/FUNCTIONS DEMONSTRATED
|
|
*
|
|
* deleteALStorage()
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* This example program demonstrates the capabilities of the debug
|
|
* libraries by doing a few bad things. Most of the bad things
|
|
* should cause an assertion error, with a good explanation of what
|
|
* happened. However, this will only work if you link with the
|
|
* debug versions of the libraries!
|
|
*
|
|
* A lot of the other demo programs in the library use a dummy framing
|
|
* window that surrounds the dialog box. This guy skips all that and
|
|
* just uses the dialog as the main window, period. This makes it
|
|
* nice and simple. In exchange for that, we give up accelerator keys
|
|
* and a few other goodies.
|
|
*
|
|
* This program is functionally equivalent to EX05WIN.CPP. The C version
|
|
* uses the translation layer functions to get the job done, but if
|
|
* you put them side by side, you won't see too much difference.
|
|
*
|
|
* REVISION HISTORY
|
|
*
|
|
* February 1, 1996 2.0A : Second release
|
|
*
|
|
*/
|
|
|
|
#define STRICT
|
|
#include <windows.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <time.h>
|
|
|
|
#include "arclib.h"
|
|
#include "filestor.h"
|
|
#include "ex05win.h"
|
|
|
|
/*
|
|
* I don't have a 32 bit version of CTL3D.DLL for Symantec or Microsoft.
|
|
*/
|
|
|
|
#if defined( AL_BORLAND ) || !defined( AL_FLAT_MODEL )
|
|
#define AL_3D
|
|
#include "ctl3d.h"
|
|
#else
|
|
#define Ctl3dColorChange()
|
|
#define Ctl3dRegister( a )
|
|
#define Ctl3dAutoSubclass( a )
|
|
#define Ctl3dUnregister( a )
|
|
#endif
|
|
|
|
HINSTANCE hInstance;
|
|
BOOL AL_EXPORT CALLBACK AboutDialogProc( HWND, UINT, WPARAM, LPARAM );
|
|
|
|
/*
|
|
* This is the main window procedure, which in this program happens
|
|
* to be a dialog box. This guy responds to a bunch of different button
|
|
* clicks.
|
|
*/
|
|
|
|
BOOL AL_EXPORT CALLBACK MainDialogProc( HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam )
|
|
{
|
|
RECT rc;
|
|
hALStorage hFile;
|
|
|
|
AL_UNUSED_PARAMETER( lParam );
|
|
|
|
switch ( message ) {
|
|
/*
|
|
* The dialog initialization code sets the position for the main window.
|
|
* I also might disable one of the tests, because it won't work for Borland
|
|
* under large model windows. This is because I can't do a heap walk under
|
|
* Windows in large model. I can walk the Windows heap using TOOLHELP.DLL,
|
|
* but since Borland uses a subsegment allocator, I might not find a good
|
|
* pointer there.
|
|
*
|
|
* In the C version, I don't support the code to check for a write past
|
|
* the end of an array. Since memory for the array is allocated using
|
|
* malloc(), not new, I don't have a write picket at the end.
|
|
*/
|
|
case WM_INITDIALOG :
|
|
GetWindowRect( hDlg, &rc );
|
|
SetWindowPos( hDlg,
|
|
0,
|
|
((GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2),
|
|
((GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 2),
|
|
0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
|
|
#if !defined( AL_MICROSOFT ) && defined( AL_LARGE_DATA )
|
|
EnableWindow( GetDlgItem( hDlg, AL_DELETE_BAD_POINTER ), 0 );
|
|
#endif
|
|
EnableWindow( GetDlgItem( hDlg, AL_WRITE_PAST_END ), 0 );
|
|
return( TRUE );
|
|
case WM_SYSCOLORCHANGE :
|
|
Ctl3dColorChange();
|
|
break;
|
|
case WM_COMMAND :
|
|
switch ( wParam ) {
|
|
case AL_EXIT :
|
|
case WM_QUIT :
|
|
case WM_DESTROY :
|
|
EndDialog( hDlg, TRUE );
|
|
return TRUE;
|
|
/*
|
|
* This button causes me to delete an object twice. Since my destructor has
|
|
* a check for the GoodTag() member function, it should catch this easily.
|
|
*/
|
|
case AL_DESTROY_TWICE : {
|
|
hFile = newALFile( "" );
|
|
deleteALStorage( hFile );
|
|
deleteALStorage( hFile );
|
|
return TRUE;
|
|
}
|
|
/*
|
|
* Here is where I try to delete a pointer that isn't in the heap. As long
|
|
* as I can do a heapwalk, I can catch this. I can't do a heap walk under
|
|
* a couple of different memory models under Windows, so this routine gets
|
|
* turned off there. Microsoft was nice enough to provide a heapwalk for
|
|
* large memory model Windows programs. Two points for them.
|
|
*/
|
|
case AL_DELETE_BAD_POINTER : {
|
|
char *p = malloc( 250 );
|
|
deleteALArchive( (hALArchive) p );
|
|
return TRUE;
|
|
}
|
|
/*
|
|
* This just does a bunch of heap stuff. When you have the debug libraries
|
|
* linked in you will see that this takes noticeably longer.
|
|
*/
|
|
case AL_EXERCISE : {
|
|
char **p = malloc( 250 * sizeof( char * ) );
|
|
EnableWindow( GetDlgItem( hDlg, AL_EXERCISE ), 0 );
|
|
srand( (unsigned) time( NULL ) );
|
|
if ( p ) {
|
|
int i;
|
|
for ( i = 0 ; i < 250 ; i++ )
|
|
p[ i ] = malloc( rand() % 250 );
|
|
for ( i = 0 ; i < 250 ; i++ )
|
|
if ( p[ i ] )
|
|
free( p[i] );
|
|
free( p );
|
|
}
|
|
EnableWindow( GetDlgItem( hDlg, AL_EXERCISE ), 1 );
|
|
return TRUE;
|
|
}
|
|
/*
|
|
* Here I create an object, then mung the bytes before it. Under normal
|
|
* circumstances, this would garbage your heap. But in debug mode, we
|
|
* have tossed in a four byte picket at the start of the object, and so
|
|
* we catch this garbage when the object is deleted.
|
|
*/
|
|
case AL_UNDERSHOOT : {
|
|
hFile = newALFile( "" );
|
|
((LPSTR) hFile)[ -1 ] = 0;
|
|
deleteALStorage( hFile );
|
|
return TRUE;
|
|
}
|
|
case AL_ABOUT :
|
|
DialogBox( hInstance, "ALAboutDialog", 0, (DLGPROC) AboutDialogProc );
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* The about box dialog procedure is pretty boring. The most interesting
|
|
* thing it does is center itself on the screen.
|
|
*/
|
|
|
|
BOOL AL_EXPORT CALLBACK AboutDialogProc( HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam )
|
|
{
|
|
RECT rc;
|
|
|
|
AL_UNUSED_PARAMETER( lParam );
|
|
|
|
switch ( message ) {
|
|
case WM_INITDIALOG :
|
|
GetWindowRect( hDlg, &rc );
|
|
SetWindowPos( hDlg,
|
|
0,
|
|
((GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2),
|
|
((GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 2),
|
|
0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
|
|
break;
|
|
case WM_COMMAND :
|
|
switch ( wParam ) {
|
|
case IDOK :
|
|
case AL_EXIT :
|
|
case WM_QUIT :
|
|
case WM_DESTROY :
|
|
EndDialog( hDlg, TRUE );
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* Since we aren't using a framing window in this program, WinMain() really
|
|
* has an easy time of it. If we took away the CTL3D stuff, there would
|
|
* be virtually nothing in here at all.
|
|
*/
|
|
|
|
int PASCAL WinMain( HINSTANCE instance,
|
|
HINSTANCE prev,
|
|
LPSTR cmd_line,
|
|
int cmd_show )
|
|
{
|
|
AL_UNUSED_PARAMETER( prev );
|
|
AL_UNUSED_PARAMETER( cmd_line );
|
|
AL_UNUSED_PARAMETER( cmd_show );
|
|
|
|
hInstance = instance;
|
|
Ctl3dRegister( instance );
|
|
Ctl3dAutoSubclass( instance );
|
|
DialogBox( instance, "ALMainDialog", 0, (DLGPROC) MainDialogProc );
|
|
Ctl3dUnregister( instance );
|
|
return 0;
|
|
}
|