/* * EX15WIN.C * * C/Windows Example program for ArchiveLib 2.0 * * Copyright (c) Greenleaf Software, Inc. 1994 - 1996 * All Rights Reserved * * MEMBERS/FUNCTIONS DEMONSTRATED * * ALArchiveFillListBoxDialog() * ALArchiveReadDirectory() * ALArchiveGetStatusCode() * ALArchiveGetStatusDetail() * ALArchiveGetStatusString() * ALArchiveSetError() * ALEntryDuplicate() * * DESCRIPTION * * This example program is a grab bag that uses several of the * archive status and informational functions. You open * an archive by clicking on it from a list box, then see * all the information regarding that archive. * * Note that this program checks for duplicate entries in an archive. * You might have to fiddle with the examples here in order to get * one with a duplicate entry, because we try to avoid that. I * created a duplicate entry by using a binary file editor and just * changing the name of an entry stored at the end of the archive. * * This program is functionally equivalent to EX15WIN.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 #include #include "al.h" #include "ex15win.h" HINSTANCE hInstance; HWND hDlgMain; void SizeFramingWindow( HWND hDlg ); void ReadDir( HWND hDlg ); void UpdateArchiveInfo( HWND HDlg ); /* * Like most of the other examples, this program uses a dialog box as * a main window. This is the dialog procedure for that window, and * it handles all of the user interface, such as buttons, text boxes, * and keystrokes. There is a framing window around this dialog, but * it doesn't do much of anything. */ BOOL AL_EXPORT CALLBACK MainDialogProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) { switch ( message ) { /* * The initialization function fills the list box with the names of all the * archives in this directory. */ case WM_INITDIALOG : SizeFramingWindow( hDlg ); SetWindowText( hDlg, "Windows Example 15" ); #if defined( ZIP ) SetDlgItemText( hDlg, AL_DIR_MASK, "*.ZIP" ); #else SetDlgItemText( hDlg, AL_DIR_MASK, "*.GAL" ); #endif ReadDir( hDlg ); return( TRUE ); /* * WM_COMMAND handles all the button presses and keyboard commands * that come in on the dialog box. */ case WM_COMMAND : switch ( LOWORD( wParam ) ) { /* * If you double click on a file name in the list box, we treat * it the same as if you pressed enter. It goes out and gets the * archive info. */ case AL_INPUT_FILES : { #if defined( AL_FLAT_MODEL ) AL_UNUSED_PARAMETER( lParam ); switch ( HIWORD( wParam ) ) { #else switch ( HIWORD( lParam ) ) { #endif case LBN_DBLCLK : UpdateArchiveInfo( hDlg ); break; } } break; /* * If you press enter, one of two things happen. If the focus is on * the list box, we get all the archive info. If you are on the * text box that contains the wild card mask, pressing enter causes * a new directory to be read into the list box. */ case IDOK : /* User has pressed enter */ if ( GetFocus() == GetDlgItem( hDlg, AL_DIR_MASK ) ) ReadDir( hDlg ); else if ( GetFocus() == GetDlgItem( hDlg, AL_INPUT_FILES ) ) UpdateArchiveInfo( hDlg ); break; case AL_EXIT : case WM_QUIT : case WM_DESTROY : PostMessage( GetParent( hDlg ),WM_DESTROY, 0, 0 ); DestroyWindow( hDlgMain ); hDlgMain = 0; return TRUE; } break; } return FALSE; } /* * This is the function that does most of the interesting stuff in this * example. It gets the file name from the list box, opens the * corresponding archive, then prints out a few status items in * text boxes. * * After that, it goes through the archive and looks for any duplicate * entries. If it finds one, it prints it out in the text box. * * If you don't have an archive to read in this example, run Example 00 * to create one. */ void UpdateArchiveInfo( HWND hDlg ) { char buf[ 128 ]; int i; int len; hALArchive archive; hALEntryList list; hALEntry entry; char version[ 10 ]; i = (int) SendDlgItemMessage( hDlg, AL_INPUT_FILES, LB_GETCURSEL, 0, 0 ); if ( i == LB_ERR ) return; len = (int) SendDlgItemMessage( hDlg, AL_INPUT_FILES, LB_GETTEXTLEN, i, 0 ); if ( i == LB_ERR || len < 0 || len > 127 ) return; SendDlgItemMessage( hDlg, AL_INPUT_FILES, LB_GETTEXT, i, (LPARAM)(LPSTR) buf ); SendDlgItemMessage( hDlg, AL_INPUT_FILES, LB_SETSEL, 0, i ); SetDlgItemText( hDlg, AL_ARCHIVE_NAME, buf ); #if defined( ZIP ) archive = newALPkArchive( buf ); #else archive = newALGlArchive( buf ); #endif ALArchiveFillListBox( archive, hDlg, AL_ARCHIVE_LISTING ); wsprintf( version, "%04x", ALArchiveGetVersion( archive ) ); SetDlgItemText( hDlg, AL_ARCHIVE_VERSION, version ); list = newALListCopyTools( 0 ); ALArchiveReadDirectory( archive, list ); entry = ALEntryListGetFirstEntry( list ); while ( entry ) { if ( ALEntryDuplicate( entry, list ) ) break; entry = ALEntryGetNextEntry( entry ); } if ( entry == 0 ) SetDlgItemText( hDlg, AL_DUPLICATE_ENTRY_NAME, "None" ); else { hALStorage storage = ALEntryGetStorage( entry ); SetDlgItemText( hDlg, AL_DUPLICATE_ENTRY_NAME, ALStorageGetName( storage ) ); ALArchiveSetError( archive, AL_DUPLICATE_ENTRY, "Duplicate entry in archive!" ); } SetDlgItemInt( hDlg, AL_ARCHIVE_STATUS_CODE, ALArchiveGetStatusCode( archive ), 1 ); SetDlgItemText( hDlg, AL_ARCHIVE_STATUS_STRING, ALArchiveGetStatusString( archive ) ); SetDlgItemText( hDlg, AL_ARCHIVE_STATUS_DETAIL, ALArchiveGetStatusDetail( archive ) ); SetFocus( GetDlgItem( hDlg, AL_EXIT ) ); deleteALArchive( archive ); deleteALEntryList( list ); } /* * This function reads a list of wild card files into a list box. * Usually this will be an expansion of "*.GAL", so that it will * show us a list of archives in the current directory. */ void ReadDir( HWND hDlg ) { char buf[ 128 ]; hALExpander files; char AL_DLL_FAR *p; GetDlgItemText( hDlg, AL_DIR_MASK, buf, 128 ); SendDlgItemMessage( hDlg, AL_INPUT_FILES, LB_RESETCONTENT, 0, 0 ); files = newALExpander( buf, 0, AL_UPPER ); while ( ( p = ALExpanderGetNextFile( files ) ) != 0 ) SendDlgItemMessage( hDlg, AL_INPUT_FILES, LB_ADDSTRING, 0, (LPARAM)( (LPSTR) p ) ); SetFocus( GetDlgItem( hDlg, AL_INPUT_FILES ) ); } /* * The main window is nothing more than a shell that exists to manage * the dialog box, take menu commands, and process accelerator keys. */ LONG AL_EXPORT CALLBACK MainWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch ( message ) { case WM_COMMAND: switch( wParam ) { case AL_EXIT : PostQuitMessage( 0 ); } break; case WM_SETFOCUS: SetFocus( hDlgMain ); /* insure that the Dialog Box has the focus */ break; case WM_DESTROY: PostQuitMessage( 0 ); break; } return DefWindowProc( hWnd, message, wParam, lParam ); } /* * WinMain calls registers our class, creates the dialog, and starts the * message pump. */ int PASCAL WinMain( HINSTANCE instance, HINSTANCE previous_instance, LPSTR lpStr, int nCmdShow ) { HWND hWnd; FARPROC lpfn; MSG msg; AL_UNUSED_PARAMETER( lpStr ); hInstance = instance; if ( previous_instance == 0 ) { WNDCLASS wc; wc.style = 0; wc.lpfnWndProc = (WNDPROC) MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = instance; wc.hIcon = LoadIcon( hInstance, "ALIcon" ); wc.hCursor = LoadCursor( 0, IDC_ARROW ); wc.hbrBackground = (HBRUSH) GetStockObject( WHITE_BRUSH ); wc.lpszMenuName = "ALMenu"; wc.lpszClassName = "ALClass"; if ( !RegisterClass( &wc ) ) return FALSE; } hWnd = CreateWindow( "ALClass", "ArchiveLib Example Program", WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, CW_USEDEFAULT, 0, 0, 0, 0, 0, hInstance, NULL ); lpfn = MakeProcInstance( (FARPROC) MainDialogProc, hInstance ); hDlgMain = CreateDialog( hInstance, "ALMainDialog", hWnd, (DLGPROC) lpfn ); ShowWindow( hWnd, (short) nCmdShow ); ShowWindow( hDlgMain, SW_SHOW ); while ( GetMessage ( &msg, 0, 0, 0 ) ) { if ( hDlgMain == NULL || !IsDialogMessage( hDlgMain,&msg ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } } return (msg.wParam); } /* * I need this routine for one purpose only. After the dialog is loaded, * it calls this routine, which adjusts the size of the framing window to * fit exactly around the dialog box. It also moves it to the center of * the screen. */ void SizeFramingWindow( HWND hDlg ) { RECT rect; int x; int y; GetWindowRect( hDlg, &rect ); y = GetSystemMetrics( SM_CYSCREEN ); y -= ( rect.bottom - rect.top ); y -= GetSystemMetrics( SM_CYMENU ) + GetSystemMetrics( SM_CYCAPTION ); y /= 2; x = GetSystemMetrics( SM_CXSCREEN ); x -= rect.right - rect.left; x /= 2; SetWindowPos( GetParent( hDlg ), 0, (short) x, (short) y, (short int) ( rect.right-rect.left ), (short int) ( rect.bottom-rect.top + GetSystemMetrics( SM_CYMENU ) + GetSystemMetrics( SM_CYCAPTION ) ), SWP_NOZORDER ); }