www.pudn.com > bambam004_source.rar > appack.asm
; #########################################################################
; aPPack is a test piece for MASM programmers using Joergen Ibsen's
; MASM version of "aPLib". It is an implementation of the LZ77 algorithm
; that has the characteristics of reasonable compression speed and very
; high decompression speed.
; This makes it highly suitable for installations and other similar
; applications where decompression speed is critical. The compression
; ratio averages slightly better than PKZIP.
; aPLib is included in MASM32 because it is available from the author
; for personal use as freeware. Commercial applications should contact
; the author for licence of the software.
; This example uses the 'safe function wrappers' for the compression and
; decompression functions, which maintain a header in front of the packed
; data that is used for crc checking and to determine the length of the
; decompressed data so that the decompression algorithm knows the correct
; buffer size to allocate.
; This example uses OLE string memory which is implemented in 2 macros
; for convenience of use. The macros are "stralloc" and "strfree".
; Note that the toolbar bitmap is the single largest component in the
; assembled program.
; #########################################################################
.386
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include aPPack.inc ; local includes for this file
; #########################################################################
.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke InitCommonControls
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax
; #########################################################################
WinMain proc hInst :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD
;====================
; Put LOCALs on stack
;====================
LOCAL wc :WNDCLASSEX
LOCAL msg :MSG
LOCAL Wwd :DWORD
LOCAL Wht :DWORD
LOCAL Wtx :DWORD
LOCAL Wty :DWORD
;==================================================
; Fill WNDCLASSEX structure with required variables
;==================================================
invoke LoadIcon,hInst,500 ; icon ID
mov hIcon, eax
szText szClassName,"aPLib_Class"
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW \
or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, offset WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
m2m wc.hInstance, hInst
mov wc.hbrBackground, COLOR_BTNFACE+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, offset szClassName
m2m wc.hIcon, hIcon
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor, eax
m2m wc.hIconSm, hIcon
invoke RegisterClassEx, ADDR wc
;================================
; Centre window at following size
;================================
mov Wwd, 334
mov Wht, 191
invoke GetSystemMetrics,SM_CXSCREEN
invoke TopXY,Wwd,eax
mov Wtx, eax
invoke GetSystemMetrics,SM_CYSCREEN
invoke TopXY,Wht,eax
mov Wty, eax
invoke CreateWindowEx,WS_EX_LEFT,
ADDR szClassName,
ADDR szDisplayName,
WS_OVERLAPPED or WS_SYSMENU,
Wtx,Wty,Wwd,Wht,
NULL,NULL,
hInst,NULL
mov hWnd,eax
invoke LoadMenu,hInst,600 ; menu ID
invoke SetMenu,hWnd,eax
invoke ShowWindow,hWnd,SW_SHOWNORMAL
invoke UpdateWindow,hWnd
;===================================
; Loop until PostQuitMessage is sent
;===================================
StartLoop:
invoke GetMessage,ADDR msg,NULL,0,0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp StartLoop
ExitLoop:
return msg.wParam
WinMain endp
; #########################################################################
WndProc proc hWin :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD
LOCAL var :DWORD
LOCAL caW :DWORD
LOCAL caH :DWORD
LOCAL hFont :DWORD
LOCAL Rct :RECT
LOCAL hDC :DWORD
LOCAL Ps :PAINTSTRUCT
LOCAL tbab :TBADDBITMAP
LOCAL tbb :TBBUTTON
LOCAL buffer1[128]:BYTE ; these are two spare buffers
LOCAL buffer2[128]:BYTE ; for text manipulation etc..
.if uMsg == WM_COMMAND
; ********************************************************
; first check commands that are not allowed while packing
; ********************************************************
.if Packing == 0
.if wParam == 50
.data
ThreadID dd 0
.code
; start compressing in a thread
mov eax, OFFSET PackFile
invoke CreateThread,NULL,NULL,eax,
NULL,0,ADDR ThreadID
invoke CloseHandle,eax
.elseif wParam == 51
invoke UnpackFile
.elseif wParam == 53
invoke SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL
.elseif wParam == 54
.data
SelectFile db "Select File",0
fPattern db "*.*",0,0
.code
mov szFileName[0], 0
invoke GetFileName,hWin,ADDR SelectFile,ADDR fPattern
.if szFileName[0] != 0
invoke lcase,ADDR szFileName
invoke SetWindowText,hEdit1,ADDR szFileName
.endif
.endif
.endif
; **************************************
; then commands that are always allowed
; **************************************
.if wParam == 52
.data
AboutTtl db "aPLib Pack",0
AboutMsg db "Joergen Ibsen's aPLib example",13,10,\
"Copyright © MASM32 2001",0
.code
invoke ShellAbout,hWin,ADDR AboutTtl,ADDR AboutMsg,hIcon
.elseif wParam == 55
mov ContPack, 0
.elseif wParam == 56
mov killFlag, 1
.endif
.elseif uMsg == WM_SYSCOLORCHANGE
invoke Do_ToolBar,hWin
.elseif uMsg == WM_CREATE
invoke Do_ToolBar,hWin
.data
align 4
caption db "...",0
abortbt db "Stop",0
nullbyte db 0
.code
invoke EditSl,ADDR nullbyte,20,100,253,22,hWin,700
mov hEdit1, eax
invoke PushButton,ADDR caption,hWin,283,100,25,22,54
mov hButn1, eax
invoke Static,ADDR nullbyte,hWin,20,127,240,20,500
mov hStat1, eax
invoke PushButton,ADDR abortbt,hWin,270,127,38,21,55
mov hButn2, eax
invoke GetStockObject,ANSI_VAR_FONT
mov hFont, eax
invoke SendMessage,hEdit1,WM_SETFONT,hFont,0
invoke SendMessage,hButn1,WM_SETFONT,hFont,0
invoke SendMessage,hStat1,WM_SETFONT,hFont,0
invoke SendMessage,hButn2,WM_SETFONT,hFont,0
.elseif uMsg == WM_SIZE
invoke SendMessage,hToolBar,TB_AUTOSIZE,0,0
.elseif uMsg == WM_PAINT
invoke BeginPaint,hWin,ADDR Ps
mov hDC, eax
invoke Paint_Proc,hWin,hDC
invoke EndPaint,hWin,ADDR Ps
return 0
.elseif uMsg == WM_CLOSE
.elseif uMsg == WM_DESTROY
invoke PostQuitMessage,NULL
return 0
.endif
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
WndProc endp
; ########################################################################
TopXY proc wDim:DWORD, sDim:DWORD
shr sDim, 1 ; divide screen dimension by 2
shr wDim, 1 ; divide window dimension by 2
mov eax, wDim ; copy window dimension into eax
sub sDim, eax ; sub half win dimension from half screen dimension
return sDim
TopXY endp
; #########################################################################
Paint_Proc proc hWin:DWORD, hDC:DWORD
LOCAL btn_hi :DWORD
LOCAL btn_lo :DWORD
LOCAL Rct :RECT
invoke GetSysColor,COLOR_BTNHIGHLIGHT
mov btn_hi, eax
invoke GetSysColor,COLOR_BTNSHADOW
mov btn_lo, eax
invoke FrameGrp,hEdit1,hButn2,4,1,0
invoke FrameGrp,hEdit1,hButn2,5,1,1
invoke FrameGrp,hEdit1,hButn2,14,1,0
return 0
Paint_Proc endp
; ########################################################################
PackFile proc Param:DWORD
LOCAL hFile :DWORD
LOCAL ln :DWORD
LOCAL br :DWORD
LOCAL source$ :DWORD
LOCAL dest$ :DWORD
LOCAL working$:DWORD
LOCAL clenth :DWORD
LOCAL szNameFile[128]:BYTE
push esi
push edi
invoke GetWindowText,hEdit1,ADDR szNameFile,128
cmp szNameFile[0], 0
jne @F
invoke MessageBox,hWnd,ADDR plSelect,
ADDR szDisplayName,MB_OK
mov eax, 0
pop edi
pop esi
ret
@@:
invoke CreateFile,ADDR szNameFile,
GENERIC_READ,
FILE_SHARE_READ,
NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
mov hFile, eax
invoke GetFileSize,hFile,NULL
mov ln, eax
stralloc ln
mov source$, eax
invoke ReadFile,hFile,source$,ln,ADDR br,NULL
invoke CloseHandle,hFile
mov esi, source$
lodsd
cmp eax, "23PA" ; test for "AP32" signature
jne @F
.data
beendone db "This file has already been compressed by aPPack",0
.code
invoke MessageBox,hWnd,ADDR beendone,
ADDR szDisplayName,MB_OK
strfree source$
pop edi
pop esi
ret
@@:
invoke aP_max_packed_size,ln
stralloc eax
mov dest$, eax
invoke aP_workmem_size,ln
stralloc eax
mov working$, eax
; ---------------------------------------
; compress source$ and write it to dest$
; ---------------------------------------
mov Packing, 1
mov ContPack, 1
invoke aPsafe_pack,source$,dest$,ln,working$,ADDR cbProc,NULL
mov clenth, eax
.if eax == 0
.data
aborted db "Packing aborted",0
.code
invoke SendMessage,hStat1,WM_SETTEXT,0,ADDR aborted
jmp Abort
.endif
.data
Patn1 db "*.*",0,0
SaveFile1 db "Save File As",0
.code
mov szFileName[0], 0
invoke SaveFileName,hWnd,ADDR SaveFile1,ADDR Patn1
.if szFileName[0] != 0
; -----------------------------------------
; truncate file to zero length if it exists
; -----------------------------------------
invoke CreateFile,ADDR szFileName, ; pointer to name of the file
GENERIC_WRITE, ; access (read-write) mode
NULL, ; share mode
NULL, ; pointer to security attributes
CREATE_ALWAYS, ; how to create
FILE_ATTRIBUTE_NORMAL, ; file attributes
NULL
mov hFile, eax
invoke WriteFile,hFile,dest$,clenth,ADDR br,NULL
invoke CloseHandle,hFile
.endif
Abort:
strfree source$
strfree dest$
strfree working$
mov Packing, 0
pop edi
pop esi
ret
PackFile endp
; ########################################################################
UnpackFile proc
LOCAL hFile :DWORD
LOCAL ln :DWORD
LOCAL br :DWORD
LOCAL dsize :DWORD
LOCAL source$ :DWORD
LOCAL dest$ :DWORD
LOCAL szNameFile[128]:BYTE
push esi
invoke GetWindowText,hEdit1,ADDR szNameFile,128
cmp szNameFile[0], 0
jne @F
invoke MessageBox,hWnd,ADDR plSelect,
ADDR szDisplayName,MB_OK
mov eax, 0
pop esi
ret
@@:
invoke CreateFile,ADDR szNameFile,
GENERIC_READ,
FILE_SHARE_READ,
NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
mov hFile, eax
invoke GetFileSize,hFile,NULL
mov ln, eax
stralloc ln
mov source$, eax
invoke ReadFile,hFile,source$,ln,ADDR br,NULL
invoke CloseHandle,hFile
invoke aPsafe_get_orig_size,source$
mov dsize, eax
test eax,eax
jnz @F
.data
noap db "This file has not been compressed by aPPack",0
.code
invoke MessageBox,hWnd,ADDR noap,
ADDR szDisplayName,MB_OK
strfree source$
pop esi
ret
@@:
stralloc dsize
mov dest$, eax
invoke aPsafe_depack,source$,ln,dest$,dsize
.data
Patn2 db "*.*",0,0
SaveFile2 db "Save File As",0
.code
mov szFileName[0], 0
invoke SaveFileName,hWnd,ADDR SaveFile2,ADDR Patn2
.if szFileName[0] != 0
; -----------------------------------------
; truncate file to zero length if it exists
; -----------------------------------------
invoke CreateFile,ADDR szFileName, ; pointer to name of the file
GENERIC_WRITE, ; access (read-write) mode
NULL, ; share mode
NULL, ; pointer to security attributes
CREATE_ALWAYS, ; how to create
FILE_ATTRIBUTE_NORMAL, ; file attributes
NULL
mov hFile, eax
invoke WriteFile,hFile,dest$,dsize,ADDR br,NULL
invoke CloseHandle,hFile
.endif
strfree source$
strfree dest$
pop esi
ret
UnpackFile endp
; ########################################################################
cbProc proc C orglen:DWORD,len1:DWORD,len2:DWORD,cbparam:DWORD
; ------------------------------------------------------
; This is an application defined callback that receives
; 2 parameters from the "aP_pack" procedure during the
; compression process. Note the "C" calling convention.
; ------------------------------------------------------
LOCAL buff[32]:BYTE
LOCAL buf2[16]:BYTE
invoke dwtoa,len1,ADDR buff
invoke dwtoa,len2,ADDR buf2
.data
arrow db " => ",0
.code
invoke lstrcat,ADDR buff,ADDR arrow
invoke lstrcat,ADDR buff,ADDR buf2
invoke SendMessage,hStat1,WM_SETTEXT,0,ADDR buff
mov eax, ContPack
ret
cbProc endp
; ########################################################################
end start