home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / hookkbsm.zip / HOOKKBSM.ASM < prev    next >
Assembly Source File  |  1993-07-28  |  79KB  |  1,890 lines

  1. ;---------------------------------------------------------------------------;
  2. ; M.F.Kaplon  Begun:Wed  09-30-1992    Revised:Wed  07-28-1993
  3. ; Title : hookkbsm.asm
  4. ;
  5. ; "Copyright 1992 M.F. Kaplon"
  6. ;
  7. ;  10-27-92  Add ShutDown Procedure via Shift-Alt-End(White)
  8. ;  11-04-92  Add Display of Small Window in Lower Right Hand Corner
  9. ;  11-06-92  Display Text in Window for RecordOff,Recording,Playback
  10. ;  11-18-92  Finally got Macro Recording to Sort of Work
  11. ;  11-30-92  Write out Message Records to Disk File in ASCII #'s in HEX
  12. ;            S-C-PgDn writes out the current macro to hookkbsm.mac
  13. ;  12-07-92  Revised Key Assignments
  14. ;            Start Macro Recording              S-C-LeftArrow(White)
  15. ;            End   Macro Recording              S-C-RightArrow(White)
  16. ;            PlayBack Macro                     S-C-Ins(White)
  17. ;            Open Small OS/2 Window             S-A-Ins(White)
  18. ;            Display ProgramDefined HotKeys     S-A-?  c:\os2\hot-keys.prg
  19. ;            Display UserDefined HotKeys        S-C-?  c:\os2\hot-keys.usr
  20. ;            Write Current Macro to ASCII File  S-C-PgDn(White)
  21. ;  12-14-92  Add inclusion of WindowNames, obtained from TaskList
  22. ;            for each Handle obtained when Recording. Window Names will
  23. ;            be first 28 characters of name in TaskList(this is default width)
  24. ;  12-27-92  Restructured to allow revision of hookkbsm.dat and updating
  25. ;            by hotkey activation. Hot Key Assigned = Shift-Alt-UpArrow
  26. ;            Displays message DAT Updated in window.
  27. ;  04-13-93  Unable to effect release of DLL from Memory. It is FREED
  28. ;            but somehow there must still be a reference to it since it
  29. ;            is not released from memory. Replace JMP's with Calls to DLL
  30. ;  04-30-93  The reason getting errors on editing file was that some editors
  31. ;            put Ctrl-Z at EOF and as written was not acceptable. Changed to
  32. ;            accept that.
  33. ;  07-20-93  Changed pusha/popa -> pushad/popad
  34. ;            Changed toolkt20 -> toolkt21 for compiles etc
  35. ;            Added switches to command line /s|Scommand_processor This command processor
  36. ;            is used for Shift-Alt-Ins window and to load  the 2 hot-key windows
  37. ;  07-21-93  Add Switch /j|J to command line to make HooK non-jumpable
  38. ;            Make Start Visible Default with option /I|i to start InVisible
  39. ;            If /I|i is chosen, then window is made visible when Recording
  40. ;            and playing back Macros in order to show progress. Similarly
  41. ;            for updating *.dat files.
  42. ;            Code modified so that when any messages displayed, regardless
  43. ;            of start modes, HOOK window is visible and displays messages.
  44. ;  07-22-93  MAKE NONJUMPABLE The Default /j|J now makes it JUMPABLE
  45. ;            Option /L|R (Or l|r)to set origin at Lower Left or Lower Right
  46. ;            Default is Lower Left
  47. ;
  48. ;  07-28-93  The program will load the command processor being used from
  49. ;            the environment using COMSPEC and DosScanEnv.
  50. ;            The user may still pass another on the command line.
  51. ;
  52. ;
  53. ; INITIALIZES,CREATES MESSAGE QUEUE, REGISTERS CLASS,CREATES STANDARD WINDOW
  54. ; ESTABLISHES MAIN MESSAGE LOOP, ESTABLISHES MAIN WINDOW PROCEDURE, Reads in
  55. ; C:\os2\hookkbsm.dat, Establishes Hook to HK_INPUT and INITIALIZE which are
  56. ; procedures in HOOKDLSM.DLL, Receives Filtered Messages from hookdlsm
  57. ; where mp1 = Alt/Ctrl flag, mp2 = scan code and
  58. ; takes appropriate action. Uses WM_USER+300h to receive message.
  59. ;
  60. ; For System Function Calls
  61. ;
  62. ; 1 - Must use the C Calling Convention which means
  63. ;     Arguments Pushed on Stack in Reverse Order than declared in function
  64. ;     And the stack pointer reset after call.
  65. ;     This is done by the MACRO   $Call   defined in DOSWIN32.MAC
  66. ; 2 - Use  .MODEL FLAT. When using a pointer, all you have to do is push
  67. ;     the offset of the variable since in FLAT model everyting is NEAR
  68. ;     in the 32 bit space
  69. ; 3 - Uses a  16K stack
  70. ;
  71. ; It is assumed that the Developers toolkit for OS/2 2.0 is installed
  72. ; on the users C:drive in the default installation. The assembler
  73. ; used is MicroSoft's MASM 6.00B
  74. ;
  75. ; The files needed to create the functioning program are:
  76. ; doswin32.mac  Macros and Equates used by Program
  77. ; hookkbsm.asm  Source for Executable  Assembled and Linked by mlc-w386.cmd
  78. ; hookdlsm.def  Define file needed by IMPLIB and LINK386 for DLL
  79. ; hookdlsm.asm  Source for DLL = Assembled and linked by dll-w386.cmd
  80. ; hookkbsm.dat  Text File assigning USER defined programs to key strokes,
  81. ;               read by hookkbsm The user creates this file according to the
  82. ;               structure outlined in sample. MUST BE LOCATED IN C:\OS2\DLL
  83. ; hot-keys.usr  Text file Template to be filled in reflecting USER defined
  84. ;               hotkeys as defined in hookkbsm.dat. This is displayed when
  85. ;               Shift-Ctrl-/(?) is struck.
  86. ; hot-keys.prg  Text File containing program defined (hard coded) key
  87. ;               assignments. Actuated by Shift-Alt-?. DO NOT CHANGE
  88. ; BOTH hot-keys.usr and hot-keys.prg must be in C:\os2\
  89. ; dll-w386.cmd  Command File to create the hookdlsm.dll and copy to c:\os2\dll
  90. ; mlc-w386.cmd  Command File to Assemble and Link hookkbsm.asm
  91. ;
  92. ; Except as noted, all files should be in the same directory.
  93. ; To assemble and link use the directory holding the above files as default
  94. ; and use the commands
  95. ; dll-w386  hookdlsm ;creates hookdlsm.dll from hookdlsm.asm,moves to c:\os2\dll
  96. ; mlc-w386  hookkbsm ;creates hookkbsm.exe from  hookkbsm.asm
  97. ;
  98. ; hookkbsm.exe is placed in the directory holding the above files
  99. ;
  100. ; There is one warning message
  101. ;
  102. ; LINK : warning L4036: no automatic data segment
  103. ;
  104. ; This message has to do with no DGROUP being defined
  105. ; It can be suppressed with DATA NONE in a "DEF" file
  106. ;
  107. ; A command processor is called into a 2-line window centered in the screen
  108. ; by the keystroke combination Shift-Alt-=(white upper keys)
  109. ; The default command processor is c:\os2\cmd.exe
  110. ; To load a different one to be called in the window pass its entire
  111. ; file specification on the command line when hookkbsm is called as
  112. ;
  113. ; start hookkbsm c:\4os2\4os2.exe
  114. ;
  115. ; In calling the procedure "Initialize" in hookdlsm.dll values are
  116. ; passed and returned in registers and the procedures are called by JUMPs
  117. ; after placing the values in the registers, pushing ECS and the offset
  118. ; of the return location. The functions examine the registers and take
  119. ; appropriate action.
  120. ;
  121. ; The example uses the 4OS2 command processor
  122. ;---------------------------------------------------------------------------;
  123. ;USES HOOK HK_INPUT and INITIALIZE: both in HOOKFLSM.DLL
  124. ;----------------- PRELIMINARIES ----------------
  125.  
  126. .386             ;preceeding .MODEL makes USE32 default
  127. .MODEL           FLAT,SYSCALL,OS_OS2
  128.  
  129. ;---------- Conditionally required equates -------------
  130. NUMBUFS            equ    1     ; Uncomment if need number routines
  131. ;DOSERROR           equ    1     ; Uncomment if need DosError Messages
  132.  
  133. TaskListHandle     equ    004001CCh  ;handle of Task List Window
  134. RecdLnth           equ    28
  135. RecdLnth_x_3       equ    28*3
  136.  
  137. INCL_WINERRORS     equ    1
  138. INCL_WIN           equ    1
  139. INCL_DOSMEMMGR     equ    1
  140. INCL_DOSFILEMGR    equ    1
  141. INCL_WINSWITCHLIST equ    1
  142. INCL_GPICONTROL    equ    1
  143. INCL_DEV           equ    1
  144.  
  145. INCLUDE        doswin32.mac                      ;macros used by *.asm
  146. INCLUDE        c:\toolkt21\asm\os2inc\os2def.inc ;structure defns includes POINTL
  147. INCLUDE        c:\toolkt21\asm\os2inc\pmwin.inc  ;structure defns POINTL defn required
  148. INCLUDE        c:\toolkt21\asm\os2inc\pmgpi.inc  ;graphics
  149. INCLUDE        c:\toolkt21\asm\os2inc\pmdev.inc  ;devices
  150. INCLUDE        c:\toolkt21\asm\os2inc\pmerr.inc  ;errors
  151. INCLUDE        c:\toolkt21\asm\os2inc\pmshl.inc
  152. INCLUDE        c:\toolkt21\asm\os2inc\bsememf.inc;memory
  153. INCLUDE        c:\toolkt21\asm\os2inc\bsedos.inc ;files
  154. INCLUDELIB     c:\toolkt21\os2lib\os2386.lib     ;Library
  155.  
  156.  
  157. ExecOnKB     STRUCT      ;Structure used in program-stores data from hook_kb.dat
  158.    Exec     DWORD   ?    ;Address of ASCIIZ str - name of exec program
  159.    CmdLn    DWORD   ?    ;Address of ASCIIZ str - command line parms
  160.    SessT     WORD   ?    ;Session Type
  161. ExecOnKB       ENDS      ;structure length now = 10
  162.  
  163. LenExec     equ    10    ;length of ExecOn Kb
  164.  
  165. .STACK    16384          ;16K stack
  166.  
  167. .DATA
  168.  
  169. IFDEF NUMBUFS                      ;To use  UNCOMMENT NUMBUFS equate above
  170.   $DefineNumBufs
  171. ENDIF
  172. IFDEF DOSERROR
  173.    $DOSErrorMessages
  174. ENDIF
  175.  
  176. ; Copyright Notice
  177. notice          BYTE   "Copyright 1992 M.F. Kaplon"
  178.  
  179. ;------------- handles --------
  180. hab             DWORD   0           ;Anchor block Handle
  181. hmq             DWORD   0           ;Message Queue Handle
  182. hwndMainFrame   DWORD   0           ;Handle to Main Frame Window of application hwndmain
  183. hwndMain        DWORD   0           ;Handle to client application window hwndMain
  184. hps             DWORD   0           ;Presentation Space Handle
  185. hwndActiveFrame DWORD   0           ;FrameWindowHandle of hwndActive
  186. hwndActive      DWORD   0           ;ACtive Window
  187. hwndFocus       DWORD   0           ;Window with Current Focus
  188. henum           DWORD   0           ;WindowEnumerationHandle
  189. hwndNext0       DWORD   0           ;Temporary Window Handles
  190. hwndNext1       DWORD   0           ;Temporary Window Handles
  191. hwndNext2       DWORD   0           ;Temporary Window Handles
  192.  
  193. ;------------- GPI & DEV variables --------
  194. hdc             DWORD   0           ;Device handle
  195. xPelsPerMeter   DWORD   ?           ;horizontal resolution of device in pels per meter
  196. yPelsPerMeter   DWORD   ?           ;vertical resolution of device in pels per meter
  197. DivideByHoriz    WORD  23           ;divisor for horizontal
  198. DivideByVert     WORD  70           ;divisor for vertical 60 originally
  199. ScreenWidth     DWORD   0           ;ScreenWidth in PELS
  200. PspSize         SIZEL  {0,0}        ;Presentaton Space size same as default
  201.  
  202. ;------------- Text Strings --------
  203. szAppName             BYTE   "Main0",0    ;Class Name of Window Procedure
  204. szWinTitle            BYTE   "HooK",0     ;Window Title
  205. szDebugMsg            BYTE   "  SwitchHandle",0
  206. textMsgOn             BYTE   "Recording",0
  207. textMsgPlay           BYTE   "PlayBack",0
  208. textMsgUpdateDat      BYTE   "USER Updated",0
  209.  
  210. msgFileErr            BYTE "hookkbsm.dat File format Error - Aborting",0
  211. msgDosLoadModule      BYTE "  DosLoadModule",0
  212. msgDosQueryProc1Addr  BYTE "  DosQueryProc1Addr",0
  213. msgDosQueryProc2Addr  BYTE "  DosQueryProc2Addr",0
  214.  
  215. ;------------- Styles --------
  216. msgBoxStyle     DWORD   (MB_YESNO OR MB_DEFBUTTON1)
  217. flStyle         DWORD   WS_SYNCPAINT ; OR CS_HITTEST ;Window Style Automatic Update
  218. flCtlData       DWORD   (((( FCF_SYSMENU       OR \    ;Window Control Styles
  219.                             FCF_MINMAX)        OR \
  220.                             FCF_SIZEBORDER)    OR \
  221.                             FCF_TASKLIST)      OR \
  222.                             FCF_TITLEBAR ) ;    OR \
  223.                          ;  FCF_SHELLPOSITION)        ;not reqd if sizing
  224.  
  225. ;------------- structures --------
  226. quemsg           QMSG    {}              ;Queue message structure
  227. rect            RECTL    {,,,}           ;Rectangle structure
  228. AltX            ExecOnKB 36 dup({0,0,9}) ;Array for  Alt-# 0-9,A-Z default Initialization
  229. CtrlX           ExecOnKB 36 dup({0,0,9}) ;Array for Ctrl-# 0-9,A-Z default Initialization
  230. WinPosX         DWORD    0               ;Window Position x
  231. WinPosY         DWORD    0               ;Window Position y
  232. ;------------- Miscellaneous --------
  233. parm1           DWORD   ?           ;handle of window sending message
  234. parm2           DWORD   ?           ;message id value
  235. parm3           DWORD   ?           ;message mp1
  236. parm4           DWORD   ?           ;message mp2
  237. parm5           DWORD   ?           ;message time
  238. param1          DWORD   ?           ;mp1 of message
  239. param2          DWORD   ?           ;mp2 of message
  240. nwritten        DWORD   ?
  241. Alt_Ctrl        DWORD   ?           ;0/1 if Alt/Ctrl key struck
  242. 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 ;
  243. 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 ;
  244. lookup2          BYTE   'Z'-37h,'X'-37h,'C'-37h,'V'-37h,'B'-37h,'N'-37h,'M'-37h                         ;35,33,12,31,11,23,22 ;
  245. textPos         DWORD   DT_CENTER OR DT_VCENTER      ;Position of text on screen
  246.  
  247. ExitMsg          BYTE  "          !! <Esc> Aborts Close Down !!",0
  248. ExitTitle        BYTE  "Close OS/2 ??",0
  249. RemoveTitle      BYTE  "Remove HOOKKBSM ??",0
  250. RemoveMsg        BYTE  "         !! <Esc> Aborts Closing TSR !!",0
  251. RecordOn         BYTE   0     ;flag indicates MacroRecording Off/On/Playback = 0/1/2
  252. LeftX           DWORD   0     ;coordinates for screen rectangle
  253. LowerY          DWORD   0
  254. RightX          DWORD   ?
  255. UpperY          DWORD   ?
  256.  
  257. ;------------ Specific to TSR Hook  use -----
  258. DllLoadError     BYTE  100 dup(0)   ;Buffer for name of object contributing to error
  259. DllHandle       DWORD 0             ;Handle of Dynamic LInk Module returned here
  260. DllFullModName   BYTE  "c:\os2\dll\hookdlsm.dll",0
  261. DllProcAddr1    DWORD 0             ;address of proc 1 in dynamic link module
  262. DllProcAddr2    DWORD 0             ;address of proc 2 in exec module
  263.  
  264.  
  265. ;- StartSession structure Offset ------------ Identification --------------
  266. StartData        WORD  32    ; 0  Length of Structure for all but Shift-Alt-W
  267.                  WORD  0     ; 2  Related 0 is independent, 1 is child
  268.                  WORD  0     ; 4  0/1 Start in Foreground/Background
  269.                  WORD  0     ; 6  Trace Option 0 is no trace
  270.                 DWORD  0     ; 8  ProgramTitle 0 uses Program Name
  271.                 DWORD  ?     ;12  Address of ASCZII string with fully qualified program name
  272.                 DWORD  0     ;16  Address of Input Args to Pgm - 0 is none
  273.                 DWORD  0     ;20  TermQ 0 is no Queue
  274.                 DWORD  0     ;24  Environment - must be 0 for DOS
  275.                  WORD  0     ;28  InheritOp 0 Inherits Shell Environment
  276.                  WORD  ?     ;30  SessType see p.2-345 of Control Prog Ref.
  277.                 DWORD  ?     ;32  ICON File
  278.                 DWORD  ?     ;36  PgmHandle
  279.                  WORD 8000h  ;40  SSF_CONTROL_SETPOS 40  PgmControl-use specified size for S-A-Ins
  280.                  WORD 140    ;42  InitXPos  for Shift-Alt-=
  281.                  WORD 200    ;44  InitYPos  for Shift-Alt-=
  282.                  WORD 350    ;46  InitXSize for Shift-Alt-=
  283.                  WORD  60    ;48  InitYSize for Shift-Alt-=
  284.  
  285. SessID          DWORD  0     ;receives Session ID for Alt-1
  286. ProcID          DWORD  0     ;receives ProcessID  for Alt-1
  287. TitleAlt         BYTE  "Alt- ",0  ;space filled in with 3 or letter
  288. TitleCtl         BYTE  "Ctl- ",0  ;space filled in with 3 or letter
  289. HotKeyID         BYTE   ?         ;Identifies HotKey Selected
  290. 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
  291. DisplayUser      BYTE  "/c type c:\os2\hot-keys.usr & pause & exit",0 ;display User Hot Key Assignments
  292. DisplayPrg       BYTE  "/c type c:\os2\hot-keys.prg & pause & exit",0 ;display Prog Hot Key Assignments
  293. DosEnvValue      BYTE  "DPMI_DOS_API=ENABLED",0
  294.  
  295. ;-------------- parameters for memory usage and file opening
  296. memAddr         DWORD   0                        ;address of memory block
  297. memFlags        DWORD 10h OR 3;  PAG_COMMIT OR (PAG_WRITE OR PAG_READ) ;read-write access required
  298. JR_Count        DWORD   0                        ;Count of records recorded
  299. JR_Counter      DWORD   0                        ;Counter for recording records
  300. PB_Ctr          DWORD   0                        ;PlayBack record counter
  301. msgParms        DWORD   0                        ;offset of PlayBackQMSG in dll
  302. MaxCount        DWORD   2660 ;Maximum qmsg structure counts
  303. AddrCtr         DWORD   0    ;increment counter
  304. loopCtr         DWORD   0
  305.  
  306. fName            BYTE    "c:\os2\hookkbsm.dat",0  ;Address of data file
  307. fhandle         DWORD   ?                        ;Address of Handle for File
  308. fActionTaken    DWORD   ?                        ;Address for action taken
  309. fSize           DWORD   ?                        ;Logical size of file
  310. fAttribute      DWORD   0
  311. fOpenFlag       DWORD   OPEN_ACTION_OPEN_IF_EXISTS
  312. fOpenMode       DWORD   OPEN_SHARE_DENYNONE OR OPEN_ACCESS_READWRITE
  313. fExtaBuf        DWORD   0                        ;no extended attributes
  314.  
  315. fmName           BYTE    "c:\hookkbsm.mac",0     ;Address of macro data file
  316. fmhandle        DWORD   ?                        ;Address of Handle for File
  317. fmActionTaken   DWORD   ?                        ;Address for action taken
  318. fmSize          DWORD   ?                        ;Logical size of file
  319. fmAttribute     DWORD   FILE_NORMAL              ;Read or Write
  320. fmOpenFlag      DWORD   OPEN_ACTION_CREATE_IF_NEW OR OPEN_ACTION_OPEN_IF_EXISTS
  321. fmOpenMode      DWORD   OPEN_SHARE_DENYNONE OR OPEN_ACCESS_READWRITE
  322. fmExtaBuf       DWORD   0                        ;no extended attributes
  323. fmWritten       DWORD   0                        ;bytes written per write
  324. fmPtrLoc        DWORD   0                        ;File Pointer Locationn
  325. fmBuffer         BYTE   82 dup(' '),13,10        ;Buffer for writing a record
  326. fmHeader         BYTE   "WinHandle MessageID msgParam1 msgParam2  msgTime  X_ScreenP Y_ScreenP TaskListName",13,10
  327. NoNameListed     BYTE   "NoNameinList"           ;Error Message
  328. NameHitFlag     DWORD   0                        ;0/1 Name notin/isin TaskList
  329. HandFromMsg     DWORD   0                        ;handle from msgQueue
  330. TaskNameAddr    DWORD   ?                        ;Address of TaskListName
  331. fpointer0       DWORD   ?                        ;file pointer start file
  332. fpointer1       DWORD   ?                        ;file pointer end file
  333. EOFflag         DWORD   0                        ;EndOfFile flag
  334.  
  335. ;------------ switch list parameters -------------
  336. numitems        DWORD   ?                        ;#items in list
  337. baseaddr        DWORD   ?                        ;of SWBLOCK {,}
  338.  
  339. ClassNameBuf     BYTE   20 dup(0)                ;Buffer for ClassNameID
  340. CoverPage        BYTE   "CLASS_COVERPAGE "        ;name for comparison
  341. WinTypeFlag     DWORD   0                        ;0/1 is Text/PM
  342. CurrentTime     DWORD   ?                        ;Store Time Delay
  343. UpdateDat       DWORD   0                        ;FlagFor Update Display
  344. JumpFlag         BYTE   0                        ;If 1 Make Hook Jumpable
  345. InvFlag          BYTE   0                        ;If 1 make Invisible
  346. SetOrigin        BYTE   0                        ;If 1 xorgn,yorgn passed
  347. xorigin          BYTE   10 dup(0)                ;x origin position
  348. yorigin          BYTE   10 dup(0)                ;y origin position
  349. posorigin        BYTE   0                        ;default LowerLeft Corner
  350. EnvVar           BYTE   "COMSPEC",0              ;Command Processor
  351. PtrToEnvStr      DWORD  0                        ;P0inter To Env String
  352.  
  353. .CODE
  354.  
  355. startup:                         ;need to do this way with flat model
  356.  
  357. ;----------  Get Command Processor -------
  358. $Call DosScanEnv,offset EnvVar,offset PtrToEnvStr
  359. mov    edi,offset InsProg       ;address of where to store
  360. mov    esi,PtrToEnvStr
  361. .WHILE  byte ptr [esi] != 0
  362.      mov   al, byte ptr[esi]
  363.      mov   [edi],al
  364.      inc   esi
  365.      inc   edi
  366. .ENDW                           ;do not need term 0 as already there
  367.  
  368. ;----------  GET COMMANDLINE PARMS -------
  369. $GetCmdLine                    ;macro esi has offset of command line
  370. .WHILE byte ptr[esi] != 0     ;go past program name
  371.       inc    esi
  372. .ENDW
  373. Inc    esi                     ;now points to  1st space after command name
  374. .WHILE  byte ptr[esi] != 0    ;go to end of command line
  375.      .WHILE byte ptr[esi] == ' '
  376.           inc   esi
  377.      .ENDW          ;below added Tue  07-20-1993
  378.      .IF byte ptr[esi] == '/' && (byte ptr[esi+1] == 'j' || byte ptr[esi+1] == 'J')
  379.          add  esi,2       ;advance for next test
  380.          mov  JumpFlag,1  ;Flag Indicating Hook to be JUMPABLE
  381.      .ENDIF
  382.      .IF byte ptr[esi] == '/' && (byte ptr[esi+1] == 'i' || byte ptr[esi+1] == 'I')
  383.          add  esi,2                ;advance for next test
  384.          mov  InvFlag,1            ;Set Invisible Flag
  385.      .ENDIF
  386.      .IF byte ptr[esi] == '/' && (byte ptr [esi+1] == 'S' || byte ptr [esi+1] == 's')
  387.          add    esi,2     ;go to string passed
  388.          mov    edi,offset InsProg   ;destination
  389.          .WHILE byte ptr[esi] != ' ' && byte ptr[esi] != 0 && byte ptr[esi] != '/'
  390.               mov   al,byte ptr[esi]
  391.               mov   [edi],al
  392.               inc   esi
  393.               inc   edi
  394.          .ENDW                  ;on exit esi,edi point to next place
  395.          mov  al,0
  396.          mov  [edi],al          ;terminating NULL
  397.      .ENDIF
  398.      ;Get Origin formatted as /O|oxval,yval
  399.      .IF byte ptr[esi] == '/' && (byte ptr[esi+1] == 'l' || byte ptr[esi+1] == 'L')
  400.          add  esi,2                ;advance to next command line aspect
  401.          mov  posorigin,0
  402.      .ENDIF
  403.      .IF byte ptr[esi] == '/' && (byte ptr[esi+1] == 'r' || byte ptr[esi+1] == 'R')
  404.          add  esi,2                ;advance to next command line aspect
  405.          mov  posorigin,1
  406.      .ENDIF
  407. ;         mov  SetOrigin,1          ;Set Origin
  408. ;         mov  edi,offset xorigin
  409. ;         .WHILE byte ptr[esi] == ' '
  410. ;             inc   esi
  411. ;         .ENDW
  412. ;         .WHILE byte ptr[esi] >= '0' && byte ptr[esi] <= '9'
  413. ;            mov  al,[esi]
  414. ;            mov  [edi],al
  415. ;            inc  esi
  416. ;            inc  edi
  417. ;         .ENDW
  418. ;         .WHILE byte ptr[esi] == ' '
  419. ;             inc   esi
  420. ;         .ENDW
  421. ;         inc   esi                 ;move past ;
  422. ;         mov   edi,offset yorigin
  423. ;         .WHILE byte ptr[esi] == ' '
  424. ;             inc   esi
  425. ;         .ENDW
  426. ;         .WHILE byte ptr[esi] >= '0' && byte ptr[esi] <= '9'
  427. ;            mov  al,[esi]
  428. ;            mov  [edi],al
  429. ;            inc  esi
  430. ;            inc  edi
  431. ;         .ENDW
  432.  
  433.      .CONTINUE                 ; see if any more
  434. .ENDW
  435.  
  436. ;----------  ESTABLISH WINDOW ------------
  437.  
  438. ;-----Initialize Window -Anchor block handle returned = hab
  439. $Call WinInitialize,0            ;called with argument 0
  440. mov    hab,eax                   ;return value
  441. .IF hab == NULL
  442.     $Alarm0
  443.     $Call WinTerminate,hab
  444.     $DosExit
  445. .ENDIF
  446.  
  447. ;-----Create MessageQue  QueueHandle returned = hmq
  448. $Call WinCreateMsgQueue,hab,0    ; 0 is default size of queue
  449. mov      hmq,eax                 ;returned queue handle
  450. .IF hmq == NULL
  451.    $WinErrMsg " : WinCreateMsgQueue"
  452.    $DosExit
  453. .ENDIF
  454.  
  455. ;---- Register Window Class Returned value is TRUE or FALSE
  456. $Call WinRegisterClass,hab,offset szAppName,offset MainWinProc,flStyle,0
  457. .IF eax == FALSE
  458.     $WinErrMsg " : WinRegisterClass"
  459.     $Call WinTerminate,hab
  460.     $DosExit
  461. .ENDIF
  462.  
  463. ;---- CreateStandard Window - Returns handle for Main Window Frame and client Window
  464. $Call WinCreateStdWindow,HWND_DESKTOP,WS_VISIBLE,offset flCtlData,offset szAppName,\
  465.                     offset szWinTitle,0,0,0,offset hwndMain
  466. mov   hwndMainFrame,eax          ;returned Frame Window handle
  467. .IF eax == 0
  468.    $WinErrMsg " : WinCreateStdWindow"
  469.    Call   ExitWin
  470. .ENDIF
  471.  
  472. Call GetWinResolution
  473. Call DefineWindowSize
  474. Call SetWindow
  475. .IF InvFlag == 1     ;If this option minimize window
  476.    $Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,SWP_MINIMIZE
  477. .ENDIF
  478. ;
  479.  
  480. ;The way to proceed is to install a System Hook. This has to go into a DLL
  481. ;otherwise it cannot be called by other programs. The procedure in hook_dls
  482. ;will inspect WM_CHAR and if the ShiftKey and one of Alt or Ctrl key is down
  483. ;and if there is a valid Scan Code THEN
  484. ;it redefine the msg ID of that message as WM_USER+cfffh so it goes nowhere
  485. ;and then post a message to this program with the mp1 and mp2 parms
  486. ;using WM_USER+300h
  487.  
  488. ;------------  IS hookDLSM.DLL LOADED ? -------------------
  489. $Call DosQueryModuleHandle,offset DllFullModName,offset DllHandle
  490. .IF  eax == 0    ;module already loaded
  491.    $Alarm0
  492.    ;  $WinInfMsg  "      HOOKDLSM Already Loaded"
  493. .ENDIF
  494. ;---- Reads In hookkbsm.dat and writes to memory buffer
  495.    Call ReadDatFile
  496. ;---------  ALLOCATE MEMORY FOR SWITCH LIST STRUCTURE -------
  497.    Call SwitchListAlloc
  498.    $Call DosLoadModule,offset DllLoadError,LENGTHOF DllLoadError,offset DllFullModName,offset DllHandle
  499.    .IF eax != 0
  500.       $WinErrMsg " DosLoadModule"
  501. ;      Call   UnloadKBHook
  502.    .ENDIF
  503. .If DllProcAddr1 == 0
  504.     $Call DosQueryProcAddr,DllHandle,1,0,offset DllProcAddr1
  505.     .IF eax != 0
  506.         $WinDebugMessage msgDosQueryProc1Addr
  507. ;        Call   UnloadKBHook
  508.     .ENDIF
  509. .ENDIF
  510.  
  511. .IF DllProcAddr2 == 0
  512.     $Call DosQueryProcAddr,DllHandle,2,0,offset DllProcAddr2  ;JournalRecordHook
  513.     .IF eax != 0
  514.         $WinDebugMessage msgDosQueryProc2Addr
  515. ;        Call   UnloadKBHook
  516.     .ENDIF
  517. .ENDIF
  518.  
  519. $Call WinSetHook,hab,NULLHANDLE,HK_INPUT,DllProcAddr1,DllHandle
  520. .IF eax == 0
  521.    $WinErrMsg " WinSetINPUTHook"
  522.    Call   UnloadKBHook
  523. .ENDIF
  524.  
  525. ;------ pass the window frame handle in ebx
  526. ;-----  returns PlayBackQMSG in eax
  527. ;esp checks before and after call
  528. mov    ebx,hwndMainFrame  ;value of this
  529. mov    eax,0              ;Initialization Identifier
  530. call    DllProcAddr2
  531. mov    msgParms,eax       ;address of message variables from DLL when Recording
  532. ;$WinInfMsg  "   address of msgParms"   ;OK
  533. ;msgParms    offset   Variable
  534. ;              0      hwnd
  535. ;              4      msgID
  536. ;              8      mp1
  537. ;             12      mp2
  538. ;             16      time
  539. ;             20      x coordinate (Screen Based)
  540. ;             24      y coordinate (Screen Based)
  541.  
  542. .IF JumpFlag == 0      ;JumpFlag set on command line
  543.    Call SetJump        ;Sets HOOKKBSM as non-jumpable THIS IS DEFAULT
  544. .ENDIF
  545.  
  546. ;---------  CREATE MAIN MESSAGE LOOP -----------
  547.  
  548. mml: $Call WinGetMsg,hab,offset quemsg,0,0,0    ;Note: differs from usual
  549.      .IF eax == TRUE                            ;msg loop - done so that program
  550.          $Call WinDispatchMsg,hab,offset quemsg ;can only be terminated
  551.          jmp   mml                              ;by the keystroke Shift-Alt-Del
  552.      .ELSE                                      ;or by Alt-F4 or Alt-Close
  553.          Call  UnloadKBHOok                     ;when Window has focus
  554.          mov   eax,TRUE
  555.          jmp   mml                              ;if ESc option chosen
  556.      .ENDIF                                     ;as notified from the DLL
  557.  
  558. ;Normally an Exit routine would go here, as indicated below but which
  559. ;is commented out. It is not required since it can never be reached.
  560. ;----------  EXIT ---------------
  561. ;Call UnloadKBHOok
  562. ;.ENDIF            ;Tue  04-13-1993
  563. ;---------------- End of Main Program -------------------
  564.  
  565. ;-------------  PROCESS MESSAGE QUEUE FOR hook_KB ------------
  566. ;------------------ MainWinProc -----------------
  567. ;parm1 = hwnd,parm2 = msg,parm3  = mp1,parm4 = mp2
  568. ;this is called from System and so has to do everything itself
  569. MainWinProc Proc Near
  570.     ;----------- GET PASSED PARAMETERS FROM STACK ------------
  571.     push   ebp           ;return address is 4 bytes and this push is 4 bytes
  572.     mov    ebp,esp       ;so first parameter is 8 bytes from top
  573.     mov    eax,[ebp+8]
  574.     mov    parm1,eax     ;hwnd
  575.     mov    eax,[ebp+12]
  576.     mov    parm2,eax     ;msg
  577.     mov    eax,[ebp+16]
  578.     mov    parm3,eax     ;mp1
  579.     mov    eax,[ebp+20]
  580.     mov    parm4,eax     ;mp2
  581.     mov    eax,[ebp+24]
  582.     mov    parm5,eax     ;time of message
  583.    ;----- RESTORE STACK POINTER AND STACK STATUS  ---
  584.     mov      esp,ebp     ;restore  stack pointer
  585.     pop      ebp
  586.     pushad  ;  Tue  07-20-1993 pusha -> pushad
  587.     ;---------------- WM_CREATE ----------------
  588.     .IF parm2 == WM_CREATE
  589.          Call InitMainWindow
  590.          jmp  wm0
  591.     .ENDIF
  592.     ;---------------- WM_PAINT ----------------
  593.     .IF parm2 == WM_PAINT ; && parm1 == hwndMain
  594.          Call MainPaint
  595.          jmp  wm0
  596.     .ENDIF
  597.     ;---------------- WM_CHAR ----------------
  598.     .IF parm2 == WM_CHAR
  599.          Call MainKeyboard
  600.          jmp  wm0
  601.     .ENDIF
  602.     ;---------------- WM_SIZE ------------
  603.     .IF parm2 == WM_SIZE
  604.          jmp  wm0
  605.     .ENDIF
  606.     ;---------------- WM_USER+300H ----------------
  607.     .IF parm2 == WM_USER+300h                    ;posted message
  608.     ;if here know that Shift Key was down and at least one of Alt or Ctrl
  609.     ;GET SCAN CODE AND ALT/CTRL FLAG
  610.          mov    edx,parm4       ;scan code
  611.          mov    eax,parm3       ;Alt/Ctrl Flag = 0/1
  612.          mov    Alt_Ctrl,eax    ;Alt-Ctrl flag
  613.     ;Test for Shift-Alt-Del(white) for Unloading KBHook
  614.          .IF edx == 83 && Alt_Ctrl == 0      ; Shift-Alt-Del (White Del key)
  615.             Call UnloadKBHook
  616.             jmp     wm0
  617.          .ENDIF
  618.     ;Test for Shift-Alt-End(white) for CloseDown
  619.          .IF  edx == 79 && Alt_Ctrl == 0      ;Shift-Alt-End(White)
  620.             Call  CloseDown                   ;Tue  04-13-1993
  621.             jmp   wm0
  622.          .ENDIF
  623.     ;Test for Shift-Ctrl-LeftArrow - Start Record
  624.          .IF  edx == 75 && Alt_Ctrl == 1      ;Shift-Ctrl-LeftArrow(White)
  625.             .IF InvFlag == 1
  626.                mov  eax,SWP_RESTORE
  627.             .ELSE
  628.                mov  eax,SWP_ACTIVATE
  629.             .ENDIF
  630.             $Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,EAX
  631.             Call  RecordMacroON
  632.             jmp   wm0
  633.          .ENDIF
  634.     ;Test for Shift-Ctrl-RightArrow  - Stop Record
  635.          .IF  edx == 77 && Alt_Ctrl == 1      ;Shift-Ctrl-RightArrow(White)
  636.             Call  RecordMacroOFF
  637.             .IF InvFlag == 1
  638.                $Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,SWP_MINIMIZE
  639.             .ENDIF
  640.             jmp   wm0
  641.          .ENDIF
  642.     ;Test for Shift-Ctrl-Ins(white)    - Playback Record Parms Basis
  643.          .IF  edx == 82 && Alt_Ctrl == 1      ;Shift-Ctrl-Ins(White)
  644.             .IF InvFlag == 1
  645.                mov   eax,SWP_RESTORE
  646.             .ELSE
  647.                mov   eax,SWP_ACTIVATE
  648.             .ENDIF
  649.             $Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,EAX
  650.             Call  PlaybackMacro
  651.             .IF InvFlag == 1
  652.                $Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,SWP_MINIMIZE
  653.             .ENDIF
  654.             jmp   wm0
  655.          .ENDIF
  656.     ;Test for Shift_Ctrl-PgDn(White)   - Write Macro File Out
  657.          .IF  edx == 81 && Alt_Ctrl == 1      ;Shift-Ctrl-PgDn(White)
  658.             Call  WriteMacroAsciiHex
  659.             jmp   wm0
  660.          .ENDIF
  661.     ;Test for Shift-Ctrl-5(white)    - ProgramTestCtrl
  662.          .IF  edx == 76 && Alt_Ctrl == 1      ;Shift-Ctrl-5(White)
  663.             Call  ProgramTestCtrl
  664.             jmp   wm0
  665.          .ENDIF
  666.     ;Test for Shift-Alt-5(white)    - ProgramTestAlt
  667.          .IF  edx == 76 && Alt_Ctrl == 0      ;Shift-Alt-5(White)
  668.             Call  ProgramTestAlt
  669.             jmp   wm0
  670.          .ENDIF
  671.     ;Test for Shift-Alt-UpArrow    - Call ReadDatFile Update hookkbsm.dat
  672.          .IF  edx == 72 && Alt_Ctrl == 0      ;Shift-Alt-UpArrow(White)
  673.             .IF InvFlag == 1
  674.                mov   eax,SWP_RESTORE
  675.             .ELSE
  676.                mov   eax,SWP_ACTIVATE
  677.             .ENDIF
  678.             $Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,EAX
  679.             mov   UpdateDat,1
  680.             $Call WinInvalidateRect,hwndMain,offset rect,TRUE
  681.             mov   edx,2500
  682.             Call  TimeDelay
  683.             Call  ReadDatFile
  684.             mov   UpdateDat,0
  685.             $Call WinInvalidateRect,hwndMain,offset rect,TRUE  ;reset
  686.             .IF InvFlag == 1
  687.                $Call WinSetWindowPos,hwndMainFrame,0,0,0,0,0,SWP_MINIMIZE
  688.             .ENDIF
  689.             jmp   wm0
  690.          .ENDIF
  691.  
  692. ;ELSE TEST FOR ASSIGNED KEYS
  693. ;SETUP DATA STRUCTURES FOR ACTIVATING HOT KEY
  694. ;---- Code in this group places the offset into the array ExecOnKB into EDX
  695.          .IF  edx == 82 && Alt_Ctrl == 0      ;Shift-Alt-Ins
  696.               mov    esi,offset StartData     ;data structure for DosStartSession
  697.               mov    word ptr StartData,50    ;for Alt-=
  698.               mov    HotKeyID,'Ω'             ;For Program Title
  699.               mov    edi,offset TitleAlt
  700.               mov    cl,HotKeyID
  701.               mov    byte ptr [edi+4],cl
  702.               mov    dword ptr[esi+8],offset TitleAlt  ;program title
  703.               $Call  WinSetFocus,HWND_DESKTOP,hwndMainFrame ;required for program started to be in foreground
  704.               mov    eax,offset InsProg       ;address of Exec program
  705.               mov    [esi+12],eax
  706.               mov    dword ptr[esi+16],0      ;no command line
  707.               mov    word ptr[esi+30],2       ;Session Type
  708.               jmp    wmexe
  709.          .ELSE
  710.               mov    word ptr StartData,32
  711.          .ENDIF
  712.          .IF  edx == 53 && Alt_Ctrl == 1      ; Shift-Ctrl-?:/  key
  713.               mov    esi,offset StartData     ;data structure for DosStartSession
  714.               mov    word ptr StartData,32    ;
  715.               mov    HotKeyID,'?'             ;For Program Title
  716.               mov    edi,offset TitleAlt
  717.               mov    cl,HotKeyID
  718.               mov    byte ptr [edi+4],cl
  719.               mov    dword ptr[esi+8],offset TitleAlt  ;program title
  720.               $Call  WinSetFocus,HWND_DESKTOP,hwndMainFrame ;required for program started to be in foreground
  721.               mov    eax,offset InsProg   ;address of Exec program
  722.               mov    [esi+12],eax
  723.               mov    eax,offset DisplayUser
  724.               mov    dword ptr[esi+16],eax    ; command line
  725.               mov    word ptr[esi+30],2       ;Session Type
  726.               jmp    wmexe
  727.          .ENDIF
  728.          .IF  edx == 53 && Alt_Ctrl == 0      ; Shift-Alt-?:/  key
  729.               mov    esi,offset StartData     ;data structure for DosStartSession
  730.               mov    word ptr StartData,32    ;
  731.               mov    HotKeyID,'/'             ;For Program Title
  732.               mov    edi,offset TitleAlt
  733.               mov    cl,HotKeyID
  734.               mov    byte ptr [edi+4],cl
  735.               mov    dword ptr[esi+8],offset TitleAlt  ;program title
  736.               $Call  WinSetFocus,HWND_DESKTOP,hwndMainFrame ;required for program started to be in foreground
  737.               mov    eax,offset InsProg   ;address of Exec program
  738.               mov    [esi+12],eax
  739.               mov    eax,offset DisplayPrg
  740.               mov    dword ptr[esi+16],eax    ; command line
  741.               mov    word ptr[esi+30],2       ;Session Type
  742.               jmp    wmexe
  743.          .ENDIF
  744.          .IF    edx >= 2 && edx <= 11     ;scan code for 1..9,0
  745.              .IF  edx >= 2 && edx <= 10
  746.                  sub   edx,1       ;convert to number 1 - 9
  747.              .ELSE
  748.                  mov   edx,0       ; 0 offset for 0
  749.              .ENDIF
  750.              mov   HotKeyID,dl
  751.              add   HotKeyID,30h    ;convert to ASCII
  752.              jmp   wmok
  753.          .ENDIF
  754.           xor   ecx,ecx
  755.          .IF  edx >= 16 && edx <= 25; && edx != 17 ; q,w,e,r,t,y,u,i,o,p
  756.                mov   esi,offset lookup0
  757.                sub   edx,16
  758.                jmp   wmoj
  759.          .ENDIF
  760.          .IF edx >= 30 && edx <= 38 ; a,s,d,f,g,h,j,k,l
  761.                mov   esi,offset lookup1
  762.                sub   edx,30
  763.                jmp   wmoj
  764.          .ENDIF
  765.          .IF  edx >= 43 && edx <= 50  ;z,x,c,v,b,n,m
  766.                mov   esi,offset lookup2
  767.                sub   edx,44
  768.                jmp   wmoj
  769.          .ELSE
  770.                jmp   wm0
  771.          .ENDIF
  772. wmoj:     mov   cl,byte ptr [esi+edx]  ;cl has value - cl+37h is UC letter
  773.           mov   HotKeyID,cl            ;identifies letter
  774.           add   HotKeyID,37h
  775.           xor   edx,edx
  776.           mov   dl,cl
  777. wmok:     ;- Alt_Ctrl has Alt_Ctrl Flag and dl has offset into array
  778.          .IF  edx >= 0 && edx <= 35
  779.               xor  eax,eax
  780.               mov   al,dl
  781.               mov  esi,offset StartData  ;data structure for DosStartSession
  782.               .IF  Alt_Ctrl == 0
  783.                   mov   ebx,offset AltX  ;Alt Definitions
  784.                   mov   edi,offset TitleAlt
  785.                   mov   cl,HotKeyID
  786.                   mov   byte ptr [edi+4],cl
  787.                   mov   dword ptr[esi+8],offset TitleAlt  ;program title
  788.               .ENDIF
  789.               .IF  Alt_Ctrl == 1
  790.                   mov   ebx,offset CtrlX ;Ctrl Definitions
  791.                   mov   edi,offset TitleCtl
  792.                   mov   cl,HotKeyID
  793.                   mov   byte ptr [edi+4],cl
  794.                   mov   dword ptr[esi+8],offset TitleCtl  ;program title
  795.               .ENDIF
  796.               mov    cl,LenExec
  797.               mul    cl             ;Structure Length ten
  798.               add    ebx,eax        ;element # of structure
  799.               ;[ebx+8] != 9 is flag that keystroke is assigned
  800.               .IF  word ptr [ebx+8] != 9
  801.                    $Call WinSetFocus,HWND_DESKTOP,hwndMainFrame ;required for program started to be in foreground
  802.                    mov  eax,[ebx]              ;address of Exec program
  803.                    mov  [esi+12],eax
  804.                    mov  eax,[ebx+4]            ;address of command line
  805.                    mov  [esi+16],eax
  806.                    mov  ax,word ptr [ebx+8]    ;Session type
  807.                    mov  [esi+30],ax
  808.                   .IF ax == 4 || ax == 7    ;set environment string DPMI_DOS_API for Borland IDE
  809.                       mov dword ptr[esi+24],offset DosEnvValue
  810.                   .ELSE
  811.                       mov  dword ptr[esi+24],0   ;default value reset
  812.                   .ENDIF
  813. ;GO THRU SWITCH LIST TO SEE IF HOT KEY ACTIVE
  814.                    ;-- called before DosStartSession to see if program loaded
  815.                    ;-- esi=offset into StartData
  816.                    ;-- go thru Switch List to see if loaded and if so switch to
  817.                    ;-- The test made on 4th char of TitleAlt/TitleCtl which
  818.                    ;-- is the title in the window and Task List
  819. wmexe:             pushad  ; Tue  07-20-1993   pusha -> pushad
  820.                    $NumSwitchListEntries
  821.                    mov  numitems,eax      ;number of switch list entries
  822.                    dec numitems
  823.                    Call GetSwitchList     ;activate structure
  824.                    mov  edi,baseaddr      ;address of switch list
  825.                    mov  ecx,0
  826.                    .IF  Alt_Ctrl == 0
  827.                         mov    bl,'A'
  828.                    .ELSE
  829.                         mov    bl,'C'
  830.                    .ENDIF
  831.                    .WHILE  ecx < numitems           ;starts at offset 0
  832.                        mov   al,byte ptr[edi+40]  ;5-th char TaskList title
  833.                        mov   dl,byte ptr[edi+36]  ;1stChar of Title A/C
  834.                        ;IF ACTIVE SWITCH TO
  835.                        .IF al == HotKeyID && bl == dl
  836.                             ;Now Switch to that window - get switch handle
  837.                             mov  eax,[edi+4]
  838.                             $Call WinSwitchToProgram,eax
  839.                             popad ; Tue  07-20-1993   popa ->popad
  840.                             jmp  wm0                ;do not reload
  841.                        .ENDIF
  842.                        inc   ecx
  843.                        add   edi,swblksize           ;next element in structure
  844.                    .ENDW
  845.                    popad ;Tue  07-20-1993 popa ->popad
  846.                    ;ELSE ACTIVATE HOT KEY PROGRAM
  847.                    $Call DosStartSession,esi,offset SessID,offset ProcID
  848.               .ENDIF
  849.          .ENDIF
  850.     .ENDIF                                     ;End WM_USER+300h
  851.    wm0:popad     ; Tue  07-20-1993 popa ->popad
  852.    ;----- Default Procedure * Return Value in eax ------
  853.    $Call WinDefWindowProc,parm1,parm2,parm3,parm4
  854.    ret
  855. MainWinProc  endp
  856.  
  857. ;-------------- MainPaint * WM_PAINT --------------
  858. MainPaint  proc
  859.       $Call WinBeginPaint,hwndMain,NULL,offset rect    ;offset rect
  860.       mov  hps,eax        ;returns cache presentation space handle
  861.       $Call WinQueryWindowRect,hwndMain,offset rect
  862.       $Call WinFillRect,hps,offset rect,CLR_YELLOW  ;SYSCLR_WINDOW
  863.       .IF RecordOn == 1
  864.           $Call WinDrawText,hps,-1,offset textMsgOn,offset rect,CLR_BLUE,CLR_YELLOW,TextPos
  865.       .ENDIF
  866.       .IF RecordOn == 2
  867.           $Call WinDrawText,hps,-1,offset textMsgPlay,offset rect,CLR_BLUE,CLR_YELLOW,TextPos
  868.       .ENDIF
  869.       .IF UpdateDat == 1
  870.           $Call WinDrawText,hps,-1,offset textMsgUpdateDat,offset rect,CLR_BLUE,CLR_YELLOW,TextPos
  871.       .ENDIF
  872.       $Call WinEndPaint,hps
  873.       mov   eax,TRUE
  874.       ret
  875. MainPaint  endp
  876.  
  877. ;-------------- InitMainWindow * WM_CREATE --------------
  878. ;var1 = hwnd, var2 = mp1, var3 = mp2
  879. InitMainWindow Proc
  880.        $Call WinDefWindowProc,parm1,parm2,parm3,parm4
  881.        ret
  882. InitMainWindow Endp
  883.  
  884. ;-------------- MainKeyBoard * WM_CHAR --------------
  885. ;var1 = mp1,var2 = mp2,var3 = hwnd
  886. MainKeyBoard  Proc
  887.       $Call WinDefWindowProc,parm1,parm2,parm3,parm4
  888.       ret
  889. MainKeyBoard Endp
  890.  
  891. ExitWin  Proc
  892.     $Call WinDestroyMsgQueue,hmq
  893.     $Call WinTerminate,hab
  894.     $Call DosFreeModule,DllHandle
  895.     $DosExit    ;so exit
  896.     ret
  897. ExitWin  Endp
  898.  
  899. SwitchListAlloc  Proc          ;allocate memory for a switch list of 30
  900.     mov     ecx,00000002h   ;write access flags for Dos alloc
  901.     or      ecx,00000010h   ;page commit
  902.     $Call DosAllocMem,offset baseaddr,3000,ecx
  903.     .IF  eax != 0
  904.        $WinErrMsg  " : DosAllocMem SwitchList"
  905.        Call Exitwin
  906.     .ENDIF
  907.     ret
  908. SwitchListAlloc  Endp
  909.  
  910. GetSwitchList   Proc   ;puts address into baseaddr
  911.     pushad
  912.     $Call  WinQuerySwitchList,hab,baseaddr,3000
  913.     .IF eax == 0
  914.         $WinErrMsg " : WinQuerySwitchList"
  915.         Call ExitWin
  916.     .ENDIF
  917.     popad
  918.     ret
  919. GetSwitchList   Endp
  920.  
  921. ;---- This procedure uses the handle returned from the message and uses
  922. ;---- that to obtain the first 24 characters of the name associated
  923. ;---- with that handle from SwitchList for which space is already allocated
  924. ;---- this is called with handle in eax
  925. GetNameFromHandle  Proc
  926.     pusha
  927.     $Call  WinQuerySwitchList,hab,baseaddr,3000
  928.     mov   numitems,eax      ;number of switch list entries
  929.     mov   edi,baseaddr      ;address of switch list
  930.     mov   ecx,1
  931.     mov   NameHitFlag,0     ;reset
  932.     mov   eax,HandFromMsg
  933.     .WHILE  ecx <= numitems           ;starts at offset 0
  934.          ;--- This group displays SwitchList Title and Iconsn
  935.          .IF   eax == [edi+8]        ;hwnd of FrameWindow of Program returned by msgQueue
  936.                mov    NameHitFlag,1
  937.                mov    eax,edi
  938.                add    eax,36         ;address of name
  939.                mov    TaskNameAddr,eax
  940.               .BREAK
  941.          .ENDIF
  942. ;         .IF   eax == [edi+12]        ;hwnd of FrameWindow of Program returned by msgQueue
  943. ;               mov    NameHitFlag,1   ;ICON
  944. ;               mov    eax,edi
  945. ;               add    eax,36         ;address of name
  946. ;               mov    TaskNameAddr,eax
  947. ;              .BREAK
  948. ;         .ENDIF;  Not Required
  949. ;         .IF   eax == [edi+16]        ;hwnd of FrameWindow of Program returned by msgQueue
  950. ;               mov    NameHitFlag,1   ;PROGRAM
  951. ;               mov    eax,edi
  952. ;               add    eax,36         ;address of name
  953. ;               mov    TaskNameAddr,eax
  954. ;              .BREAK
  955. ;         .ENDIF ;   Plays No role
  956.          ;;--- Displays programTitles
  957.          push  ecx
  958.          $Call WinQueryWindow,HandFromMsg,QW_PARENT
  959.          pop   ecx
  960.          .BREAK .IF eax == 0
  961.          .IF   eax == [edi+8]        ;hwnd of FrameWindow of Program returned by msgQueue
  962.                mov    NameHitFlag,1
  963.                mov    eax,edi
  964.                add    eax,36         ;address of name
  965.                mov    TaskNameAddr,eax
  966.               .BREAK
  967.          .ENDIF
  968.          inc   ecx
  969.          add   edi,swblksize           ;next element in structure
  970.     .ENDW
  971.     .IF  NameHitFlag == 0
  972.          mov  TaskNameAddr,offset NoNameListed
  973.     .ENDIF
  974.     popa
  975.     ret
  976. GetNameFromHandle  Endp
  977.  
  978. CloseDown       Proc
  979.     $Call WinMessageBox,HWND_DESKTOP,HWND_DESKTOP,offset ExitMsg,offset ExitTitle,0,MB_OKCANCEL
  980.     .IF eax != MBID_CANCEL
  981.         $Call WinShutdownSystem,hab,hmq
  982.         $Call DosFreeMem,memAddr
  983.         $Call WinReleaseHook,hab,NULL,HK_INPUT,[DllProcAddr1],DllHandle
  984.         $Call DosFreeModule,DllHandle
  985.         $Call WinDestroyWindow,hwndMainFrame
  986.         Call  ExitWin
  987.     .ENDIF
  988.     ret
  989. CloseDown       Endp
  990.  
  991. UnloadKBHook   Proc
  992.     $Alarm0
  993.     $Call WinMessageBox,HWND_DESKTOP,HWND_DESKTOP,offset RemoveMsg,offset RemoveTitle,0,MB_OKCANCEL
  994.     .IF eax != MBID_CANCEL
  995.         $Call DosFreeMem,memAddr
  996.         .IF eax != 0
  997.             $WinErrMsg " : DosFreeRegularMem"
  998.         .ENDIF
  999.         $Call WinReleaseHook,hab,NULL,HK_INPUT,[DllProcAddr1],DllHandle
  1000.         .IF eax == 0
  1001.            $WinErrMsg " : WinReleasInputHook-1"
  1002.         .ENDIF
  1003.         $Call DosFreeModule,DllHandle
  1004.         .IF  eax != 0
  1005.             $WinErrMsg "  : DosFreeModule-DLL"
  1006.         .ENDIF
  1007.         $Call WinDestroyWindow,hwndMainFrame
  1008.         .IF  eax == 0
  1009.             $WinErrMsg " : WinDestroyWindow"
  1010.         .ENDIF
  1011.         Call  ExitWin
  1012.     .ENDIF
  1013.     mov  eax,TRUE
  1014.     ret
  1015. UnloadKBHook   Endp
  1016.  
  1017. ;----- Gets horizontal and vertical window resolution
  1018. GetWinResolution  Proc
  1019.     $Call WinGetPS,HWND_DESKTOP
  1020.     mov   hps,eax              ;presentation space
  1021.     .IF eax == 0
  1022.        $WinErrMsg "  WinGetPS"
  1023.       Call   ExitWin
  1024.     .ENDIF
  1025.  
  1026.     $Call GpiQueryDevice,hps
  1027.     mov   hdc,eax              ;device handle
  1028.     .IF eax == 0 || eax == HDC_ERROR
  1029.        $WinErrMsg "  GpiQueryDevice"
  1030.        Call   ExitWin
  1031.     .ENDIF
  1032.  
  1033. ;---- will get horizontal and vertical resolution in one read
  1034. ;---- xPelsPerMeter and yPelsPerMeter are consecutive
  1035.     $Call DevQueryCaps,hdc,CAPS_HORIZONTAL_RESOLUTION,2,offset xPelsPerMeter
  1036.     .IF eax == 0
  1037.        $WinErrMsg " : DosQueryCapsHorizontal"
  1038.        Call   ExitWin
  1039.     .ENDIF
  1040. ;---- Get Screen Width in PELS
  1041.     $Call DevQueryCaps,hdc,CAPS_WIDTH,1,offset ScreenWidth
  1042.     .IF eax == 0
  1043.        $WinErrMsg " : DosQueryCapsScreenWidth"
  1044.        Call   ExitWin
  1045.     .ENDIF
  1046.  
  1047.     $Call WinReleasePS,hps
  1048.     ret
  1049. GetWinResolution  Endp
  1050.  
  1051. ;----- Fills RECT structure for window size ---
  1052. DefineWindowSize  Proc
  1053.     xor   edx,edx
  1054.     mov   eax,xPelsPerMeter    ;basevalue is 2667 before divide
  1055.     div   DivideByHoriz
  1056.     mov   RightX,eax
  1057.  
  1058.     xor   edx,edx
  1059.     mov   eax,yPelsPerMeter    ;basevalue is 2667 before divide
  1060.     div   DivideByVert
  1061. ;    mov   ebx,eax
  1062. ;    shr   eax,2                ;divide eax by 4
  1063. ;    mov   UpperY,ebx
  1064. ;    sub   UpperY,eax
  1065.     mov    UpperY,eax
  1066.  
  1067.     mov   esi,offset rect
  1068.     mov   eax,LeftX
  1069.     mov   [esi],eax
  1070.     mov   eax,LowerY
  1071.     mov   [esi+4],eax
  1072.     mov   eax,RightX
  1073.     mov   [esi +8],eax
  1074.     mov   eax,UpperY
  1075.     mov   [esi+12],eax
  1076.     ret
  1077. DefineWindowSize  Endp
  1078.  
  1079. ;------ sets window position ---
  1080. SetWindow   Proc
  1081.     mov   edx,0                      ;y-origin
  1082.     .IF posorigin == 0               ;default Lower Left Corner
  1083.         mov   eax,0
  1084.     .ENDIF
  1085.     .IF posorigin == 1               ;lower right corner
  1086.        mov   eax,ScreenWidth
  1087.        sub   eax,Rightx
  1088. ;       sub   eax,14                 ;attempting to offset a bit
  1089.     .ENDIF
  1090.  
  1091. ;    .IF SetOrigin == 1               ;origin location passed
  1092. ;        mov  eax,0                   ;getting errors here I do not understand
  1093. ;        mov  edx,0
  1094. ;        $AsciiToDWord   yorigin
  1095. ;        mov edx,eax
  1096. ;        $AsciiToDWord   xorigin     ;result in eax
  1097. ;    .ENDIF
  1098.     mov   ebx,SWP_SIZE
  1099.     or    ebx,SWP_MOVE
  1100.     $Call WinSetWindowPos,hwndMainFrame,0,eax,edx,RightX,UpperY,ebx
  1101.     .IF eax == 0
  1102.         $WinErrMsg " WinSetWindowsPos"
  1103.     .ENDIF
  1104.     ret
  1105. SetWindow   Endp
  1106.  
  1107. RecordMacroON Proc   ;esp checks before and after call
  1108.     .IF  RecordOn == 0
  1109.         mov   RecordOn,1
  1110.         mov    JR_Count,0        ;as is done in call
  1111.         mov    JR_Counter,0      ;as is done in call
  1112.         mov    AddrCtr,0
  1113.         $Call WinInvalidateRect,hwndMain,offset rect,TRUE
  1114.         mov    eax,1             ;in DLL JR_Counter->0,RecordOn->1
  1115.         call    DllProcAddr2
  1116.     .ENDIF
  1117.     ret
  1118. RecordMacroON  Endp
  1119.  
  1120. ; When turning OFF the Shift-Ctrl-Ins key strokes are recorded. They
  1121. ; contribute 6 counts tothe records. A single key stroke (down and up)
  1122. ; contributes 2 counts to the record.
  1123. RecordMacroOFF   Proc   ;esp checks before and after calls
  1124.     pusha
  1125.     .IF  RecordOn == 1
  1126.         mov    RecordOn,0
  1127.         mov    eax,2             ;JR_Counter,JR_Count,RecordON->0
  1128.         call    DllProcAddr2      ;Returns JR_Count in eax
  1129.         mov    JR_Count,eax      ;JR_Counter returned from DLL
  1130.         $Call WinInvalidateRect,hwndMain,offset rect,TRUE
  1131.     .ENDIF
  1132.     popa
  1133.     ret
  1134. RecordMacroOFF       Endp
  1135. ;
  1136. PlaybackMacro  Proc
  1137.     .IF RecordOn == 1
  1138.         Call RecordMacroOff
  1139.         mov  JR_Count,0
  1140.          mov    eax,0
  1141.          $WinInfMsg   " !! Aborting Macro Recording - Cannot PlayBack while Recording !!"
  1142.         ret
  1143.     .ENDIF
  1144.     .IF  JR_Count == 0  || JR_Count == 8     ;8 is 3 StartUp and 5 Close WM_CHAR messages
  1145.          mov    eax,0
  1146.          $WinInfMsg   " Messages to Play back !!"
  1147.          ret
  1148.     .ENDIF
  1149.     pusha
  1150.     .IF  RecordOn == 0 && JR_Count > 8 ;edi saved across calls
  1151.         mov  eax,JR_Count
  1152.         sub  eax,8             ;Omit 3 start and 5 terminating messages
  1153. ;        $WinInfMsg   " Messages to Play back !!"
  1154. ;---- Temporarily Release HotKey Activation, Display "Playback" message
  1155. ;     If release hook then during playback ALt-x/Ctrl-X assignments appear
  1156. ;        $Call WinReleaseHook,hab,NULLHANDLE,HK_INPUT,DllProcAddr1,DllHandle
  1157.         mov   RecordOn,2
  1158.         $Call WinInvalidateRect,hwndMain,offset rect,TRUE
  1159. ;----  Now Playback the Macro
  1160.         mov   esi,msgParms           ;block holding playback records
  1161.         add   esi,RecdLnth_x_3       ;no include 1st 3 msgs which are KeyUp of Shift-Ctrl-LeftArrow StartUp Sequence
  1162.         mov   ecx,9                  ;Omit 3 start 5 ending messages
  1163.         mov   ebx,0
  1164.         mov   edx,0                  ;value for first time around
  1165.         .WHILE  ecx <= JR_Count
  1166.             .IF edx > 0  ;&& dword ptr[esi+ebx+4] != WM_TIMER
  1167.                  Call TimeDelay
  1168.             .ENDIF
  1169.             pusha
  1170.             Call UseCurWindows
  1171.             popa
  1172.             mov   eax,[esi+ebx+16] ;time of this just played
  1173.             inc   ecx
  1174.             add   ebx,RecdLnth
  1175.             mov   edx,[esi+ebx+16] ;time of message coming up
  1176.             sub   edx,eax          ;time diff between messages
  1177.         .ENDW
  1178. ;        mov   eax,ecx
  1179. ;        dec   eax
  1180. ;        $WinInfMsg "       Records Played Back"
  1181.         ;---- Restore to non Playback
  1182.         mov   RecordOn,0      ;reset to no recording
  1183.         $Call WinInvalidateRect,hwndMain,offset rect,TRUE
  1184. ;        $Call WinSetHook,hab,NULLHANDLE,HK_INPUT,DllProcAddr1,DllHandle
  1185.     .ENDIF
  1186.     popa
  1187.     ret
  1188. PlaybackMacro  Endp
  1189.  
  1190. ;---- Called by PlayBack to use Current Windows which are either
  1191. ;---- ACtive Windows (mouse related) or windows with focus (KBoard related)
  1192. UseCurWindows   Proc
  1193. ;---- WM_CHAR ----
  1194.      ;--- Code here ensures that window with focus gets WM_CHAR messages
  1195.      ;--- Using only those on the Down Stroke
  1196.     ;Test for Shift-Alt-Ins(white)     -
  1197.      .IF  [esi+4+ebx] ==  WM_CHAR  && byte ptr[esi+8+ebx] > 40H   ;Up stroke
  1198.          mov    eax,TRUE
  1199.          ret
  1200.      .ENDIF
  1201.      .IF  [esi+4+ebx] ==  WM_CHAR  && byte ptr[esi+8+ebx] <= 40H  ;down stroke
  1202.          ;---  Code below ensures that no messages called by Alt/Ctrl -Key
  1203.          ;---- Are Called with Shift Alt/Ctrl-Key sequence in playback
  1204.          ;---  If Alt/Ctrl down lowest byte of param2=0
  1205.          ;---  AND next lowest byte is Scan Code of Key Struck
  1206.          ;---  If Shift Down Test Lowest Word of param1 for KC_SHIFT
  1207.          mov     edx,[esi+12+ebx] ;param2
  1208.          .IF     dh != 0 && dl == 0 ;Alt/Ctrl down and ScanCode valid
  1209.              test   [esi+8+ebx],KC_SHIFT   ;is ShiftKey Down
  1210.              jz     NoShft
  1211.              mov   eax,TRUE
  1212.              ret
  1213.          .ENDIF
  1214. NoShft:  $Call WinQueryFocus,HWND_DESKTOP    ;window handle returned in EAX
  1215.          $Call WinSendMsg,eax,WM_CHAR,[esi+8+ebx],[esi+12+ebx]  ;this works
  1216.          mov   eax,TRUE
  1217.          ret
  1218.      .ENDIF
  1219.  
  1220. ;---- WM_MOUSEMOVE ----
  1221. ;---- The parms here are x,y coordinates relative to Screen
  1222. ;---- x = 0, y = 0 is lower left corner
  1223.      .IF   dword ptr[esi+4+ebx] == WM_MOUSEMOVE || dword ptr[esi+4+ebx] == WM_MOUSELAST
  1224.           $Call  WinSetPointerPos,HWND_DESKTOP,dword ptr[esi+20+ebx],dword ptr[esi+24+ebx]
  1225.           mov   eax,TRUE
  1226.           ret
  1227.      .ENDIF
  1228.  
  1229. ;---- WM_BUTTON1DOWN=WM_BUTTON1CLICK WM_SINGLESELECT WM_BUTTON1DBLCLK WM_BUTTON1UP  WM_BUTTON1MOTIONSTART || [esi+4+ebx] == WM_BUTTON1MOTIONEND----
  1230.      .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
  1231.           ;--- This gets handle of active window from DeskTop
  1232.           mov   eax,[esi+20+ebx]        ;X Screen Coordinate
  1233.           mov   WinPosX,eax
  1234.           mov   eax,[esi+24+ebx]        ;Y Screen Coordinate
  1235.           mov   WinPosY,eax
  1236.           $Call WinWindowFromPoint,HWND_DESKTOP,offset WinPosX,TRUE
  1237.           mov   hwndActive,eax
  1238.           $Call WinSetFocus,HWND_DESKTOP,eax
  1239.           $Call WinSendMsg,hwndActive,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx]  ;this works
  1240.           mov   eax,TRUE
  1241.           ret
  1242.      .ENDIF
  1243.  
  1244. ;---- WM_BUTTON2DOWN  WM_BUTTON2UP WM_BUTTON2DBLCLK  WM_BUTTON2MOTIONSTART  WM_BUTTON2MOTIONEND WM_BUTTON2CLICK ----
  1245.      .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
  1246.           ;--- This gets handle of active window from DeskTop
  1247.           mov   eax,[esi+20+ebx]        ;X Screen Coordinate
  1248.           mov   WinPosX,eax
  1249.           mov   eax,[esi+24+ebx]        ;Y Screen Coordinate
  1250.           mov   WinPosY,eax
  1251.           $Call WinWindowFromPoint,HWND_DESKTOP,offset WinPosX,TRUE
  1252.           mov   hwndActive,eax
  1253.           $Call WinSetFocus,HWND_DESKTOP,eax
  1254.           $Call WinSendMsg,hwndActive,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx]  ;this works
  1255.          mov   eax,TRUE
  1256.          ret
  1257.      .ENDIF
  1258.  
  1259. ;---- WM_ related to mouse drag
  1260.      .IF   dword ptr[esi+4+ebx] == WM_BEGINDRAG || dword ptr[esi+4+ebx] == WM_ENDDRAG || [esi+4+ebx] == WM_BUTTON2MOTIONEND
  1261.           mov   eax,[esi+20+ebx]        ;X Screen Coordinate
  1262.           mov   WinPosX,eax
  1263.           mov   eax,[esi+24+ebx]        ;Y Screen Coordinate
  1264.           mov   WinPosY,eax
  1265.           $Call WinWindowFromPoint,HWND_DESKTOP,offset WinPosX,TRUE
  1266.           mov   hwndActive,eax
  1267. ;          .IF word ptr [esi+8+ebx] == TRUE   ;was from Pointer event
  1268. ;               $Call DosBeep,100,1000
  1269. ;               mov   eax,[esi+12+ebx]    ;parm2
  1270. ;               xor   ecx,ecx
  1271. ;               mov   cx,ax               ;y coordinate
  1272. ;               shr   eax,16              ;move x coord to ax
  1273. ;               $Call WinSetWindowPos,hwndActive,eax,ecx,NULL,NULL,SWP_MOVE
  1274. ;               .IF eax == 0
  1275. ;                   $WinInfMsg  " WinSetWindowPos Err"
  1276. ;               .ENDIF
  1277. ;          .ENDIF
  1278.           $Call WinSetFocus,HWND_DESKTOP,hwndActive
  1279.           $Call WinSendMsg,hwndActive,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx]  ;this works
  1280.           ret
  1281.      .ENDIF
  1282.  
  1283. ;---- WM_TASKLIST 082H----
  1284. ;---- Task List -- TaskList Handle is Unique,TaskListHandle equ 004001CCh
  1285. ;---- Though there are other messages associated with the Task List
  1286. ;---- 80H = SH_TASKLIST 81h = SH_TASKMANAGER 82H = SH_TASKACTIVATE
  1287. ;---- ALso 02f43h and 02F42h seem associated
  1288. ;---- If this not included Ctrl-Esc not recognized on playback
  1289. ;---- Inclusion of 2F43H below meakes Macro Playback involving Ctrl-Esc work incorrectly
  1290. ;---- Inclusion of 81h makes no difference
  1291. ;---- Inclusion of 80h makes no difference
  1292. ;---- Inclusion of 1003H makes no difference but does display TaskLIst at End
  1293.      .IF dword ptr[esi+ebx+4] == 82h
  1294.          $Call WinSetFocus,HWND_DESKTOP,TaskListHandle
  1295.          $Call WinSendMsg,TaskListHandle,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx]  ;this works
  1296.          mov   eax,TRUE
  1297.          ret
  1298.      .ENDIF
  1299.  
  1300. ;     .IF dword ptr[esi+4+ebx] == 405h   ;seems to make no difference
  1301. ;         $Call WinSendMsg,00200138h,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx]
  1302. ;         mov   eax,TRUE
  1303. ;         ret
  1304. ;     .ENDIF
  1305.  
  1306. ;---- WM_OPEN WM_CLOSE WM_SYSCOMMAND WM_COMMAND
  1307. ;---- Inclusion of WM_CONTROL seems to make no difference
  1308.      .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
  1309.           $Call WinQueryFocus,HWND_DESKTOP
  1310.           $Call WinSendMsG,eax,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx]  ;this works
  1311.          mov   eax,TRUE
  1312.          ret
  1313.      .ENDIF
  1314.  
  1315. ;---- WM_PAINT ----
  1316.      .IF   [esi+4+ebx] == WM_PAINT
  1317.          $Call WinQueryFocus,HWND_DESKTOP
  1318.          $Call WinSendMsg,eax,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx]  ;this works
  1319.          mov   eax,TRUE
  1320.          ret
  1321.      .ENDIF
  1322.  
  1323. ;---- WM_USER+300h --- Send message to this Program (= hwndMain) for action
  1324.      .IF   [esi+4+ebx] == WM_USER+300h
  1325.          $Call WinSendMsg,hwndMain,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx]
  1326.          mov   eax,TRUE
  1327.          ret
  1328.      .ENDIF
  1329.  
  1330. ;---- WM_ALL_THE_REST ----
  1331. ;---- Since we do not know what window to send them to
  1332. ;    $Call WinQueryFocus,HWND_DESKTOP                           ;including this and
  1333. ;    $Call WinSendMsg,eax,[esi+4+ebx],[esi+8+ebx],[esi+12+ebx]  ;this seems to make no difference
  1334.      mov   eax,TRUE
  1335.      ret            ;for all those messages not explicitly handled
  1336. UseCurWindows   Endp
  1337.  
  1338. ;---- Called with window handle in eax -
  1339. FocusClass    Proc
  1340.      pusha
  1341.      $Call  WinQueryWindow,eax,QW_NEXT
  1342.      $Call  WinQueryClassName,eax,16,offset ClassNameBuf
  1343.      mov    esi,offset ClassNameBuf
  1344.      mov    edi,offset CoverPage
  1345.      mov    ecx,1
  1346.      mov    ebx,0
  1347.      .WHILE ecx <= 4
  1348.             mov   eax,[esi+ebx]
  1349.             cmp   eax,[edi+ebx]
  1350.             jne   nomtch
  1351.             add   ebx,4
  1352.             inc   ecx
  1353.      .ENDW
  1354. ;---- If got here there was a match
  1355.      $Call DosBeep,100,1000
  1356. nomtch: popa
  1357.      ret
  1358. FocusClass    Endp
  1359.  
  1360. ;--- Will Display handle of Window Under Mouse and WindowClass and
  1361. ;--- Then whether 16/32 bit
  1362. ProgramTestAlt  Proc      ;Use for testing things  Shift-Alt-5(white)
  1363.     pusha
  1364.     $Call WinQueryFocus,HWND_DESKTOP    ;get current focus to save
  1365.     push   eax
  1366.     $Call WinQueryPointerPos,HWND_DESKTOP,offset WinPosX
  1367.     ;--- IF FALSE is chosen returns Handle of Frame Window under HWND_DESKTOP
  1368.     ;--- IF  TRUE is chosen returns Handle of Actual Window
  1369.     $Call WinWindowFromPoint,HWND_DESKTOP,offset WinPosX,TRUE
  1370.     mov   hwndNext0,eax
  1371.     $WinInfMsg  " is Handle of Window Under Mouse"
  1372.     $Call WinQueryClassName,hwndNext0,16,offset ClassNameBuf
  1373.     mov   eax,hwndNext0
  1374.     $WinDebugMessage   ClassNameBuf
  1375.     $Call WinQueryWindowModel,eax        ;0 = 16 bit, 1 = 32 bit
  1376.     .IF  eax == 0
  1377.          mov   eax,16
  1378.     .ELSEIF  eax == 1
  1379.          mov   eax,32
  1380.     .ENDIF
  1381.     $WinInfMsg  "   Bit Window"
  1382.     $Call WinQueryWindow,hwndNext0,QW_OWNER
  1383.     $WinInfMsg  " is Owner of window under mouse"
  1384.     $Call WinQueryWindow,hwndNext0,QW_PARENT
  1385.     $WinInfMsg  " is Parent of window under mouse"
  1386.     pop   eax
  1387.     $Call WinSetFocus,HWND_DESKTOP,eax
  1388.     popa
  1389.     ret
  1390. ProgramTestAlt  Endp
  1391.  
  1392. ProgramTestCtrl  Proc      ;Use for testing things  Shift-Ctrl-5(white)
  1393.     pusha
  1394.     $Call WinQueryPointerPos,HWND_DESKTOP,offset WinPosX
  1395.     ;--- IF FALSE is chosen returns Handle of Frame Window under HWND_DESKTOP
  1396.     ;--- IF  TRUE is chosen returns Handle of Actual Window
  1397.     $Call WinWindowFromPoint,HWND_DESKTOP,offset WinPosX,FALSE
  1398.     mov   hwndNext0,eax
  1399.     $WinInfMsg  "      Handle of Frame of Window Under Mouse"
  1400.     $Call WinBeginEnumWindows,hwndNext0      ;HWND_DESKTOP
  1401.     .IF  eax == PMERR_INVALID_HWND
  1402.          $WinInfMsg   "  Error Calling WinBeginEnumWindows"
  1403.          jmp   xptc
  1404.     .ENDIF
  1405.     mov   henum,eax           ;enum handle
  1406.     mov   ecx,0
  1407.     .WHILE TRUE
  1408.          push   ecx
  1409.          $Call WinGetNextWindow,henum
  1410.          pop    ecx
  1411.          .BREAK .IF eax == 0
  1412.          .IF  ecx == 0
  1413.               mov   hwndNext0,eax
  1414.          .ENDIF
  1415.          .IF  ecx == 1
  1416.               mov   hwndNext1,eax
  1417.          .ENDIF
  1418.          .IF  ecx == 2
  1419.               mov   hwndNext2,eax
  1420.          .ENDIF
  1421.          push   ecx
  1422.          $WinInfMsg  "     Window Handle Value"
  1423.          pop    ecx
  1424.          inc   ecx
  1425.     .ENDW
  1426.     mov  eax,ecx
  1427.     $WinInfMsg   "     Number of Windows below Frame Window"
  1428.     $Call WinEndEnumWindows,henum
  1429.  
  1430.     mov   eax,hwndNext0
  1431.     $Call WinQueryClassName,hwndNext0,7,offset ClassNameBuf
  1432.     mov   eax,hwndNext0
  1433.     $WinDebugMessage   ClassNameBuf
  1434.  
  1435.     $WinInfMsg   "   Enumerating Children of Window to Left"
  1436.     $Call WinBeginEnumWindows,hwndNext0
  1437.     .IF  eax == PMERR_INVALID_HWND
  1438.          $WinInfMsg   "  Error Calling WinBeginEnumWindowsNext0"
  1439.          jmp   xptc
  1440.     .ENDIF
  1441.     mov   henum,eax           ;enum handle
  1442.     .WHILE TRUE
  1443.          $Call WinGetNextWindow,henum
  1444.          .BREAK .IF eax == 0
  1445.          push  eax
  1446.          $Call WinQueryClassName,eax,20,offset ClassNameBuf
  1447.          pop   eax            ;handle back
  1448.          $WinDebugMessage   ClassNameBuf
  1449.     .ENDW
  1450.     $Call WinEndEnumWindows,henum
  1451.     .IF eax == 0
  1452.         $WinInfMsg  "  WinEndEnumWindows"
  1453.     .ENDIF
  1454. xptc: popa
  1455.     ret
  1456. ProgramTestCtrl  Endp
  1457.  
  1458. ;------Write Macro to File  Format is in ASCII HEX in LF/CR separated records
  1459. ;      hwnd msgID mp1 mp2 Time Coord
  1460. ;      Activated by Shift-Ctrl-PgDn(White)
  1461. ;      Format 8 DWords into HEX using $DWordtoHex, copy from DW_Buff to
  1462. ;      fmBuffer, space separating each Dword then write out to file
  1463. ;      The handle at offset 8 in switch structure is handle of parent
  1464. ;      frame of window identified by hwnd in quemsg structure
  1465. WriteMacroAsciiHex   Proc      ;Write Macro to File
  1466.     pusha
  1467.     ;--- first set file size to correspond to number of messages
  1468.     ;fsize = #records x 84 + header
  1469.     mov   eax,JR_Count
  1470.     mov   ecx,84
  1471.     mul   ecx
  1472.     add   eax,84            ;header size
  1473.     mov   fmsize,eax
  1474.     $Call DosOpen,offset fmName,offset fmhandle,offset fmActionTaken,fmsize,fmAttribute,fmOpenFlag,fmOpenMode,fmExtaBuf
  1475.     .IF   eax != 0
  1476.          $WinInfMsg " : DosOpenMacroFile "
  1477.          ret
  1478.     .ENDIF
  1479.     ;----- first write header line
  1480.     $Call DosWrite,fmhandle,offset fmHeader,84,offset fmWritten
  1481.     ;----- then actual data records
  1482.     mov    ebx,msgParms           ;Address of Source
  1483.     mov    edx,JR_Count
  1484.     .WHILE edx > 0
  1485.         mov   ecx,1
  1486.         mov   esi,offset fmBuffer
  1487.         .WHILE ecx <= 7
  1488.             mov  eax,[ebx]
  1489.             .IF  ecx == 1     ;handle from msgparms
  1490.                 mov   HandFromMsg,eax   ;value to be passed
  1491.                 pusha
  1492.                 Call GetNameFromHandle   ;value of handle passed in HandFromMsg
  1493.                 mov  edi,TaskNameAddr    ;address of TaskListName returned
  1494.                 mov  edx,1
  1495.                 add  esi,70
  1496.                 .WHILE  edx <= 12        ;copy to fmBuffer
  1497.                     mov   al,byte ptr[edi]
  1498.                     .IF   al == 13 || al == 10  ;CR or LF
  1499.                         .BREAK
  1500.                     .ENDIF
  1501.                     mov   [esi],al
  1502.                     inc   edx
  1503.                     inc   esi
  1504.                     inc   edi
  1505.                 .ENDW
  1506.                 .IF edx != 13             ;need to fill out with spaces
  1507.                     dec   edx
  1508.                     dec   esi
  1509.                    .WHILE  edx <= 12
  1510.                        mov  byte ptr [esi]," "
  1511.                        inc  esi
  1512.                        inc  edx
  1513.                    .ENDW
  1514.                 .ENDIF
  1515.                 popa
  1516.             .ENDIF
  1517.              mov    eax,[ebx]
  1518.              Call   DwordToHex
  1519.              inc    ecx
  1520.              add    ebx,4                 ;get next parm
  1521.              add    esi,10
  1522.         .ENDW
  1523.         dec   edx
  1524.  
  1525.         $Call DosWrite,fmhandle,offset fmBuffer,84,offset fmWritten
  1526.         .IF   eax != 0
  1527.              $WinInfMsg " : DosWrite "
  1528.              ret
  1529.         .ENDIF
  1530.     .ENDW
  1531.     $Call DosSetFileSize,fmHandle,fmSize
  1532.     $Call DosClose,fmHandle
  1533.     .IF   eax != 0
  1534.          $WinInfMsg " : DosCloseMacroFile "
  1535.          ret
  1536.     .ENDIF
  1537.     popa
  1538.     ret
  1539. WriteMacroAsciiHex   Endp
  1540.  
  1541. ;---- Inserts a TimeDelay of milliseconds  in edx register
  1542. ;---- probably is resolution of timer
  1543. TimeDelay  Proc
  1544.     pusha
  1545.     $Call WinGetCurrentTime,hab
  1546.     mov   CurrentTime,eax
  1547.     add   CurrentTime,edx
  1548.     .WHILE eax < CurrentTime
  1549.         $Call WinGetCurrentTime,hab
  1550.     .ENDW
  1551.     popa
  1552.     ret
  1553. TimeDelay Endp
  1554.  
  1555. ReadDatFile   Proc
  1556. ;----------  IS Data File AVAILABLE AND VALID ? ------------
  1557. ;---------- First see if  hookkbsm.dat exists in proper location ------
  1558.      mov   EOFFlag,0       ;initial value
  1559.      $Call DosOpen,offset fName,offset fhandle,offset fActionTaken,fsize,fAttribute,fOpenFlag,fOpenMode,fExtaBuf
  1560.      .IF   eax != 0
  1561.           $WinErrMsg " : DosOpen "
  1562.           Call   ExitWin
  1563.      .ENDIF
  1564. ;------- get file size
  1565.      $Call DosSetFilePtr,fhandle,0,FILE_BEGIN,offset fpointer0
  1566.      .IF    eax != 0
  1567.           $WinErrMsg " : DosSetFilePtr"
  1568.           Call   ExitWin
  1569.      .ENDIF
  1570.      $Call DosSetFilePtr,fhandle,0,FILE_END,offset fpointer1
  1571.      mov    eax,fpointer1
  1572.      sub    eax,fpointer0
  1573.      mov    fsize,eax        ;fsize now has file size
  1574.      add    eax,16           ;allow a little leeway in buffer
  1575.      push   eax
  1576. ;;------- now allocate memory for file buffers
  1577.      .IF memAddr != 0      ;not first time around
  1578.           $Call DosFreeMem,memAddr
  1579.           .IF eax != 0
  1580.               $WinErrMsg " : DosFreeRegularMem"
  1581.           .ENDIF
  1582.      .ENDIF
  1583.      pop    eax            ;get back size needed
  1584.      $Call DosAllocMem,offset memAddr,eax,memFlags
  1585.      .IF    eax != 0
  1586.           $WinErrMsg " : DosAllocMem FileBuf"
  1587.           Call   ExitWin
  1588.      .ENDIF
  1589. ;------Read File Into buffer and Close file -------
  1590. ;reposition to start of file
  1591.      $Call DosSetFilePtr,fhandle,0,FILE_BEGIN,offset fpointer0
  1592.      $Call DosRead,fHandle,memAddr,fsize,offset nwritten
  1593.      $Call DosClose,fHandle
  1594.      mov   eax,fsize
  1595. ;------ Reset SessT of ExecONKB arrays to 9
  1596.      mov   edi,offset AltX
  1597.      mov   esi,offset CtrlX
  1598.      mov   ecx,1
  1599.      mov   ebx,10
  1600.      .WHILE  ecx <= 36
  1601.           mov  word ptr[edi+ebx],9
  1602.           mov  word ptr[esi+ebx],9
  1603.           inc  ecx
  1604.           add  ebx,10
  1605.      .ENDW
  1606. ;------ Read Buffer and Initialize Arrays ALtX and CtrlX ----
  1607.      mov    esi,memAddr
  1608.      mov    ecx,0               ;Index and Counter for memAddr
  1609.      .WHILE ecx <=  fsize && byte ptr [esi+ecx] != 26   ;Ctrl-Z  Fri  04-30-1993
  1610.          call   SkipSpaces        ;skip over any initial spaces
  1611.          .BREAK .IF EOFflag == 1
  1612.          call   SkipCommentsToEOL ;skip over comments and spaces to first valid entry
  1613.          .BREAK .IF EOFflag == 1
  1614.          call SkipSpaces          ;skip over initial spaces
  1615.          .BREAK .IF EOFflag == 1
  1616.          .IF (byte ptr [esi+ecx] == 'A' || byte ptr [esi+ecx] == 'a' || byte ptr [esi+ecx] == 'C' || byte ptr [esi+ecx] == 'c')
  1617.               inc   ecx           ;point to number or letter
  1618.               xor   eax,eax
  1619.               xor   edx,edx
  1620.               mov  al,byte ptr [esi+ecx]  ;get digit or letter ID
  1621.              .IF  (al >= '0' && al <= '9')
  1622.                   sub  al,'0'         ;convert to decimal
  1623.              .ENDIF
  1624.              .IF  al  >= 'a'
  1625.                   sub  al,32          ;convert to UpperCase
  1626.              .ENDIF
  1627.              .IF  (al >= 'A' && al <= 'Z')
  1628.                   sub  al,37h          ;convert to decimal 10 +
  1629.              .ENDIF
  1630.               mov      dl,LenExec ;Length of Structure    10
  1631.               mul      dl         ;ax has offset into array
  1632.               inc      ecx        ;right after digit/letter id A/C number
  1633.          .ELSE
  1634.               .CONTINUE           ;go around again
  1635.          .ENDIF
  1636.          .IF byte ptr[esi+ecx - 2] == 'A' || byte ptr[esi+ecx - 2] == 'a'
  1637.                mov     edi,offset AltX      ;this is Alt Keys
  1638.          .ENDIF
  1639.          .IF byte ptr[esi+ecx - 2] == 'C' || byte ptr[esi+ecx - 2] ==  'c'
  1640.                mov     edi,offset CtrlX     ;this is a Ctrl Key
  1641.          .ENDIF
  1642.          .IF edi == offset AltX || edi == offset CtrlX
  1643.                mov     edx,eax              ;edx is offset into array
  1644.                call    SkipSpaces           ;go to SessID
  1645.                .BREAK .IF EOFflag == 1
  1646.                xor     eax,eax
  1647.                mov     al,byte ptr [esi+ecx] ;get sess type
  1648.                sub     al,'0'                ;convert to  number
  1649.                mov     word ptr [edi + edx+8],ax
  1650.                inc     ecx
  1651.                call    SkipSpaces            ;get to Exec string
  1652.                .BREAK .IF EOFflag == 1
  1653.                mov     eax,esi
  1654.                add     eax,ecx               ;offset of exec
  1655.                mov     [edi+edx],eax         ;store its address
  1656.                ; have to go to end of Exec string and place a numeric 0 there
  1657.                .WHILE  byte ptr [esi+ecx] != ' '
  1658.                     inc  ecx
  1659.                .ENDW   ;exits    pointing to end of exec command
  1660.                .BREAK .IF byte ptr[esi+ecx] != ' '
  1661.                   mov     byte ptr [esi+ecx],0
  1662.                inc     ecx
  1663.                call    SkipSpaces            ;get next parameter
  1664.                .BREAK .IF EOFflag == 1
  1665.                xor     eax,eax
  1666.                .IF     byte ptr [esi+ecx]== '0'  ;no command line
  1667.                    mov     al,byte ptr [esi+ecx]
  1668.                    sub     al,'0'
  1669.                    mov     [edi+edx+4],eax
  1670.                .ELSE                         ;its a string - copy its address
  1671.                    mov eax,esi
  1672.                    add eax,ecx               ;offset of command line
  1673.                    .IF   byte ptr [esi+ecx] != 22h  ;not a "
  1674.                       mov     [edi+edx+4],eax   ;store command line address
  1675.                       .WHILE  byte ptr [esi+ecx] != ' ' && ecx < fsize  ;skip until a space
  1676.                           .IF byte ptr[esi+ecx] == lf || byte ptr[esi+ecx] == cr  ; LF but no ";"
  1677.                                Call DataFormatErr
  1678.                           .ENDIF
  1679.                            inc  ecx
  1680.                       .ENDW                  ;exits  pointing to end of command line
  1681.                      .BREAK .IF ecx >= fsize
  1682.                       mov    byte ptr [esi+ecx],0 ;put 0 at end
  1683.                    .ELSE                     ;first char is a quote
  1684.                       inc  ecx               ;move beyond it
  1685.                       inc  eax
  1686.                       mov     [edi+edx+4],eax   ;store command line address
  1687.                       .WHILE byte ptr [esi+ecx] != 22h && ecx < fsize ; skip until a "
  1688.                            inc  ecx
  1689.                       .ENDW                  ;exits pointing to final quote
  1690.                       mov    byte ptr [esi+ecx],0 ;put 0 at end
  1691.                       .BREAK .IF ecx >= fsize
  1692.                       inc    ecx
  1693.                       .BREAK .IF byte ptr[esi+ecx] != ' '
  1694.                    .ENDIF
  1695.                .ENDIF
  1696.                .BREAK .IF ecx >= fsize || byte ptr[esi+ecx] == 26 ;Ctrl-Z
  1697.                xor    edi,edi                ;reset to 0 so test can be made
  1698.                .WHILE byte ptr[esi+ecx] != ';' && ecx < fsize  ;go to next comment ;
  1699.                    .IF byte ptr[esi+ecx] == lf || byte ptr[esi+ecx] == cr  ; LF but no ";"
  1700.                         Call DataFormatErr
  1701.                    .ENDIF
  1702.                    inc   ecx
  1703.                .ENDW
  1704.                .BREAK .IF ecx >= fsize || byte ptr[esi+ecx] == 26 ;Ctrl-Z
  1705.                .CONTINUE
  1706.          .ENDIF
  1707.      .ENDW
  1708. ; See if Dat File properly read in
  1709.      .IF byte ptr [esi+ecx] == 26   ;Ctrl-Z
  1710. ;         $WinErrMsg " : Ctrl-Z here"
  1711.      .ELSEIF ecx < fsize
  1712.           Call DataFormatErr
  1713.      .ENDIF
  1714.      ret
  1715. ReadDatFile   Endp
  1716.  
  1717. ;if there are spaces this exits pointing to next non-space else points to non-space
  1718. SkipSpaces   proc    ;just skips over spaces
  1719.    .WHILE ecx < fsize && byte ptr [esi+ecx] == ' '   ;spaces
  1720.         inc ecx
  1721.    .ENDW
  1722.    .IF ecx >= fsize || byte ptr [esi+ecx] == 26  ; Ctrl-Z  Sat  05-01-1993
  1723.         mov EOFflag,1
  1724.    .ENDIF
  1725.     ret
  1726. SkipSpaces   endp
  1727.  
  1728. SkipCommentsToEOL proc    ;skip from ';' to beginning of next line
  1729.     .IF byte ptr[esi+ecx] == ';' && ecx < fsize  ;if a comment
  1730.         inc    ecx
  1731.         .WHILE byte ptr [esi+ecx] != 0ah && ecx < fsize  ;Line feed end of line
  1732.             inc ecx
  1733.         .ENDW                       ;points to 0ah if it exists if not EOF
  1734.         .IF byte ptr[esi+ecx] == 26 ; Ctrl-Z
  1735.             mov EOFflag,1
  1736.         .ENDIF
  1737.     .ELSE
  1738.         mov    eax,ecx              ;bytes processed appears in message
  1739.         call DataFormatErr
  1740.     .ENDIF
  1741.     .IF  byte ptr[esi+ecx] != 0ah   ;must be EOF
  1742.          mov    EOFflag,1
  1743.     .ELSE                           ;it is end of line
  1744.          inc    ecx                 ;goto next line
  1745.          .IF    ecx >= fsize || byte ptr[esi+ecx] == 26  ; Ctrl-Z
  1746.              mov    EOFflag,1
  1747.          .ENDIF
  1748.     .ENDIF
  1749.     ret
  1750. SkipCommentsToEOL endp
  1751.  
  1752. DataFormatErr   Proc
  1753.     mov     eax,ecx            ;bytes processed appears in message
  1754.     mov     ecx,fsize
  1755.     sub     ecx,eax
  1756.     .IF     ecx >= 4           ;Sat  05-01-1993
  1757.         $WinDebugMessage msgFileErr
  1758.         call ExitWin           ;Fri  04-30-1993
  1759.     .ENDIF
  1760.     ret
  1761. DataFormatErr   EndP
  1762.  
  1763. SetJump   Proc           ;set HOOK to be not jumpable
  1764. ;    $Call DosBeep, 800,275
  1765. ;    $Call DosBeep,1200,275
  1766. ;    $Call DosBeep,2500,275
  1767.    $NumSwitchListEntries
  1768.    mov  numitems,eax      ;number of switch list entries
  1769.    dec numitems
  1770.    Call GetSwitchList     ;activate structure
  1771.    mov  edi,baseaddr      ;address of switch list
  1772.    mov  ecx,0
  1773.    mov  bl,'H'
  1774.    mov  bh,'o'
  1775.    mov  dl,'o'
  1776.    mov  dh,'K'
  1777.    .WHILE  ecx < numitems           ;starts at offset 0
  1778.        .IF bl == [edi+36] && bh == [edi+37] && dl == [edi+38]  && dh ==[edi+39]
  1779. ;            $Call DosBeep, 50,1000
  1780.             ;Mark this is as not jumpable
  1781.             mov  dword ptr[edi+32],SWL_NOTJUMPABLE     ;jumpable ?
  1782.             mov  esi,edi
  1783.             add  esi,8
  1784.             $Call WinChangeSwitchEntry,dword ptr[edi+4],esi
  1785.             .BREAK
  1786.        .ENDIF
  1787.        inc   ecx
  1788.        add   edi,swblksize           ;next element in structure
  1789.    .ENDW
  1790.    ret
  1791. SetJump   Endp
  1792.  
  1793. END   startup                       ;required
  1794.  
  1795.  
  1796. ;---- This procedure places the window handle of the true Client Window
  1797. ;---- in the variable hwndActive. It obtains the handle of the Frame
  1798. ;---- Window that is on TOP and uses WinEnumWindows and WinQueryClass
  1799. ;---- to obtain the handle of the Client window which is the window
  1800. ;---- with Class not starting with "#"
  1801. ;GetClientWinHandle  Proc
  1802. ;    push  ebx
  1803. ;    $Call WinQueryActiveWindow,HWND_DESKTOP
  1804. ;    $WinInfMsg  "      is Active Frame"
  1805. ;    mov   hwndActiveFrame,Eax
  1806. ;    $Call WinBeginEnumWindows,hwndActiveFrame
  1807. ;    .IF  eax == PMERR_INVALID_HWND
  1808. ;         $WinInfMsg   "  Error Calling WinBeginEnumWindows"
  1809. ;         ret
  1810. ;    .ENDIF
  1811. ;    mov   henum,eax           ;enum handle
  1812. ;    mov   eax,hwndActiveFrame ;top window
  1813. ;    $Call WinEndEnumWindows,henum
  1814. ;
  1815. ;    $Call WinBeginEnumWindows,hwndActiveFrame
  1816. ;    mov   henum,eax           ;enum handle
  1817. ;    mov   ecx,0
  1818. ;    .WHILE TRUE
  1819. ;         $Call WinGetNextWindow,henum
  1820. ;         .IF eax == 0  && ecx == 0   ; no more
  1821. ;               mov  eax,hwndActiveFrame
  1822. ;               $WinInfMsg  "  Has no children"
  1823. ;               .Break
  1824. ;         .Endif
  1825. ;         push  eax
  1826. ;         $Call WinQueryClassName,eax,20,offset ClassNameBuf
  1827. ;         pop   eax            ;handle back
  1828. ;         mov   ebx,offset ClassNameBuf
  1829. ;         .IF   byte ptr [ebx] != "#"   ;this is the Client window
  1830. ;               mov   WinFlag,1
  1831. ;               mov   hwndActive,eax    ;handle of Client window
  1832. ;               $WinDebugMessage   ClassNameBuf
  1833. ;               .BREAK                  ;exit
  1834. ;         .ENDIF
  1835. ;    .ENDW
  1836. ;    .IF  WinFlag !=1
  1837. ;         $WinInfMsg   "No Match to !=# "
  1838. ;    .ENDIF
  1839. ;    $Call WinEndEnumWindows,henum
  1840. ;    pop   ebx
  1841. ;    ret
  1842. ;GetClientWinHandle  Endp
  1843.  
  1844. ;FillPlaybackDispatchMsg  Proc
  1845. ;    mov   ebx,0
  1846. ;    mov   esi,m_esi
  1847. ;;    mov   edi,offset pb_qmsg
  1848. ;    .WHILE  ebx <= 20
  1849. ;        mov   eax,[esi]       ;0:hwnd 4:msgID 8:mp1 12:mp2 16:time 20:coordinates
  1850. ;        mov   [edi+ebx],eax   ;edi always points to offset of pb_qmsg
  1851. ;        add   ebx,4
  1852. ;        add   esi,4           ;this leaves esi pointing to next record in block
  1853. ;    .ENDW
  1854. ;    add   m_esi,RecdLnth
  1855. ;    $Call WinDispatchMsg,hab,edi  ;offset pb_qmsg
  1856. ;    ret
  1857. ;FillPlaybackDispatchMsg  Endp
  1858.  
  1859. ;---- Determines whether the windowed program is Text or a PM Program.
  1860. ;---- If the Window Class is SHIELD it is text, otherwise it is PM
  1861. ;---- Called Only on KeyDown parameter
  1862. ;WindowType    Proc
  1863. ;    pusha
  1864. ;    mov   WinTypeFlag,0       ;0 is SHIELD type Window Class
  1865. ;    $Call WinQueryPointerPos,HWND_DESKTOP,offset WinPosX
  1866. ;    ;--- IF FALSE is chosen returns Handle of Frame Window under HWND_DESKTOP
  1867. ;    ;--- IF  TRUE is chosen returns Handle of Actual Window
  1868. ;    $Call WinWindowFromPoint,HWND_DESKTOP,offset WinPosX,TRUE
  1869. ;    mov   hwndNext0,eax
  1870. ;    $Call WinQueryClassName,hwndNext0,7,offset ClassNameBuf
  1871. ;    mov   esi,offset ClassNameBuf
  1872. ;    cmp   byte ptr [esi],'S'
  1873. ;    jne   NotPM
  1874. ;    cmp   byte ptr [esi+1],'H'
  1875. ;    jne   NotPM
  1876. ;    cmp   byte ptr [esi+2],'I'
  1877. ;    jne   NotPM
  1878. ;    cmp   byte ptr [esi+3],'E'
  1879. ;    jne   NotPM
  1880. ;    cmp   byte ptr [esi+4],'L'
  1881. ;    jne   NotPM
  1882. ;    cmp   byte ptr [esi+5],'D'
  1883. ;    jne   NotPM
  1884. ;    mov   WinTypeFlag,1
  1885. ;NotPM: popa
  1886. ;    ret
  1887. ;WindowType    Endp
  1888.  
  1889.  
  1890.