home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
hookkbsm.zip
/
HOOKKBSM.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-07-28
|
79KB
|
1,890 lines
;---------------------------------------------------------------------------;
; M.F.Kaplon Begun:Wed 09-30-1992 Revised:Wed 07-28-1993
; Title : hookkbsm.asm
;
; "Copyright 1992 M.F. Kaplon"
;
; 10-27-92 Add ShutDown Procedure via Shift-Alt-End(White)
; 11-04-92 Add Display of Small Window in Lower Right Hand Corner
; 11-06-92 Display Text in Window for RecordOff,Recording,Playback
; 11-18-92 Finally got Macro Recording to Sort of Work
; 11-30-92 Write out Message Records to Disk File in ASCII #'s in HEX
; S-C-PgDn writes out the current macro to hookkbsm.mac
; 12-07-92 Revised Key Assignments
; Start Macro Recording S-C-LeftArrow(White)
; End Macro Recording S-C-RightArrow(White)
; PlayBack Macro S-C-Ins(White)
; Open Small OS/2 Window S-A-Ins(White)
; Display ProgramDefined HotKeys S-A-? c:\os2\hot-keys.prg
; Display UserDefined HotKeys S-C-? c:\os2\hot-keys.usr
; Write Current Macro to ASCII File S-C-PgDn(White)
; 12-14-92 Add inclusion of WindowNames, obtained from TaskList
; for each Handle obtained when Recording. Window Names will
; be first 28 characters of name in TaskList(this is default width)
; 12-27-92 Restructured to allow revision of hookkbsm.dat and updating
; by hotkey activation. Hot Key Assigned = Shift-Alt-UpArrow
; Displays message DAT Updated in window.
; 04-13-93 Unable to effect release of DLL from Memory. It is FREED
; but somehow there must still be a reference to it since it
; is not released from memory. Replace JMP's with Calls to DLL
; 04-30-93 The reason getting errors on editing file was that some editors
; put Ctrl-Z at EOF and as written was not acceptable. Changed to
; accept that.
; 07-20-93 Changed pusha/popa -> pushad/popad
; Changed toolkt20 -> toolkt21 for compiles etc
; Added switches to command line /s|Scommand_processor This command processor
; is used for Shift-Alt-Ins window and to load the 2 hot-key windows
; 07-21-93 Add Switch /j|J to command line to make HooK non-jumpable
; Make Start Visible Default with option /I|i to start InVisible
; If /I|i is chosen, then window is made visible when Recording
; and playing back Macros in order to show progress. Similarly
; for updating *.dat files.
; Code modified so that when any messages displayed, regardless
; of start modes, HOOK window is visible and displays messages.
; 07-22-93 MAKE NONJUMPABLE The Default /j|J now makes it JUMPABLE
; Option /L|R (Or l|r)to set origin at Lower Left or Lower Right
; Default is Lower Left
;
; 07-28-93 The program will load the command processor being used from
; the environment using COMSPEC and DosScanEnv.
; The user may still pass another on the command line.
;
;
; INITIALIZES,CREATES MESSAGE QUEUE, REGISTERS CLASS,CREATES STANDARD WINDOW
; ESTABLISHES MAIN MESSAGE LOOP, ESTABLISHES MAIN WINDOW PROCEDURE, Reads in
; C:\os2\hookkbsm.dat, Establishes Hook to HK_INPUT and INITIALIZE which are
; procedures in HOOKDLSM.DLL, Receives Filtered Messages from hookdlsm
; where mp1 = Alt/Ctrl flag, mp2 = scan code and
; takes appropriate action. Uses WM_USER+300h to receive message.
;
; For System Function Calls
;
; 1 - Must use the C Calling Convention which means
; Arguments Pushed on Stack in Reverse Order than declared in function
; And the stack pointer reset after call.
; This is done by the MACRO $Call defined in DOSWIN32.MAC
; 2 - Use .MODEL FLAT. When using a pointer, all you have to do is push
; the offset of the variable since in FLAT model everyting is NEAR
; in the 32 bit space
; 3 - Uses a 16K stack
;
; It is assumed that the Developers toolkit for OS/2 2.0 is installed
; on the users C:drive in the default installation. The assembler
; used is MicroSoft's MASM 6.00B
;
; The files needed to create the functioning program are:
; doswin32.mac Macros and Equates used by Program
; hookkbsm.asm Source for Executable Assembled and Linked by mlc-w386.cmd
; hookdlsm.def Define file needed by IMPLIB and LINK386 for DLL
; hookdlsm.asm Source for DLL = Assembled and linked by dll-w386.cmd
; hookkbsm.dat Text File assigning USER defined programs to key strokes,
; read by hookkbsm The user creates this file according to the
; structure outlined in sample. MUST BE LOCATED IN C:\OS2\DLL
; hot-keys.usr Text file Template to be filled in reflecting USER defined
; hotkeys as defined in hookkbsm.dat. This is displayed when
; Shift-Ctrl-/(?) is struck.
; hot-keys.prg Text File containing program defined (hard coded) key
; assignments. Actuated by Shift-Alt-?. DO NOT CHANGE
; BOTH hot-keys.usr and hot-keys.prg must be in C:\os2\
; dll-w386.cmd Command File to create the hookdlsm.dll and copy to c:\os2\dll
; mlc-w386.cmd Command File to Assemble and Link hookkbsm.asm
;
; Except as noted, all files should be in the same directory.
; To assemble and link use the directory holding the above files as default
; and use the commands
; dll-w386 hookdlsm ;creates hookdlsm.dll from hookdlsm.asm,moves to c:\os2\dll
; mlc-w386 hookkbsm ;creates hookkbsm.exe from hookkbsm.asm
;
; hookkbsm.exe is placed in the directory holding the above files
;
; There is one warning message
;
; LINK : warning L4036: no automatic data segment
;
; This message has to do with no DGROUP being defined
; It can be suppressed with DATA NONE in a "DEF" file
;
; A command processor is called into a 2-line window centered in the screen
; by the keystroke combination Shift-Alt-=(white upper keys)
; The default command processor is c:\os2\cmd.exe
; To load a different one to be called in the window pass its entire
; file specification on the command line when hookkbsm is called as
;
; start hookkbsm c:\4os2\4os2.exe
;
; In calling the procedure "Initialize" in hookdlsm.dll values are
; passed and returned in registers and the procedures are called by JUMPs
; after placing the values in the registers, pushing ECS and the offset
; of the return location. The functions examine the registers and take
; appropriate action.
;
; The example uses the 4OS2 command processor
;---------------------------------------------------------------------------;
;USES HOOK HK_INPUT and INITIALIZE: both in HOOKFLSM.DLL
;----------------- PRELIMINARIES ----------------
.386 ;preceeding .MODEL makes USE32 default
.MODEL FLAT,SYSCALL,OS_OS2
;---------- Conditionally required equates -------------
NUMBUFS equ 1 ; Uncomment if need number routines
;DOSERROR equ 1 ; Uncomment if need DosError Messages
TaskListHandle equ 004001CCh ;handle of Task List Window
RecdLnth equ 28
RecdLnth_x_3 equ 28*3
INCL_WINERRORS equ 1
INCL_WIN equ 1
INCL_DOSMEMMGR equ 1
INCL_DOSFILEMGR equ 1
INCL_WINSWITCHLIST equ 1
INCL_GPICONTROL equ 1
INCL_DEV equ 1
INCLUDE doswin32.mac ;macros used by *.asm
INCLUDE c:\toolkt21\asm\os2inc\os2def.inc ;structure defns includes POINTL
INCLUDE c:\toolkt21\asm\os2inc\pmwin.inc ;structure defns POINTL defn required
INCLUDE c:\toolkt21\asm\os2inc\pmgpi.inc ;graphics
INCLUDE c:\toolkt21\asm\os2inc\pmdev.inc ;devices
INCLUDE c:\toolkt21\asm\os2inc\pmerr.inc ;errors
INCLUDE c:\toolkt21\asm\os2inc\pmshl.inc
INCLUDE c:\toolkt21\asm\os2inc\bsememf.inc;memory
INCLUDE c:\toolkt21\asm\os2inc\bsedos.inc ;files
INCLUDELIB c:\toolkt21\os2lib\os2386.lib ;Library
ExecOnKB STRUCT ;Structure used in program-stores data from hook_kb.dat
Exec DWORD ? ;Address of ASCIIZ str - name of exec program
CmdLn DWORD ? ;Address of ASCIIZ str - command line parms
SessT WORD ? ;Session Type
ExecOnKB ENDS ;structure length now = 10
LenExec equ 10 ;length of ExecOn Kb
.STACK 16384 ;16K stack
.DATA
IFDEF NUMBUFS ;To use UNCOMMENT NUMBUFS equate above
$DefineNumBufs
ENDIF
IFDEF DOSERROR
$DOSErrorMessages
ENDIF
; Copyright Notice
notice BYTE "Copyright 1992 M.F. Kaplon"
;------------- handles --------
hab DWORD 0 ;Anchor block Handle
hmq DWORD 0 ;Message Queue Handle
hwndMainFrame DWORD 0 ;Handle to Main Frame Window of application hwndmain
hwndMain DWORD 0 ;Handle to client application window hwndMain
hps DWORD 0 ;Presentation Space Handle
hwndActiveFrame DWORD 0 ;FrameWindowHandle of hwndActive
hwndActive DWORD 0 ;ACtive Window
hwndFocus DWORD 0 ;Window with Current Focus
henum DWORD 0 ;WindowEnumerationHandle
hwndNext0 DWORD 0 ;Temporary Window Handles
hwndNext1 DWORD 0 ;Temporary Window Handles
hwndNext2 DWORD 0 ;Temporary Window Handles
;------------- GPI & DEV variables --------
hdc DWORD 0 ;Device handle
xPelsPerMeter DWORD ? ;horizontal resolution of device in pels per meter
yPelsPerMeter DWORD ? ;vertical resolution of device in pels per meter
DivideByHoriz WORD 23 ;divisor for horizontal
DivideByVert WORD 70 ;divisor for vertical 60 originally
ScreenWidth DWORD 0 ;ScreenWidth in PELS
PspSize SIZEL {0,0} ;Presentaton Space size same as default
;------------- Text Strings --------
szAppName BYTE "Main0",0 ;Class Name of Window Procedure
szWinTitle BYTE "HooK",0 ;Window Title
szDebugMsg BYTE " SwitchHandle",0
textMsgOn BYTE "Recording",0
textMsgPlay BYTE "PlayBack",0
textMsgUpdateDat BYTE "USER Updated",0
msgFileErr BYTE "hookkbsm.dat File format Error - Aborting",0
msgDosLoadModule BYTE " DosLoadModule",0
msgDosQueryProc1Addr BYTE " DosQueryProc1Addr",0
msgDosQueryProc2Addr BYTE " DosQueryProc2Addr",0
;------------- Styles --------
msgBoxStyle DWORD (MB_YESNO OR MB_DEFBUTTON1)
flStyle DWORD WS_SYNCPAINT ; OR CS_HITTEST ;Window Style Automatic Update
flCtlData DWORD (((( FCF_SYSMENU OR \ ;Window Control Styles
FCF_MINMAX) OR \
FCF_SIZEBORDER) OR \
FCF_TASKLIST) OR \
FCF_TITLEBAR ) ; OR \
; FCF_SHELLPOSITION) ;not reqd if sizing
;------------- structures --------
quemsg QMSG {} ;Queue message structure
rect RECTL {,,,} ;Rectangle structure
AltX ExecOnKB 36 dup({0,0,9}) ;Array for Alt-# 0-9,A-Z default Initialization
CtrlX ExecOnKB 36 dup({0,0,9}) ;Array for Ctrl-# 0-9,A-Z default Initialization
WinPosX DWORD 0 ;Window Position x
WinPosY DWORD 0 ;Window Position y
;------------- Miscellaneous --------
parm1 DWORD ? ;handle of window sending message
parm2 DWORD ? ;message id value
parm3 DWORD ? ;message mp1
parm4 DWORD ? ;message mp2
parm5 DWORD ? ;message time
param1 DWORD ? ;mp1 of message
param2 DWORD ? ;mp2 of message
nwritten DWORD ?
Alt_Ctrl DWORD ? ;0/1 if Alt/Ctrl key struck
lookup0 BYTE 'Q'-37h,'W'-37h,'E'-37h,'R'-37h,'T'-37h,'Y'-37h,'U'-37h,'I'-37h,'O'-37h,'P'-37h ;26,32,14,27,29,34,30,18,24,25 ;
lookup1 BYTE 'A'-37h,'S'-37h,'D'-37h,'F'-37h,'G'-37h,'H'-37h,'J'-37h,'K'-37h,'L'-37h ;10,28,13,15,16,17,19,20,21 ;
lookup2 BYTE 'Z'-37h,'X'-37h,'C'-37h,'V'-37h,'B'-37h,'N'-37h,'M'-37h ;35,33,12,31,11,23,22 ;
textPos DWORD DT_CENTER OR DT_VCENTER ;Position of text on screen
ExitMsg BYTE " !! <Esc> Aborts Close Down !!",0
ExitTitle BYTE "Close OS/2 ??",0
RemoveTitle BYTE "Remove HOOKKBSM ??",0
RemoveMsg BYTE " !! <Esc> Aborts Closing TSR !!",0
RecordOn BYTE 0 ;flag indicates MacroRecording Off/On/Playback = 0/1/2
LeftX DWORD 0 ;coordinates for screen rectangle
LowerY DWORD 0
RightX DWORD ?
UpperY DWORD ?
;------------ Specific to TSR Hook use -----
DllLoadError BYTE 100 dup(0) ;Buffer for name of object contributing to error
DllHandle DWORD 0 ;Handle of Dynamic LInk Module returned here
DllFullModName BYTE "c:\os2\dll\hookdlsm.dll",0
DllProcAddr1 DWORD 0 ;address of proc 1 in dynamic link module
DllProcAddr2 DWORD 0 ;address of proc 2 in exec module
;- StartSession structure Offset ------------ Identification --------------
StartData WORD 32 ; 0 Length of Structure for all but Shift-Alt-W
WORD 0 ; 2 Related 0 is independent, 1 is child
WORD 0 ; 4 0/1 Start in Foreground/Background
WORD 0 ; 6 Trace Option 0 is no trace
DWORD 0 ; 8 ProgramTitle 0 uses Program Name
DWORD ? ;12 Address of ASCZII string with fully qualified program name
DWORD 0 ;16 Address of Input Args to Pgm - 0 is none
DWORD 0 ;20 TermQ 0 is no Queue
DWORD 0 ;24 Environment - must be 0 for DOS
WORD 0 ;28 InheritOp 0 Inherits Shell Environment
WORD ? ;30 SessType see p.2-345 of Control Prog Ref.
DWORD ? ;32 ICON File
DWORD ? ;36 PgmHandle
WORD 8000h ;40 SSF_CONTROL_SETPOS 40 PgmControl-use specified size for S-A-Ins
WORD 140 ;42 InitXPos for Shift-Alt-=
WORD 200 ;44 InitYPos for Shift-Alt-=
WORD 350 ;46 InitXSize for Shift-Alt-=
WORD 60 ;48 InitYSize for Shift-Alt-=
SessID DWORD 0 ;receives Session ID for Alt-1
ProcID DWORD 0 ;receives ProcessID for Alt-1
TitleAlt BYTE "Alt- ",0 ;space filled in with 3 or letter
TitleCtl BYTE "Ctl- ",0 ;space filled in with 3 or letter
HotKeyID BYTE ? ;Identifies HotKey Selected
InsProg BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; use command processor in COMSPEC
DisplayUser BYTE "/c type c:\os2\hot-keys.usr & pause & exit",0 ;display User Hot Key Assignments
DisplayPrg BYTE "/c type c:\os2\hot-keys.prg & pause & exit",0 ;display Prog Hot Key Assignments
DosEnvValue BYTE "DPMI_DOS_API=ENABLED",0
;-------------- parameters for memory usage and file opening
memAddr DWORD 0 ;address of memory block
memFlags DWORD 10h OR 3; PAG_COMMIT OR (PAG_WRITE OR PAG_READ) ;read-write access required
JR_Count DWORD 0 ;Count of records recorded
JR_Counter DWORD 0 ;Counter for recording records
PB_Ctr DWORD 0 ;PlayBack record counter
msgParms DWORD 0 ;offset of PlayBackQMSG in dll
MaxCount DWORD 2660 ;Maximum qmsg structure counts
AddrCtr DWORD 0 ;increment counter
loopCtr DWORD 0
fName BYTE "c:\os2\hookkbsm.dat",0 ;Address of data file
fhandle DWORD ? ;Address of Handle for File
fActionTaken DWORD ? ;Address for action taken
fSize DWORD ? ;Logical size of file
fAttribute DWORD 0
fOpenFlag DWORD OPEN_ACTION_OPEN_IF_EXISTS
fOpenMode DWORD OPEN_SHARE_DENYNONE OR OPEN_ACCESS_READWRITE
fExtaBuf DWORD 0 ;no extended attributes
fmName BYTE "c:\hookkbsm.mac",0 ;Address of macro data file
fmhandle DWORD ? ;Address of Handle for File
fmActionTaken DWORD ? ;Address for action taken
fmSize DWORD ? ;Logical size of file
fmAttribute DWORD FILE_NORMAL ;Read or Write
fmOpenFlag DWORD OPEN_ACTION_CREATE_IF_NEW OR OPEN_ACTION_OPEN_IF_EXISTS
fmOpenMode DWORD OPEN_SHARE_DENYNONE OR OPEN_ACCESS_READWRITE
fmExtaBuf DWORD 0 ;no extended attributes
fmWritten DWORD 0 ;bytes written per write
fmPtrLoc DWORD 0 ;File Pointer Locationn
fmBuffer BYTE 82 dup(' '),13,10 ;Buffer for writing a record
fmHeader BYTE "WinHandle MessageID msgParam1 msgParam2 msgTime X_ScreenP Y_ScreenP TaskListName",13,10
NoNameListed BYTE "NoNameinList" ;Error Message
NameHitFlag DWORD 0 ;0/1 Name notin/isin TaskList
HandFromMsg DWORD 0 ;handle from msgQueue
TaskNameAddr DWORD ? ;Address of TaskListName
fpointer0 DWORD ? ;file pointer start file
fpointer1 DWORD ? ;file pointer end file
EOFflag DWORD 0 ;EndOfFile flag
;------------ switch list parameters -------------
numitems DWORD ? ;#items in list
baseaddr DWORD ? ;of SWBLOCK {,}
ClassNameBuf BYTE 20 dup(0) ;Buffer for ClassNameID
CoverPage BYTE "CLASS_COVERPAGE " ;name for comparison
WinTypeFlag DWORD 0 ;0/1 is Text/PM
CurrentTime DWORD ? ;Store Time Delay
UpdateDat DWORD 0 ;FlagFor Update Display
JumpFlag BYTE 0 ;If 1 Make Hook Jumpable
InvFlag BYTE 0 ;If 1 make Invisible
SetOrigin BYTE 0 ;If 1 xorgn,yorgn passed
xorigin BYTE 10 dup(0) ;x origin position
yorigin BYTE 10 dup(0) ;y origin position
posorigin BYTE 0 ;default LowerLeft Corner
EnvVar BYTE "COMSPEC",0 ;Command Processor
PtrToEnvStr DWORD 0 ;P0inter To Env String
.CODE
startup: ;need to do this way with flat model
;---------- Get Command Processor -------
$Call DosScanEnv,offset EnvVar,offset PtrToEnvStr
mov edi,offset InsProg ;address of where to store
mov esi,PtrToEnvStr
.WHILE byte ptr [esi] != 0
mov al, byte ptr[esi]
mov [edi],al
inc esi
inc edi
.ENDW ;do not need term 0 as already there
;---------- GET COMMANDLINE PARMS -------
$GetCmdLine ;macro esi has offset of command line
.WHILE byte ptr[esi] != 0 ;go past program name
inc esi
.ENDW
Inc esi ;now points to 1st space after command name
.WHILE byte ptr[esi] != 0 ;go to end of command line
.WHILE byte ptr[esi] == ' '
inc esi
.ENDW ;below added Tue 07-20-1993
.IF byte ptr[esi] == '/' && (byte ptr[esi+1] == 'j' || byte ptr[esi+1] == 'J')
add esi,2 ;advance for next test
mov JumpFlag,1 ;Flag Indicating Hook to be JUMPABLE
.ENDIF
.IF byte ptr[esi] == '/' && (byte ptr[esi+1] == 'i' || byte ptr[esi+1] == 'I')
add esi,2 ;advance for next test
mov InvFlag,1 ;Set Invisible Flag
.ENDIF
.IF byte ptr[esi] == '/' && (byte ptr [esi+1] == 'S' || byte ptr [esi+1] == 's')
add esi,2 ;go to string passed
mov edi,offset InsProg ;destination
.WHILE byte ptr[esi] != ' ' && byte ptr[esi] != 0 && byte ptr[esi] != '/'
mov al,byte ptr[esi]
mov [edi],al
inc esi
inc edi
.ENDW ;on exit esi,edi point to next place
mov al,0
mov [edi],al ;terminating NULL
.ENDIF
;Get Origin formatted as /O|oxval,yval
.IF byte ptr[esi] == '/' && (byte ptr[esi+1] == 'l' || byte ptr[esi+1] == 'L')
add esi,2 ;advance to next command line aspect
mov posorigin,0
.ENDIF
.IF byte ptr[esi] == '/' && (byte ptr[esi+1] == 'r' || byte ptr[esi+1] == 'R')
add esi,2 ;advance to next command line aspect
mov posorigin,1
.ENDIF
; mov SetOrigin,1 ;Set Origin
; mov edi,offset xorigin
; .WHILE byte ptr[esi] == ' '
; inc esi
; .ENDW
; .WHILE byte ptr[esi] >= '0' && byte ptr[esi] <= '9'
; mov al,[esi]
; mov [edi],al
; inc esi
; inc edi
; .ENDW
; .WHILE byte ptr[esi] == ' '
; inc esi
; .ENDW
; inc esi ;move past ;
; mov edi,offset yorigin
; .WHILE byte ptr[esi] == ' '
; inc esi
; .ENDW
; .WHILE byte ptr[esi] >= '0' && byte ptr[esi] <= '9'
; mov al,[esi]
; mov [edi],al
; inc esi
; inc edi
; .ENDW
.CONTINUE ; see if any more
.ENDW
;---------- ESTABLISH WINDOW ------------
;-----Initialize Window -Anchor block handle returned = hab
$Call WinInitialize,0 ;called with argument 0
mov hab,eax ;return value
.IF hab == NULL
$Alarm0
$Call WinTerminate,hab
$DosExit
.ENDIF
;-----Create MessageQue QueueHandle returned = hmq
$Call WinCreateMsgQueue,hab,0 ; 0 is default size of queue
mov hmq,eax ;returned queue handle
.IF hmq == NULL
$WinErrMsg " : WinCreateMsgQueue"
$DosExit
.ENDIF
;---- Register Window Class Returned value is TRUE or FALSE
$Call WinRegisterClass,hab,offset szAppName,offset MainWinProc,flStyle,0
.IF eax == FALSE
$WinErrMsg " : WinRegisterClass"
$Call WinTerminate,hab
$DosExit
.ENDIF
;---- CreateStandard Window - Returns handle for Main Window Frame and client Window
$Call WinCreateStdWindow,HWND_DESKTOP,WS_VISIBLE,offset flCtlData,offset szAppName,\
offset szWinTitle,0,0,0,offset hwndMain
mov hwndMainFrame,eax ;returned Frame Window handle
.IF eax == 0
$WinErrMsg " : WinCreateStdWindow"
Call ExitWin
.ENDIF
Call GetWinResolution
Call DefineWindowSize
Call SetWindow
.IF InvFlag == 1 ;If this option minimize window
$Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,SWP_MINIMIZE
.ENDIF
;
;The way to proceed is to install a System Hook. This has to go into a DLL
;otherwise it cannot be called by other programs. The procedure in hook_dls
;will inspect WM_CHAR and if the ShiftKey and one of Alt or Ctrl key is down
;and if there is a valid Scan Code THEN
;it redefine the msg ID of that message as WM_USER+cfffh so it goes nowhere
;and then post a message to this program with the mp1 and mp2 parms
;using WM_USER+300h
;------------ IS hookDLSM.DLL LOADED ? -------------------
$Call DosQueryModuleHandle,offset DllFullModName,offset DllHandle
.IF eax == 0 ;module already loaded
$Alarm0
; $WinInfMsg " HOOKDLSM Already Loaded"
.ENDIF
;---- Reads In hookkbsm.dat and writes to memory buffer
Call ReadDatFile
;--------- ALLOCATE MEMORY FOR SWITCH LIST STRUCTURE -------
Call SwitchListAlloc
$Call DosLoadModule,offset DllLoadError,LENGTHOF DllLoadError,offset DllFullModName,offset DllHandle
.IF eax != 0
$WinErrMsg " DosLoadModule"
; Call UnloadKBHook
.ENDIF
.If DllProcAddr1 == 0
$Call DosQueryProcAddr,DllHandle,1,0,offset DllProcAddr1
.IF eax != 0
$WinDebugMessage msgDosQueryProc1Addr
; Call UnloadKBHook
.ENDIF
.ENDIF
.IF DllProcAddr2 == 0
$Call DosQueryProcAddr,DllHandle,2,0,offset DllProcAddr2 ;JournalRecordHook
.IF eax != 0
$WinDebugMessage msgDosQueryProc2Addr
; Call UnloadKBHook
.ENDIF
.ENDIF
$Call WinSetHook,hab,NULLHANDLE,HK_INPUT,DllProcAddr1,DllHandle
.IF eax == 0
$WinErrMsg " WinSetINPUTHook"
Call UnloadKBHook
.ENDIF
;------ pass the window frame handle in ebx
;----- returns PlayBackQMSG in eax
;esp checks before and after call
mov ebx,hwndMainFrame ;value of this
mov eax,0 ;Initialization Identifier
call DllProcAddr2
mov msgParms,eax ;address of message variables from DLL when Recording
;$WinInfMsg " address of msgParms" ;OK
;msgParms offset Variable
; 0 hwnd
; 4 msgID
; 8 mp1
; 12 mp2
; 16 time
; 20 x coordinate (Screen Based)
; 24 y coordinate (Screen Based)
.IF JumpFlag == 0 ;JumpFlag set on command line
Call SetJump ;Sets HOOKKBSM as non-jumpable THIS IS DEFAULT
.ENDIF
;--------- CREATE MAIN MESSAGE LOOP -----------
mml: $Call WinGetMsg,hab,offset quemsg,0,0,0 ;Note: differs from usual
.IF eax == TRUE ;msg loop - done so that program
$Call WinDispatchMsg,hab,offset quemsg ;can only be terminated
jmp mml ;by the keystroke Shift-Alt-Del
.ELSE ;or by Alt-F4 or Alt-Close
Call UnloadKBHOok ;when Window has focus
mov eax,TRUE
jmp mml ;if ESc option chosen
.ENDIF ;as notified from the DLL
;Normally an Exit routine would go here, as indicated below but which
;is commented out. It is not required since it can never be reached.
;---------- EXIT ---------------
;Call UnloadKBHOok
;.ENDIF ;Tue 04-13-1993
;---------------- End of Main Program -------------------
;------------- PROCESS MESSAGE QUEUE FOR hook_KB ------------
;------------------ MainWinProc -----------------
;parm1 = hwnd,parm2 = msg,parm3 = mp1,parm4 = mp2
;this is called from System and so has to do everything itself
MainWinProc Proc Near
;----------- GET PASSED PARAMETERS FROM STACK ------------
push ebp ;return address is 4 bytes and this push is 4 bytes
mov ebp,esp ;so first parameter is 8 bytes from top
mov eax,[ebp+8]
mov parm1,eax ;hwnd
mov eax,[ebp+12]
mov parm2,eax ;msg
mov eax,[ebp+16]
mov parm3,eax ;mp1
mov eax,[ebp+20]
mov parm4,eax ;mp2
mov eax,[ebp+24]
mov parm5,eax ;time of message
;----- RESTORE STACK POINTER AND STACK STATUS ---
mov esp,ebp ;restore stack pointer
pop ebp
pushad ; Tue 07-20-1993 pusha -> pushad
;---------------- WM_CREATE ----------------
.IF parm2 == WM_CREATE
Call InitMainWindow
jmp wm0
.ENDIF
;---------------- WM_PAINT ----------------
.IF parm2 == WM_PAINT ; && parm1 == hwndMain
Call MainPaint
jmp wm0
.ENDIF
;---------------- WM_CHAR ----------------
.IF parm2 == WM_CHAR
Call MainKeyboard
jmp wm0
.ENDIF
;---------------- WM_SIZE ------------
.IF parm2 == WM_SIZE
jmp wm0
.ENDIF
;---------------- WM_USER+300H ----------------
.IF parm2 == WM_USER+300h ;posted message
;if here know that Shift Key was down and at least one of Alt or Ctrl
;GET SCAN CODE AND ALT/CTRL FLAG
mov edx,parm4 ;scan code
mov eax,parm3 ;Alt/Ctrl Flag = 0/1
mov Alt_Ctrl,eax ;Alt-Ctrl flag
;Test for Shift-Alt-Del(white) for Unloading KBHook
.IF edx == 83 && Alt_Ctrl == 0 ; Shift-Alt-Del (White Del key)
Call UnloadKBHook
jmp wm0
.ENDIF
;Test for Shift-Alt-End(white) for CloseDown
.IF edx == 79 && Alt_Ctrl == 0 ;Shift-Alt-End(White)
Call CloseDown ;Tue 04-13-1993
jmp wm0
.ENDIF
;Test for Shift-Ctrl-LeftArrow - Start Record
.IF edx == 75 && Alt_Ctrl == 1 ;Shift-Ctrl-LeftArrow(White)
.IF InvFlag == 1
mov eax,SWP_RESTORE
.ELSE
mov eax,SWP_ACTIVATE
.ENDIF
$Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,EAX
Call RecordMacroON
jmp wm0
.ENDIF
;Test for Shift-Ctrl-RightArrow - Stop Record
.IF edx == 77 && Alt_Ctrl == 1 ;Shift-Ctrl-RightArrow(White)
Call RecordMacroOFF
.IF InvFlag == 1
$Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,SWP_MINIMIZE
.ENDIF
jmp wm0
.ENDIF
;Test for Shift-Ctrl-Ins(white) - Playback Record Parms Basis
.IF edx == 82 && Alt_Ctrl == 1 ;Shift-Ctrl-Ins(White)
.IF InvFlag == 1
mov eax,SWP_RESTORE
.ELSE
mov eax,SWP_ACTIVATE
.ENDIF
$Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,EAX
Call PlaybackMacro
.IF InvFlag == 1
$Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,SWP_MINIMIZE
.ENDIF
jmp wm0
.ENDIF
;Test for Shift_Ctrl-PgDn(White) - Write Macro File Out
.IF edx == 81 && Alt_Ctrl == 1 ;Shift-Ctrl-PgDn(White)
Call WriteMacroAsciiHex
jmp wm0
.ENDIF
;Test for Shift-Ctrl-5(white) - ProgramTestCtrl
.IF edx == 76 && Alt_Ctrl == 1 ;Shift-Ctrl-5(White)
Call ProgramTestCtrl
jmp wm0
.ENDIF
;Test for Shift-Alt-5(white) - ProgramTestAlt
.IF edx == 76 && Alt_Ctrl == 0 ;Shift-Alt-5(White)
Call ProgramTestAlt
jmp wm0
.ENDIF
;Test for Shift-Alt-UpArrow - Call ReadDatFile Update hookkbsm.dat
.IF edx == 72 && Alt_Ctrl == 0 ;Shift-Alt-UpArrow(White)
.IF InvFlag == 1
mov eax,SWP_RESTORE
.ELSE
mov eax,SWP_ACTIVATE
.ENDIF
$Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,EAX
mov UpdateDat,1
$Call WinInvalidateRect,hwndMain,offset rect,TRUE
mov edx,2500
Call TimeDelay
Call ReadDatFile
mov UpdateDat,0
$Call WinInvalidateRect,hwndMain,offset rect,TRUE ;reset
.IF InvFlag == 1
$Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,SWP_MINIMIZE
.ENDIF
jmp wm0
.ENDIF
;ELSE TEST FOR ASSIGNED KEYS
;SETUP DATA STRUCTURES FOR ACTIVATING HOT KEY
;---- Code in this group places the offset into the array ExecOnKB into EDX
.IF edx == 82 && Alt_Ctrl == 0 ;Shift-Alt-Ins
mov esi,offset StartData ;data structure for DosStartSession
mov word ptr StartData,50 ;for Alt-=
mov HotKeyID,'Ω' ;For Program Title
mov edi,offset TitleAlt
mov cl,HotKeyID
mov byte ptr [edi+4],cl
mov dword ptr[esi+8],offset TitleAlt ;program title
$Call WinSetFocus,HWND_DESKTOP,hwndMainFrame ;required for program started to be in foreground
mov eax,offset InsProg ;address of Exec program
mov [esi+12],eax
mov dword ptr[esi+16],0 ;no command line
mov word ptr[esi+30],2 ;Session Type
jmp wmexe
.ELSE
mov word ptr StartData,32
.ENDIF
.IF edx == 53 && Alt_Ctrl == 1 ; Shift-Ctrl-?:/ key
mov esi,offset StartData ;data structure for DosStartSession
mov word ptr StartData,32 ;
mov HotKeyID,'?' ;For Program Title
mov edi,offset TitleAlt
mov cl,HotKeyID
mov byte ptr [edi+4],cl
mov dword ptr[esi+8],offset TitleAlt ;program title
$Call WinSetFocus,HWND_DESKTOP,hwndMainFrame ;required for program started to be in foreground
mov eax,offset InsProg ;address of Exec program
mov [esi+12],eax
mov eax,offset DisplayUser
mov dword ptr[esi+16],eax ; command line
mov word ptr[esi+30],2 ;Session Type
jmp wmexe
.ENDIF
.IF edx == 53 && Alt_Ctrl == 0 ; Shift-Alt-?:/ key
mov esi,offset StartData ;data structure for DosStartSession
mov word ptr StartData,32 ;
mov HotKeyID,'/' ;For Program Title
mov edi,offset TitleAlt
mov cl,HotKeyID
mov byte ptr [edi+4],cl
mov dword ptr[esi+8],offset TitleAlt ;program title
$Call WinSetFocus,HWND_DESKTOP,hwndMainFrame ;required for program started to be in foreground
mov eax,offset InsProg ;address of Exec program
mov [esi+12],eax
mov eax,offset DisplayPrg
mov dword ptr[esi+16],eax ; command line
mov word ptr[esi+30],2 ;Session Type
jmp wmexe
.ENDIF
.IF edx >= 2 && edx <= 11 ;scan code for 1..9,0
.IF edx >= 2 && edx <= 10
sub edx,1 ;convert to number 1 - 9
.ELSE
mov edx,0 ; 0 offset for 0
.ENDIF
mov HotKeyID,dl
add HotKeyID,30h ;convert to ASCII
jmp wmok
.ENDIF
xor ecx,ecx
.IF edx >= 16 && edx <= 25; && edx != 17 ; q,w,e,r,t,y,u,i,o,p
mov esi,offset lookup0
sub edx,16
jmp wmoj
.ENDIF
.IF edx >= 30 && edx <= 38 ; a,s,d,f,g,h,j,k,l
mov esi,offset lookup1
sub edx,30
jmp wmoj
.ENDIF
.IF edx >= 43 && edx <= 50 ;z,x,c,v,b,n,m
mov esi,offset lookup2
sub edx,44
jmp wmoj
.ELSE
jmp wm0
.ENDIF
wmoj: mov cl,byte ptr [esi+edx] ;cl has value - cl+37h is UC letter
mov HotKeyID,cl ;identifies letter
add HotKeyID,37h
xor edx,edx
mov dl,cl
wmok: ;- Alt_Ctrl has Alt_Ctrl Flag and dl has offset into array
.IF edx >= 0 && edx <= 35
xor eax,eax
mov al,dl
mov esi,offset StartData ;data structure for DosStartSession
.IF Alt_Ctrl == 0
mov ebx,offset AltX ;Alt Definitions
mov edi,offset TitleAlt
mov cl,HotKeyID
mov byte ptr [edi+4],cl
mov dword ptr[esi+8],offset TitleAlt ;program title
.ENDIF
.IF Alt_Ctrl == 1
mov ebx,offset CtrlX ;Ctrl Definitions
mov edi,offset TitleCtl
mov cl,HotKeyID
mov byte ptr [edi+4],cl
mov dword ptr[esi+8],offset TitleCtl ;program title
.ENDIF
mov cl,LenExec
mul cl ;Structure Length ten
add ebx,eax ;element # of structure
;[ebx+8] != 9 is flag that keystroke is assigned
.IF word ptr [ebx+8] != 9
$Call WinSetFocus,HWND_DESKTOP,hwndMainFrame ;required for program started to be in foreground
mov eax,[ebx] ;address of Exec program
mov [esi+12],eax
mov eax,[ebx+4] ;address of command line
mov [esi+16],eax
mov ax,word ptr [ebx+8] ;Session type
mov [esi+30],ax
.IF ax == 4 || ax == 7 ;set environment string DPMI_DOS_API for Borland IDE
mov dword ptr[esi+24],offset DosEnvValue
.ELSE
mov dword ptr[esi+24],0 ;default value reset
.ENDIF
;GO THRU SWITCH LIST TO SEE IF HOT KEY ACTIVE
;-- called before DosStartSession to see if program loaded
;-- esi=offset into StartData
;-- go thru Switch List to see if loaded and if so switch to
;-- The test made on 4th char of TitleAlt/TitleCtl which
;-- is the title in the window and Task List
wmexe: pushad ; Tue 07-20-1993 pusha -> pushad
$NumSwitchListEntries
mov numitems,eax ;number of switch list entries
dec numitems
Call GetSwitchList ;activate structure
mov edi,baseaddr ;address of switch list
mov ecx,0
.IF Alt_Ctrl == 0
mov bl,'A'
.ELSE
mov bl,'C'
.ENDIF
.WHILE ecx < numitems ;starts at offset 0
mov al,byte ptr[edi+40] ;5-th char TaskList title
mov dl,byte ptr[edi+36] ;1stChar of Title A/C
;IF ACTIVE SWITCH TO
.IF al == HotKeyID && bl == dl
;Now Switch to that window - get switch handle
mov eax,[edi+4]
$Call WinSwitchToProgram,eax
popad ; Tue 07-20-1993 popa ->popad
jmp wm0 ;do not reload
.ENDIF
inc ecx
add edi,swblksize ;next element in structure
.ENDW
popad ;Tue 07-20-1993 popa ->popad
;ELSE ACTIVATE HOT KEY PROGRAM
$Call DosStartSession,esi,offset SessID,offset ProcID
.ENDIF
.ENDIF
.ENDIF ;End WM_USER+300h
wm0:popad ; Tue 07-20-1993 popa ->popad
;----- Default Procedure * Return Value in eax ------
$Call WinDefWindowProc,parm1,parm2,parm3,parm4
ret
MainWinProc endp
;-------------- MainPaint * WM_PAINT --------------
MainPaint proc
$Call WinBeginPaint,hwndMain,NULL,offset rect ;offset rect
mov hps,eax ;returns cache presentation space handle
$Call WinQueryWindowRect,hwndMain,offset rect
$Call WinFillRect,hps,offset rect,CLR_YELLOW ;SYSCLR_WINDOW
.IF RecordOn == 1
$Call WinDrawText,hps,-1,offset textMsgOn,offset rect,CLR_BLUE,CLR_YELLOW,TextPos
.ENDIF
.IF RecordOn == 2
$Call WinDrawText,hps,-1,offset textMsgPlay,offset rect,CLR_BLUE,CLR_YELLOW,TextPos
.ENDIF
.IF UpdateDat == 1
$Call WinDrawText,hps,-1,offset textMsgUpdateDat,offset rect,CLR_BLUE,CLR_YELLOW,TextPos
.ENDIF
$Call WinEndPaint,hps
mov eax,TRUE
ret
MainPaint endp
;-------------- InitMainWindow * WM_CREATE --------------
;var1 = hwnd, var2 = mp1, var3 = mp2
InitMainWindow Proc
$Call WinDefWindowProc,parm1,parm2,parm3,parm4
ret
InitMainWindow Endp
;-------------- MainKeyBoard * WM_CHAR --------------
;var1 = mp1,var2 = mp2,var3 = hwnd
MainKeyBoard Proc
$Call WinDefWindowProc,parm1,parm2,parm3,parm4
ret
MainKeyBoard Endp
ExitWin Proc
$Call WinDestroyMsgQueue,hmq
$Call WinTerminate,hab
$Call DosFreeModule,DllHandle
$DosExit ;so exit
ret
ExitWin Endp
SwitchListAlloc Proc ;allocate memory for a switch list of 30
mov ecx,00000002h ;write access flags for Dos alloc
or ecx,00000010h ;page commit
$Call DosAllocMem,offset baseaddr,3000,ecx
.IF eax != 0
$WinErrMsg " : DosAllocMem SwitchList"
Call Exitwin
.ENDIF
ret
SwitchListAlloc Endp
GetSwitchList Proc ;puts address into baseaddr
pushad
$Call WinQuerySwitchList,hab,baseaddr,3000
.IF eax == 0
$WinErrMsg " : WinQuerySwitchList"
Call ExitWin
.ENDIF
popad
ret
GetSwitchList Endp
;---- This procedure uses the handle returned from the message and uses
;---- that to obtain the first 24 characters of the name associated
;---- with that handle from SwitchList for which space is already allocated
;---- this is called with handle in eax
GetNameFromHandle Proc
pusha
$Call WinQuerySwitchList,hab,baseaddr,3000
mov numitems,eax ;number of switch list entries
mov edi,baseaddr ;address of switch list
mov ecx,1
mov NameHitFlag,0 ;reset
mov eax,HandFromMsg
.WHILE ecx <= numitems ;starts at offset 0
;--- This group displays SwitchList Title and Iconsn
.IF eax == [edi+8] ;hwnd of FrameWindow of Program returned by msgQueue
mov NameHitFlag,1
mov eax,edi
add eax,36 ;address of name
mov TaskNameAddr,eax
.BREAK
.ENDIF
; .IF eax == [edi+12] ;hwnd of FrameWindow of Program returned by msgQueue
; mov NameHitFlag,1 ;ICON
; mov eax,edi
; add eax,36 ;address of name
; mov TaskNameAddr,eax
; .BREAK
; .ENDIF; Not Required
; .IF eax == [edi+16] ;hwnd of FrameWindow of Program returned by msgQueue
; mov NameHitFlag,1 ;PROGRAM
; mov eax,edi
; add eax,36 ;address of name
; mov TaskNameAddr,eax
; .BREAK
; .ENDIF ; Plays No role
;;--- Displays programTitles
push ecx
$Call WinQueryWindow,HandFromMsg,QW_PARENT
pop ecx
.BREAK .IF eax == 0
.IF eax == [edi+8] ;hwnd of FrameWindow of Program returned by msgQueue
mov NameHitFlag,1
mov eax,edi
add eax,36 ;address of name
mov TaskNameAddr,eax
.BREAK
.ENDIF
inc ecx
add edi,swblksize ;next element in structure
.ENDW
.IF NameHitFlag == 0
mov TaskNameAddr,offset NoNameListed
.ENDIF
popa
ret
GetNameFromHandle Endp
CloseDown Proc
$Call WinMessageBox,HWND_DESKTOP,HWND_DESKTOP,offset ExitMsg,offset ExitTitle,0,MB_OKCANCEL
.IF eax != MBID_CANCEL
$Call WinShutdownSystem,hab,hmq
$Call DosFreeMem,memAddr
$Call WinReleaseHook,hab,NULL,HK_INPUT,[DllProcAddr1],DllHandle
$Call DosFreeModule,DllHandle
$Call WinDestroyWindow,hwndMainFrame
Call ExitWin
.ENDIF
ret
CloseDown Endp
UnloadKBHook Proc
$Alarm0
$Call WinMessageBox,HWND_DESKTOP,HWND_DESKTOP,offset RemoveMsg,offset RemoveTitle,0,MB_OKCANCEL
.IF eax != MBID_CANCEL
$Call DosFreeMem,memAddr
.IF eax != 0
$WinErrMsg " : DosFreeRegularMem"
.ENDIF
$Call WinReleaseHook,hab,NULL,HK_INPUT,[DllProcAddr1],DllHandle
.IF eax == 0
$WinErrMsg " : WinReleasInputHook-1"
.ENDIF
$Call DosFreeModule,DllHandle
.IF eax != 0
$WinErrMsg " : DosFreeModule-DLL"
.ENDIF
$Call WinDestroyWindow,hwndMainFrame
.IF eax == 0
$WinErrMsg " : WinDestroyWindow"
.ENDIF
Call ExitWin
.ENDIF
mov eax,TRUE
ret
UnloadKBHook Endp
;----- Gets horizontal and vertical window resolution
GetWinResolution Proc
$Call WinGetPS,HWND_DESKTOP
mov hps,eax ;presentation space
.IF eax == 0
$WinErrMsg " WinGetPS"
Call ExitWin
.ENDIF
$Call GpiQueryDevice,hps
mov hdc,eax ;device handle
.IF eax == 0 || eax == HDC_ERROR
$WinErrMsg " GpiQueryDevice"
Call ExitWin
.ENDIF
;---- will get horizontal and vertical resolution in one read
;---- xPelsPerMeter and yPelsPerMeter are consecutive
$Call DevQueryCaps,hdc,CAPS_HORIZONTAL_RESOLUTION,2,offset xPelsPerMeter
.IF eax == 0
$WinErrMsg " : DosQueryCapsHorizontal"
Call ExitWin
.ENDIF
;---- Get Screen Width in PELS
$Call DevQueryCaps,hdc,CAPS_WIDTH,1,offset ScreenWidth
.IF eax == 0
$WinErrMsg " : DosQueryCapsScreenWidth"
Call ExitWin
.ENDIF
$Call WinReleasePS,hps
ret
GetWinResolution Endp
;----- Fills RECT structure for window size ---
DefineWindowSize Proc
xor edx,edx
mov eax,xPelsPerMeter ;basevalue is 2667 before divide
div DivideByHoriz
mov RightX,eax
xor edx,edx
mov eax,yPelsPerMeter ;basevalue is 2667 before divide
div DivideByVert
; mov ebx,eax
; shr eax,2 ;divide eax by 4
; mov UpperY,ebx
; sub UpperY,eax
mov UpperY,eax
mov esi,offset rect
mov eax,LeftX
mov [esi],eax
mov eax,LowerY
mov [esi+4],eax
mov eax,RightX
mov [esi +8],eax
mov eax,UpperY
mov [esi+12],eax
ret
DefineWindowSize Endp
;------ sets window position ---
SetWindow Proc
mov edx,0 ;y-origin
.IF posorigin == 0 ;default Lower Left Corner
mov eax,0
.ENDIF
.IF posorigin == 1 ;lower right corner
mov eax,ScreenWidth
sub eax,Rightx
; sub eax,14 ;attempting to offset a bit
.ENDIF
; .IF SetOrigin == 1 ;origin location passed
; mov eax,0 ;getting errors here I do not understand
; mov edx,0
; $AsciiToDWord yorigin
; mov edx,eax
; $AsciiToDWord xorigin ;result in eax
; .ENDIF
mov ebx,SWP_SIZE
or ebx,SWP_MOVE
$Call WinSetWindowPos,hwndMainFrame,0,eax,edx,RightX,UpperY,ebx
.IF eax == 0
$WinErrMsg " WinSetWindowsPos"
.ENDIF
ret
SetWindow Endp
RecordMacroON Proc ;esp checks before and after call
.IF RecordOn == 0
mov RecordOn,1
mov JR_Count,0 ;as is done in call
mov JR_Counter,0 ;as is done in call
mov AddrCtr,0
$Call WinInvalidateRect,hwndMain,offset rect,TRUE
mov eax,1 ;in DLL JR_Counter->0,RecordOn->1
call DllProcAddr2
.ENDIF
ret
RecordMacroON Endp
; When turning OFF the Shift-Ctrl-Ins key strokes are recorded. They
; contribute 6 counts tothe records. A single key stroke (down and up)
; contributes 2 counts to the record.
RecordMacroOFF Proc ;esp checks before and after calls
pusha
.IF RecordOn == 1
mov RecordOn,0
mov eax,2 ;JR_Counter,JR_Count,RecordON->0
call DllProcAddr2 ;Returns JR_Count in eax
mov JR_Count,eax ;JR_Counter returned from DLL
$Call WinInvalidateRect,hwndMain,offset rect,TRUE
.ENDIF
popa
ret
RecordMacroOFF Endp
;
PlaybackMacro Proc
.IF RecordOn == 1
Call RecordMacroOff
mov JR_Count,0
mov eax,0
$WinInfMsg " !! Aborting Macro Recording - Cannot PlayBack while Recording !!"
ret
.ENDIF
.IF JR_Count == 0 || JR_Count == 8 ;8 is 3 StartUp and 5 Close WM_CHAR messages
mov eax,0
$WinInfMsg " Messages to Play back !!"
ret
.ENDIF
pusha
.IF RecordOn == 0 && JR_Count > 8 ;edi saved across calls
mov eax,JR_Count
sub eax,8 ;Omit 3 start and 5 terminating messages
; $WinInfMsg " Messages to Play back !!"
;---- Temporarily Release HotKey Activation, Display "Playback" message
; If release hook then during playback ALt-x/Ctrl-X assignments appear
; $Call WinReleaseHook,hab,NULLHANDLE,HK_INPUT,DllProcAddr1,DllHandle
mov RecordOn,2
$Call WinInvalidateRect,hwndMain,offset rect,TRUE
;---- Now Playback the Macro
mov esi,msgParms ;block holding playback records
add esi,RecdLnth_x_3 ;no include 1st 3 msgs which are KeyUp of Shift-Ctrl-LeftArrow StartUp Sequence
mov ecx,9 ;Omit 3 start 5 ending messages
mov ebx,0
mov edx,0 ;value for first time around
.WHILE ecx <= JR_Count
.IF edx > 0 ;&& dword ptr[esi+ebx+4] != WM_TIMER
Call TimeDelay
.ENDIF
pusha
Call UseCurWindows
popa
mov eax,[esi+ebx+16] ;time of this just played
inc ecx
add ebx,RecdLnth
mov edx,[esi+ebx+16] ;time of message coming up
sub edx,eax ;time diff between messages
.ENDW
; mov eax,ecx
; dec eax
; $WinInfMsg " Records Played Back"
;---- Restore to non Playback
mov RecordOn,0 ;reset to no recording
$Call WinInvalidateRect,hwndMain,offset rect,TRUE
; $Call WinSetHook,hab,NULLHANDLE,HK_INPUT,DllProcAddr1,DllHandle
.ENDIF
popa
ret
PlaybackMacro Endp
;---- Called by PlayBack to use Current Windows which are either
;---- ACtive Windows (mouse related) or windows with focus (KBoard related)
UseCurWindows Proc
;---- WM_CHAR ----
;--- Code here ensures that window with focus gets WM_CHAR messages
;--- Using only those on the Down Stroke
;Test for Shift-Alt-Ins(white) -
.IF [esi+4+ebx] == WM_CHAR && byte ptr[esi+8+ebx] > 40H ;Up stroke
mov eax,TRUE
ret
.ENDIF
.IF [esi+4+ebx] == WM_CHAR && byte ptr[esi+8+ebx] <= 40H ;down stroke
;--- Code below ensures that no messages called by Alt/Ctrl -Key
;---- Are Called with Shift Alt/Ctrl-Key sequence in playback
;--- If Alt/Ctrl down lowest byte of param2=0
;--- AND next lowest byte is Scan Code of Key Struck
;--- If Shift Down Test Lowest Word of param1 for KC_SHIFT
mov edx,[esi+12+ebx] ;param2
.IF dh != 0 && dl == 0 ;Alt/Ctrl down and ScanCode valid
test [esi+8+ebx],KC_SHIFT ;is ShiftKey Down
jz NoShft
mov eax,TRUE
ret
.ENDIF
NoShft: $Call WinQueryFocus,HWND_DESKTOP ;window handle returned in EAX
$Call WinSendMsg,eax,WM_CHAR,[esi+8+ebx],[esi+12+ebx] ;this works
mov eax,TRUE
ret
.ENDIF
;---- WM_MOUSEMOVE ----
;---- The parms here are x,y coordinates relative to Screen
;---- x = 0, y = 0 is lower left corner
.IF dword ptr[esi+4+ebx] == WM_MOUSEMOVE || dword ptr[esi+4+ebx] == WM_MOUSELAST
$Call WinSetPointerPos,HWND_DESKTOP,dword ptr[esi+20+ebx],dword ptr[esi+24+ebx]
mov eax,TRUE
ret
.ENDIF
;---- WM_BUTTON1DOWN=WM_BUTTON1CLICK WM_SINGLESELECT WM_BUTTON1DBLCLK WM_BUTTON1UP WM_BUTTON1MOTIONSTART || [esi+4+ebx] == WM_BUTTON1MOTIONEND----
.IF [esi+4+ebx] == WM_BUTTON1DOWN || [esi+4+ebx] == WM_BUTTON1UP || [esi+4+ebx] == WM_BUTTON1DBLCLK || [esi+4+ebx] == WM_BUTTON1MOTIONSTART || [esi+4+ebx] == WM_BUTTON1MOTIONEND || [esi+4+ebx] == WM_BUTTON1CLICK ;| [esi+4+ebx] == WM_SINGLESELECT
;--- This gets handle of active window from DeskTop
mov eax,[esi+20+ebx] ;X Screen Coordinate
mov WinPosX,eax
mov eax,[esi+24+ebx] ;Y Screen Coordinate
mov WinPosY,eax
$Call WinWindowFromPoint,HWND_DESKTOP,offset WinPosX,TRUE
mov hwndActive,eax
$Call WinSetFocus,HWND_DESKTOP,eax
$Call WinSendMsg,hwndActive,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx] ;this works
mov eax,TRUE
ret
.ENDIF
;---- WM_BUTTON2DOWN WM_BUTTON2UP WM_BUTTON2DBLCLK WM_BUTTON2MOTIONSTART WM_BUTTON2MOTIONEND WM_BUTTON2CLICK ----
.IF [esi+4+ebx] == WM_BUTTON2DOWN || [esi+4+ebx] == WM_BUTTON2UP || [esi+4+ebx] == WM_BUTTON2DBLCLK || [esi+4+ebx] == WM_BUTTON2MOTIONSTART || [esi+4+ebx] == WM_BUTTON2CLICK
;--- This gets handle of active window from DeskTop
mov eax,[esi+20+ebx] ;X Screen Coordinate
mov WinPosX,eax
mov eax,[esi+24+ebx] ;Y Screen Coordinate
mov WinPosY,eax
$Call WinWindowFromPoint,HWND_DESKTOP,offset WinPosX,TRUE
mov hwndActive,eax
$Call WinSetFocus,HWND_DESKTOP,eax
$Call WinSendMsg,hwndActive,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx] ;this works
mov eax,TRUE
ret
.ENDIF
;---- WM_ related to mouse drag
.IF dword ptr[esi+4+ebx] == WM_BEGINDRAG || dword ptr[esi+4+ebx] == WM_ENDDRAG || [esi+4+ebx] == WM_BUTTON2MOTIONEND
mov eax,[esi+20+ebx] ;X Screen Coordinate
mov WinPosX,eax
mov eax,[esi+24+ebx] ;Y Screen Coordinate
mov WinPosY,eax
$Call WinWindowFromPoint,HWND_DESKTOP,offset WinPosX,TRUE
mov hwndActive,eax
; .IF word ptr [esi+8+ebx] == TRUE ;was from Pointer event
; $Call DosBeep,100,1000
; mov eax,[esi+12+ebx] ;parm2
; xor ecx,ecx
; mov cx,ax ;y coordinate
; shr eax,16 ;move x coord to ax
; $Call WinSetWindowPos,hwndActive,eax,ecx,NULL,NULL,SWP_MOVE
; .IF eax == 0
; $WinInfMsg " WinSetWindowPos Err"
; .ENDIF
; .ENDIF
$Call WinSetFocus,HWND_DESKTOP,hwndActive
$Call WinSendMsg,hwndActive,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx] ;this works
ret
.ENDIF
;---- WM_TASKLIST 082H----
;---- Task List -- TaskList Handle is Unique,TaskListHandle equ 004001CCh
;---- Though there are other messages associated with the Task List
;---- 80H = SH_TASKLIST 81h = SH_TASKMANAGER 82H = SH_TASKACTIVATE
;---- ALso 02f43h and 02F42h seem associated
;---- If this not included Ctrl-Esc not recognized on playback
;---- Inclusion of 2F43H below meakes Macro Playback involving Ctrl-Esc work incorrectly
;---- Inclusion of 81h makes no difference
;---- Inclusion of 80h makes no difference
;---- Inclusion of 1003H makes no difference but does display TaskLIst at End
.IF dword ptr[esi+ebx+4] == 82h
$Call WinSetFocus,HWND_DESKTOP,TaskListHandle
$Call WinSendMsg,TaskListHandle,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx] ;this works
mov eax,TRUE
ret
.ENDIF
; .IF dword ptr[esi+4+ebx] == 405h ;seems to make no difference
; $Call WinSendMsg,00200138h,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx]
; mov eax,TRUE
; ret
; .ENDIF
;---- WM_OPEN WM_CLOSE WM_SYSCOMMAND WM_COMMAND
;---- Inclusion of WM_CONTROL seems to make no difference
.IF [esi+4+ebx] == WM_OPEN || [esi+4+ebx] == WM_CLOSE || [esi+4+ebx] == WM_SYSCOMMAND || [esi+4+ebx] == WM_COMMAND || [esi+4+ebx] == WM_CONTROL || dword ptr[esi+4+ebx] == 185h
$Call WinQueryFocus,HWND_DESKTOP
$Call WinSendMsG,eax,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx] ;this works
mov eax,TRUE
ret
.ENDIF
;---- WM_PAINT ----
.IF [esi+4+ebx] == WM_PAINT
$Call WinQueryFocus,HWND_DESKTOP
$Call WinSendMsg,eax,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx] ;this works
mov eax,TRUE
ret
.ENDIF
;---- WM_USER+300h --- Send message to this Program (= hwndMain) for action
.IF [esi+4+ebx] == WM_USER+300h
$Call WinSendMsg,hwndMain,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx]
mov eax,TRUE
ret
.ENDIF
;---- WM_ALL_THE_REST ----
;---- Since we do not know what window to send them to
; $Call WinQueryFocus,HWND_DESKTOP ;including this and
; $Call WinSendMsg,eax,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx] ;this seems to make no difference
mov eax,TRUE
ret ;for all those messages not explicitly handled
UseCurWindows Endp
;---- Called with window handle in eax -
FocusClass Proc
pusha
$Call WinQueryWindow,eax,QW_NEXT
$Call WinQueryClassName,eax,16,offset ClassNameBuf
mov esi,offset ClassNameBuf
mov edi,offset CoverPage
mov ecx,1
mov ebx,0
.WHILE ecx <= 4
mov eax,[esi+ebx]
cmp eax,[edi+ebx]
jne nomtch
add ebx,4
inc ecx
.ENDW
;---- If got here there was a match
$Call DosBeep,100,1000
nomtch: popa
ret
FocusClass Endp
;--- Will Display handle of Window Under Mouse and WindowClass and
;--- Then whether 16/32 bit
ProgramTestAlt Proc ;Use for testing things Shift-Alt-5(white)
pusha
$Call WinQueryFocus,HWND_DESKTOP ;get current focus to save
push eax
$Call WinQueryPointerPos,HWND_DESKTOP,offset WinPosX
;--- IF FALSE is chosen returns Handle of Frame Window under HWND_DESKTOP
;--- IF TRUE is chosen returns Handle of Actual Window
$Call WinWindowFromPoint,HWND_DESKTOP,offset WinPosX,TRUE
mov hwndNext0,eax
$WinInfMsg " is Handle of Window Under Mouse"
$Call WinQueryClassName,hwndNext0,16,offset ClassNameBuf
mov eax,hwndNext0
$WinDebugMessage ClassNameBuf
$Call WinQueryWindowModel,eax ;0 = 16 bit, 1 = 32 bit
.IF eax == 0
mov eax,16
.ELSEIF eax == 1
mov eax,32
.ENDIF
$WinInfMsg " Bit Window"
$Call WinQueryWindow,hwndNext0,QW_OWNER
$WinInfMsg " is Owner of window under mouse"
$Call WinQueryWindow,hwndNext0,QW_PARENT
$WinInfMsg " is Parent of window under mouse"
pop eax
$Call WinSetFocus,HWND_DESKTOP,eax
popa
ret
ProgramTestAlt Endp
ProgramTestCtrl Proc ;Use for testing things Shift-Ctrl-5(white)
pusha
$Call WinQueryPointerPos,HWND_DESKTOP,offset WinPosX
;--- IF FALSE is chosen returns Handle of Frame Window under HWND_DESKTOP
;--- IF TRUE is chosen returns Handle of Actual Window
$Call WinWindowFromPoint,HWND_DESKTOP,offset WinPosX,FALSE
mov hwndNext0,eax
$WinInfMsg " Handle of Frame of Window Under Mouse"
$Call WinBeginEnumWindows,hwndNext0 ;HWND_DESKTOP
.IF eax == PMERR_INVALID_HWND
$WinInfMsg " Error Calling WinBeginEnumWindows"
jmp xptc
.ENDIF
mov henum,eax ;enum handle
mov ecx,0
.WHILE TRUE
push ecx
$Call WinGetNextWindow,henum
pop ecx
.BREAK .IF eax == 0
.IF ecx == 0
mov hwndNext0,eax
.ENDIF
.IF ecx == 1
mov hwndNext1,eax
.ENDIF
.IF ecx == 2
mov hwndNext2,eax
.ENDIF
push ecx
$WinInfMsg " Window Handle Value"
pop ecx
inc ecx
.ENDW
mov eax,ecx
$WinInfMsg " Number of Windows below Frame Window"
$Call WinEndEnumWindows,henum
mov eax,hwndNext0
$Call WinQueryClassName,hwndNext0,7,offset ClassNameBuf
mov eax,hwndNext0
$WinDebugMessage ClassNameBuf
$WinInfMsg " Enumerating Children of Window to Left"
$Call WinBeginEnumWindows,hwndNext0
.IF eax == PMERR_INVALID_HWND
$WinInfMsg " Error Calling WinBeginEnumWindowsNext0"
jmp xptc
.ENDIF
mov henum,eax ;enum handle
.WHILE TRUE
$Call WinGetNextWindow,henum
.BREAK .IF eax == 0
push eax
$Call WinQueryClassName,eax,20,offset ClassNameBuf
pop eax ;handle back
$WinDebugMessage ClassNameBuf
.ENDW
$Call WinEndEnumWindows,henum
.IF eax == 0
$WinInfMsg " WinEndEnumWindows"
.ENDIF
xptc: popa
ret
ProgramTestCtrl Endp
;------Write Macro to File Format is in ASCII HEX in LF/CR separated records
; hwnd msgID mp1 mp2 Time Coord
; Activated by Shift-Ctrl-PgDn(White)
; Format 8 DWords into HEX using $DWordtoHex, copy from DW_Buff to
; fmBuffer, space separating each Dword then write out to file
; The handle at offset 8 in switch structure is handle of parent
; frame of window identified by hwnd in quemsg structure
WriteMacroAsciiHex Proc ;Write Macro to File
pusha
;--- first set file size to correspond to number of messages
;fsize = #records x 84 + header
mov eax,JR_Count
mov ecx,84
mul ecx
add eax,84 ;header size
mov fmsize,eax
$Call DosOpen,offset fmName,offset fmhandle,offset fmActionTaken,fmsize,fmAttribute,fmOpenFlag,fmOpenMode,fmExtaBuf
.IF eax != 0
$WinInfMsg " : DosOpenMacroFile "
ret
.ENDIF
;----- first write header line
$Call DosWrite,fmhandle,offset fmHeader,84,offset fmWritten
;----- then actual data records
mov ebx,msgParms ;Address of Source
mov edx,JR_Count
.WHILE edx > 0
mov ecx,1
mov esi,offset fmBuffer
.WHILE ecx <= 7
mov eax,[ebx]
.IF ecx == 1 ;handle from msgparms
mov HandFromMsg,eax ;value to be passed
pusha
Call GetNameFromHandle ;value of handle passed in HandFromMsg
mov edi,TaskNameAddr ;address of TaskListName returned
mov edx,1
add esi,70
.WHILE edx <= 12 ;copy to fmBuffer
mov al,byte ptr[edi]
.IF al == 13 || al == 10 ;CR or LF
.BREAK
.ENDIF
mov [esi],al
inc edx
inc esi
inc edi
.ENDW
.IF edx != 13 ;need to fill out with spaces
dec edx
dec esi
.WHILE edx <= 12
mov byte ptr [esi]," "
inc esi
inc edx
.ENDW
.ENDIF
popa
.ENDIF
mov eax,[ebx]
Call DwordToHex
inc ecx
add ebx,4 ;get next parm
add esi,10
.ENDW
dec edx
$Call DosWrite,fmhandle,offset fmBuffer,84,offset fmWritten
.IF eax != 0
$WinInfMsg " : DosWrite "
ret
.ENDIF
.ENDW
$Call DosSetFileSize,fmHandle,fmSize
$Call DosClose,fmHandle
.IF eax != 0
$WinInfMsg " : DosCloseMacroFile "
ret
.ENDIF
popa
ret
WriteMacroAsciiHex Endp
;---- Inserts a TimeDelay of milliseconds in edx register
;---- probably is resolution of timer
TimeDelay Proc
pusha
$Call WinGetCurrentTime,hab
mov CurrentTime,eax
add CurrentTime,edx
.WHILE eax < CurrentTime
$Call WinGetCurrentTime,hab
.ENDW
popa
ret
TimeDelay Endp
ReadDatFile Proc
;---------- IS Data File AVAILABLE AND VALID ? ------------
;---------- First see if hookkbsm.dat exists in proper location ------
mov EOFFlag,0 ;initial value
$Call DosOpen,offset fName,offset fhandle,offset fActionTaken,fsize,fAttribute,fOpenFlag,fOpenMode,fExtaBuf
.IF eax != 0
$WinErrMsg " : DosOpen "
Call ExitWin
.ENDIF
;------- get file size
$Call DosSetFilePtr,fhandle,0,FILE_BEGIN,offset fpointer0
.IF eax != 0
$WinErrMsg " : DosSetFilePtr"
Call ExitWin
.ENDIF
$Call DosSetFilePtr,fhandle,0,FILE_END,offset fpointer1
mov eax,fpointer1
sub eax,fpointer0
mov fsize,eax ;fsize now has file size
add eax,16 ;allow a little leeway in buffer
push eax
;;------- now allocate memory for file buffers
.IF memAddr != 0 ;not first time around
$Call DosFreeMem,memAddr
.IF eax != 0
$WinErrMsg " : DosFreeRegularMem"
.ENDIF
.ENDIF
pop eax ;get back size needed
$Call DosAllocMem,offset memAddr,eax,memFlags
.IF eax != 0
$WinErrMsg " : DosAllocMem FileBuf"
Call ExitWin
.ENDIF
;------Read File Into buffer and Close file -------
;reposition to start of file
$Call DosSetFilePtr,fhandle,0,FILE_BEGIN,offset fpointer0
$Call DosRead,fHandle,memAddr,fsize,offset nwritten
$Call DosClose,fHandle
mov eax,fsize
;------ Reset SessT of ExecONKB arrays to 9
mov edi,offset AltX
mov esi,offset CtrlX
mov ecx,1
mov ebx,10
.WHILE ecx <= 36
mov word ptr[edi+ebx],9
mov word ptr[esi+ebx],9
inc ecx
add ebx,10
.ENDW
;------ Read Buffer and Initialize Arrays ALtX and CtrlX ----
mov esi,memAddr
mov ecx,0 ;Index and Counter for memAddr
.WHILE ecx <= fsize && byte ptr [esi+ecx] != 26 ;Ctrl-Z Fri 04-30-1993
call SkipSpaces ;skip over any initial spaces
.BREAK .IF EOFflag == 1
call SkipCommentsToEOL ;skip over comments and spaces to first valid entry
.BREAK .IF EOFflag == 1
call SkipSpaces ;skip over initial spaces
.BREAK .IF EOFflag == 1
.IF (byte ptr [esi+ecx] == 'A' || byte ptr [esi+ecx] == 'a' || byte ptr [esi+ecx] == 'C' || byte ptr [esi+ecx] == 'c')
inc ecx ;point to number or letter
xor eax,eax
xor edx,edx
mov al,byte ptr [esi+ecx] ;get digit or letter ID
.IF (al >= '0' && al <= '9')
sub al,'0' ;convert to decimal
.ENDIF
.IF al >= 'a'
sub al,32 ;convert to UpperCase
.ENDIF
.IF (al >= 'A' && al <= 'Z')
sub al,37h ;convert to decimal 10 +
.ENDIF
mov dl,LenExec ;Length of Structure 10
mul dl ;ax has offset into array
inc ecx ;right after digit/letter id A/C number
.ELSE
.CONTINUE ;go around again
.ENDIF
.IF byte ptr[esi+ecx - 2] == 'A' || byte ptr[esi+ecx - 2] == 'a'
mov edi,offset AltX ;this is Alt Keys
.ENDIF
.IF byte ptr[esi+ecx - 2] == 'C' || byte ptr[esi+ecx - 2] == 'c'
mov edi,offset CtrlX ;this is a Ctrl Key
.ENDIF
.IF edi == offset AltX || edi == offset CtrlX
mov edx,eax ;edx is offset into array
call SkipSpaces ;go to SessID
.BREAK .IF EOFflag == 1
xor eax,eax
mov al,byte ptr [esi+ecx] ;get sess type
sub al,'0' ;convert to number
mov word ptr [edi + edx+8],ax
inc ecx
call SkipSpaces ;get to Exec string
.BREAK .IF EOFflag == 1
mov eax,esi
add eax,ecx ;offset of exec
mov [edi+edx],eax ;store its address
; have to go to end of Exec string and place a numeric 0 there
.WHILE byte ptr [esi+ecx] != ' '
inc ecx
.ENDW ;exits pointing to end of exec command
.BREAK .IF byte ptr[esi+ecx] != ' '
mov byte ptr [esi+ecx],0
inc ecx
call SkipSpaces ;get next parameter
.BREAK .IF EOFflag == 1
xor eax,eax
.IF byte ptr [esi+ecx]== '0' ;no command line
mov al,byte ptr [esi+ecx]
sub al,'0'
mov [edi+edx+4],eax
.ELSE ;its a string - copy its address
mov eax,esi
add eax,ecx ;offset of command line
.IF byte ptr [esi+ecx] != 22h ;not a "
mov [edi+edx+4],eax ;store command line address
.WHILE byte ptr [esi+ecx] != ' ' && ecx < fsize ;skip until a space
.IF byte ptr[esi+ecx] == lf || byte ptr[esi+ecx] == cr ; LF but no ";"
Call DataFormatErr
.ENDIF
inc ecx
.ENDW ;exits pointing to end of command line
.BREAK .IF ecx >= fsize
mov byte ptr [esi+ecx],0 ;put 0 at end
.ELSE ;first char is a quote
inc ecx ;move beyond it
inc eax
mov [edi+edx+4],eax ;store command line address
.WHILE byte ptr [esi+ecx] != 22h && ecx < fsize ; skip until a "
inc ecx
.ENDW ;exits pointing to final quote
mov byte ptr [esi+ecx],0 ;put 0 at end
.BREAK .IF ecx >= fsize
inc ecx
.BREAK .IF byte ptr[esi+ecx] != ' '
.ENDIF
.ENDIF
.BREAK .IF ecx >= fsize || byte ptr[esi+ecx] == 26 ;Ctrl-Z
xor edi,edi ;reset to 0 so test can be made
.WHILE byte ptr[esi+ecx] != ';' && ecx < fsize ;go to next comment ;
.IF byte ptr[esi+ecx] == lf || byte ptr[esi+ecx] == cr ; LF but no ";"
Call DataFormatErr
.ENDIF
inc ecx
.ENDW
.BREAK .IF ecx >= fsize || byte ptr[esi+ecx] == 26 ;Ctrl-Z
.CONTINUE
.ENDIF
.ENDW
; See if Dat File properly read in
.IF byte ptr [esi+ecx] == 26 ;Ctrl-Z
; $WinErrMsg " : Ctrl-Z here"
.ELSEIF ecx < fsize
Call DataFormatErr
.ENDIF
ret
ReadDatFile Endp
;if there are spaces this exits pointing to next non-space else points to non-space
SkipSpaces proc ;just skips over spaces
.WHILE ecx < fsize && byte ptr [esi+ecx] == ' ' ;spaces
inc ecx
.ENDW
.IF ecx >= fsize || byte ptr [esi+ecx] == 26 ; Ctrl-Z Sat 05-01-1993
mov EOFflag,1
.ENDIF
ret
SkipSpaces endp
SkipCommentsToEOL proc ;skip from ';' to beginning of next line
.IF byte ptr[esi+ecx] == ';' && ecx < fsize ;if a comment
inc ecx
.WHILE byte ptr [esi+ecx] != 0ah && ecx < fsize ;Line feed end of line
inc ecx
.ENDW ;points to 0ah if it exists if not EOF
.IF byte ptr[esi+ecx] == 26 ; Ctrl-Z
mov EOFflag,1
.ENDIF
.ELSE
mov eax,ecx ;bytes processed appears in message
call DataFormatErr
.ENDIF
.IF byte ptr[esi+ecx] != 0ah ;must be EOF
mov EOFflag,1
.ELSE ;it is end of line
inc ecx ;goto next line
.IF ecx >= fsize || byte ptr[esi+ecx] == 26 ; Ctrl-Z
mov EOFflag,1
.ENDIF
.ENDIF
ret
SkipCommentsToEOL endp
DataFormatErr Proc
mov eax,ecx ;bytes processed appears in message
mov ecx,fsize
sub ecx,eax
.IF ecx >= 4 ;Sat 05-01-1993
$WinDebugMessage msgFileErr
call ExitWin ;Fri 04-30-1993
.ENDIF
ret
DataFormatErr EndP
SetJump Proc ;set HOOK to be not jumpable
; $Call DosBeep, 800,275
; $Call DosBeep,1200,275
; $Call DosBeep,2500,275
$NumSwitchListEntries
mov numitems,eax ;number of switch list entries
dec numitems
Call GetSwitchList ;activate structure
mov edi,baseaddr ;address of switch list
mov ecx,0
mov bl,'H'
mov bh,'o'
mov dl,'o'
mov dh,'K'
.WHILE ecx < numitems ;starts at offset 0
.IF bl == [edi+36] && bh == [edi+37] && dl == [edi+38] && dh ==[edi+39]
; $Call DosBeep, 50,1000
;Mark this is as not jumpable
mov dword ptr[edi+32],SWL_NOTJUMPABLE ;jumpable ?
mov esi,edi
add esi,8
$Call WinChangeSwitchEntry,dword ptr[edi+4],esi
.BREAK
.ENDIF
inc ecx
add edi,swblksize ;next element in structure
.ENDW
ret
SetJump Endp
END startup ;required
;---- This procedure places the window handle of the true Client Window
;---- in the variable hwndActive. It obtains the handle of the Frame
;---- Window that is on TOP and uses WinEnumWindows and WinQueryClass
;---- to obtain the handle of the Client window which is the window
;---- with Class not starting with "#"
;GetClientWinHandle Proc
; push ebx
; $Call WinQueryActiveWindow,HWND_DESKTOP
; $WinInfMsg " is Active Frame"
; mov hwndActiveFrame,Eax
; $Call WinBeginEnumWindows,hwndActiveFrame
; .IF eax == PMERR_INVALID_HWND
; $WinInfMsg " Error Calling WinBeginEnumWindows"
; ret
; .ENDIF
; mov henum,eax ;enum handle
; mov eax,hwndActiveFrame ;top window
; $Call WinEndEnumWindows,henum
;
; $Call WinBeginEnumWindows,hwndActiveFrame
; mov henum,eax ;enum handle
; mov ecx,0
; .WHILE TRUE
; $Call WinGetNextWindow,henum
; .IF eax == 0 && ecx == 0 ; no more
; mov eax,hwndActiveFrame
; $WinInfMsg " Has no children"
; .Break
; .Endif
; push eax
; $Call WinQueryClassName,eax,20,offset ClassNameBuf
; pop eax ;handle back
; mov ebx,offset ClassNameBuf
; .IF byte ptr [ebx] != "#" ;this is the Client window
; mov WinFlag,1
; mov hwndActive,eax ;handle of Client window
; $WinDebugMessage ClassNameBuf
; .BREAK ;exit
; .ENDIF
; .ENDW
; .IF WinFlag !=1
; $WinInfMsg "No Match to !=# "
; .ENDIF
; $Call WinEndEnumWindows,henum
; pop ebx
; ret
;GetClientWinHandle Endp
;FillPlaybackDispatchMsg Proc
; mov ebx,0
; mov esi,m_esi
;; mov edi,offset pb_qmsg
; .WHILE ebx <= 20
; mov eax,[esi] ;0:hwnd 4:msgID 8:mp1 12:mp2 16:time 20:coordinates
; mov [edi+ebx],eax ;edi always points to offset of pb_qmsg
; add ebx,4
; add esi,4 ;this leaves esi pointing to next record in block
; .ENDW
; add m_esi,RecdLnth
; $Call WinDispatchMsg,hab,edi ;offset pb_qmsg
; ret
;FillPlaybackDispatchMsg Endp
;---- Determines whether the windowed program is Text or a PM Program.
;---- If the Window Class is SHIELD it is text, otherwise it is PM
;---- Called Only on KeyDown parameter
;WindowType Proc
; pusha
; mov WinTypeFlag,0 ;0 is SHIELD type Window Class
; $Call WinQueryPointerPos,HWND_DESKTOP,offset WinPosX
; ;--- IF FALSE is chosen returns Handle of Frame Window under HWND_DESKTOP
; ;--- IF TRUE is chosen returns Handle of Actual Window
; $Call WinWindowFromPoint,HWND_DESKTOP,offset WinPosX,TRUE
; mov hwndNext0,eax
; $Call WinQueryClassName,hwndNext0,7,offset ClassNameBuf
; mov esi,offset ClassNameBuf
; cmp byte ptr [esi],'S'
; jne NotPM
; cmp byte ptr [esi+1],'H'
; jne NotPM
; cmp byte ptr [esi+2],'I'
; jne NotPM
; cmp byte ptr [esi+3],'E'
; jne NotPM
; cmp byte ptr [esi+4],'L'
; jne NotPM
; cmp byte ptr [esi+5],'D'
; jne NotPM
; mov WinTypeFlag,1
;NotPM: popa
; ret
;WindowType Endp