home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / MKHOOK1.ZIP / HOOK_KB.DOC < prev    next >
Internet Message Format  |  1992-09-05  |  17KB

  1. From : Morton F. Kaplon  CIS : 73457,437
  2.        1047 Johnston Drive
  3.        Bethlehem PA 18017
  4.        (215)758-9686
  5.  
  6. To   : Those Concerned
  7.  
  8. Sat  09-05-1992
  9.  
  10. Subject : Hooking the Keyboard in OS/2 2.0  (Revised)
  11.  
  12. REVISION NOTE
  13.  
  14.   This revision uses the hook HK_INPUT instead of HK_SENDMSG and hooks WM_CHAR
  15.   rather than WM_TRANSLATEACCEL. The conflicts that existed with KWIKINF no
  16.   longer exists and the kludge that was used is no longer required.
  17.  
  18.  
  19. INTRODUCTION
  20.  
  21.   Hook_kb works in conjunction with hook_dll, a dynamic link module. hook_dll
  22.   captures Key Strokes (via sampling the systen nessage queue) from all
  23.   Windows BUT OS/2 or DOS Full Screen. To capture from these would require an
  24.   additional program but since my principal purpose was to create a program
  25.   that would allow me to assign the calling of programs to Alt-# or Ctrl-#
  26.   keystrokes independent of where I was working and since not using Full
  27.   Screen has advantages in flexibility, I decided to go without it.
  28.  
  29.  
  30. OVERVIEW
  31.  
  32.   FILES REQUIRED TO CREATE hook_kb.EXE AND hook_dll.DLL
  33.   doswin32.mac  Macros and Equates used by Programs
  34.  
  35.   hook_kb.asm   Source for Executable, Assembled and Linked by mlc-w386.cmd
  36.  
  37.   hook_dll.def  Define file needed by IMPLIB and linker for hook_dll.asm
  38.  
  39.   hook_dll.asm  Source for hook_dll.dll, Assembled and linked by dll-w386.cmd
  40.  
  41.   dll-w386.cmd  IMPLIB with hook_dll.def creates c:\toolkt20\os2lib\hook_dll.lib
  42.   (a CMD File)  MASM then assembles hook_dll.asm, LINK386 produces hook_dll.dll
  43.                 and hook_dll.dll is copied to c:\os2\dll
  44.  
  45.   mlc-w386.cmd  MASM assembles hook_kb.asm and LINK386 produces hook_kb.exe
  46.   (a CMD File)
  47.  
  48.   To ASSEMBLE and LINK use the directory holding the above files as default
  49.   and the commands below to produce the necessary files.
  50.      dll-w386  hook_dll
  51.      mlc-w386  hook_kb
  52.  
  53.   FILES REQUIRED TO EXECUTE hook_kb.EXE
  54.   hook_kb.dat   Text File assigning programs to key strokes-read by hook_kb.
  55.                 The user creates this file according to structure outlined in
  56.                 the sample. MUST BE LOCATED IN C:\OS2. Edit the sample to
  57.                 fit your needs.
  58.  
  59.   hook_kb.exe   Exec file created above
  60.  
  61.   hook_dll.dll  Dynamic Load File Created Above - must be in c:\os2\dll
  62.  
  63.   DO NOT RENAME hook_dll.* or hook_kb.DAT as those names are coded into
  64.   hook_kb.ASM .
  65.  
  66.   The assembler used is MASM 6.0 including its built in MACROS for control
  67.   structures and segment definitions.
  68.  
  69.  
  70.   PROGRAM METHOD
  71.  
  72.   The system message queue is hooked using the HK_INPUT parameter. The
  73.   function which samples the message queue is in hook_dll.DLL. In the section
  74.   "Input Hook", p. 30-2 in the Programming Guide, Vol. II, it states : "The
  75.   system calls an input_hook function whenever the WinGetMsg or WinPeekMsg
  76.   functions is about to return a message." The installed function tests for
  77.   WM_CHAR and when detected POSTS the mp1 and mp2 parameters of the message to
  78.   HOOK_KB which tests for the following set of Key Strokes: Alt-Del (NumPad),
  79.   Alt-0 to Alt-9 and Ctrl-0 to Ctrl-9. (The restriction is mine since I did
  80.   not want to interfere with keystrokes used by my editor and OS/2 uses a lot
  81.   of the Function Keys). The Alt-Del key-stroke is assigned to removing the
  82.   DLL from memory and closing the program, equivalent to unloading a TSR in
  83.   DOS.
  84.  
  85.   The main program, hook_kb.exe, a PM program, sets up the hook, receives the
  86.   message indicated above and takes the appropriate action depending on the
  87.   Key Stroke. The program is established as Invisible and Not listed in the
  88.   Window List. The program should be launched from an OS/2 window with the
  89.   START command, i.e. "START hook_kb". That command can be placed in a
  90.   STARTUP.CMD for automatic loading.
  91.  
  92.   The flow of hook_kb is delineated below. The same headings are listed in
  93.   the source code in hook_kb.ASM.
  94.  
  95.  
  96.   PROGRAM FLOW : hook_kb
  97.  
  98.   PRELIMINARIES
  99.     Define Model and Calling Protocol
  100.     Equates for Using Macros in .DATA
  101.     Equates for INC files
  102.     Include file listings
  103.     Prototype definitions for MASM
  104.     Structure definition for storing info on Program Assignment to Keys
  105.  
  106.   .STACK   defines an 8KB stack
  107.  
  108.   .DATA    contains variables,parameters and strings required for .CODE section
  109.  
  110.   .CODE    outlined below
  111.  
  112.   ESTABLISH WINDOW
  113.     WinInitialize            ;Initialize
  114.     WinCreateMessageQueue    ;Create a Message Queue
  115.     WinRegisterClass         ;Registers and identifies MainWinProc as name
  116.                              ;of Procedure for messages
  117.     WinCreateStdWindow       ;Creates window - here it is made Invisible,etc.
  118.  
  119.   IS hook_dll.DLL LOADED ?   ;If yes, display message and exit
  120.  
  121.   ALLOCATE SHARED MEM AND STORE HANDLE Returned by WinCreateStdWindow
  122.     This is required in order to pass the Handle to hook_dll
  123.  
  124.  IS DATA FILE AVAILABLE AND VALID ?  ;for custom use may not be required
  125.     Load c:\os2\hook_kb.dat  ;If it does not exist, exit with Error Message
  126.     Get hook_kb.dat FileSize ;Required by program for subsequent use
  127.     AllocateMemoryBuffer     ;Buffer for User Key assignments from DataFile
  128.     Copy hook_kb.dat->Buffer ;Read File into Buffer
  129.     Close hook_kb.dat        ;No longer needed
  130.     Process Data in Buffer   ;If Format Not Correct, EXIT with  Message
  131.  
  132.   ESTABLISH THE HOOK
  133.     DosLoadModule            ;Loads hook_dll.dll
  134.     DosQueryProcAddr         ;Get the address of the function in the DLL
  135.     WinSetHook               ;Uses the Address above and HK_INPUT to set HOOK
  136.  
  137.   CREATE MAIN MESSAGE LOOP   ;Standard PM requirement but EXIT TEST is
  138.                              ;commented out - a WM_QUIT message has no
  139.                              ;impact here
  140.  
  141.   EXIT ROUTINE               ;Note this is commented out but is included
  142.                              ;to demonstrate the overall structure of
  143.                              ;setting up a PM program
  144.  
  145.   PROCESS MESSAGE QUEUE      ;The heart of a PM program
  146.  
  147.     MainWinProc              ;Processes message queue
  148.       TEST SYSTEM QUEUE FOR MESSAGES FROM
  149.         WM_CREATE
  150.         WM_PAINT
  151.         WM_CHAR
  152.         WM_USER+200h             ;dispatched from hook_dll.dll
  153.         IF msg = WM_USER+200h
  154.          FILTER KEYSTROKES      ;Can be customized and code below replaces
  155.          IF Alt-Del struck
  156.               Release DLL,Memory, Close Queues and Windows and Exit
  157.           ELSE
  158.               Test for keystrokes ALt-0 to Alt-9 and Ctrl-0 to Ctrl-9.If
  159.               assigned in hook_kb.dat then call DosStartSession with
  160.               parameters to start desired programs. The programs that may be
  161.               started are OS/2 or DOS Windows, CMD or BAT files, or any OS/2
  162.               or DOS executables (EXE or COM).
  163.           ENDIF
  164.         ENDIF
  165.  
  166.   The flow of hook_dll is delineated below. The same headings are listed in
  167.   hook_kb.DLL.
  168.  
  169.   PROGRAM FLOW : hook_dll
  170.  
  171.   PRELIMINARIES
  172.     Define Model and Calling Protocol
  173.     Equates for INC files
  174.     Include file listings
  175.  
  176.   .STACK   defines a 2KB stack
  177.  
  178.   .DATA    contains variables,parameters and strings required for .CODE section
  179.  
  180.   .CODE    delineated below
  181.  
  182.   ESTABLISH InputHook
  183.  
  184.   GET ADDRESS OF SHARED MEMORY
  185.  
  186.   GET HANDLE OF hook_kb AND RELEASE SHARED MEMORY
  187.  
  188.   IF WM_CHAR MESSAGE DETECTED
  189.        WinPostMessage to hook_kb
  190.   ENDIF
  191.  
  192.  
  193. DISCUSSION
  194.  
  195.  
  196.   DOSWIN32.MAC  (Macros and Equates used by Program)
  197.  
  198.   This file contains the equates, EXTRN declarations, MACROS and Procedures
  199.   used in the ASM files. The EXTRN declarations include many more than those
  200.   used in the program but represent the accrued list of those used so far in
  201.   my OS/2 assembler programming. (As I use a new one, I just add it).
  202.  
  203.   Included are two defines used in the .DATA section of hook_kb.asm. The
  204.   single most important MACRO is $CALL. This allows one to list parameters
  205.   after the function name in the same order as they are listed in the OS/2 2.0
  206.   Technical Manuals. The macro pushes them on the stack in the correct order
  207.   and resets the stack pointer after the call. It could clearly easily be
  208.   extended to accomodate a longer parameter list. Following that are several
  209.   useful macros and three others defined via equates.
  210.  
  211.   For displaying error messages and rudimentary inline debugging, there are
  212.   three macros named $DosErrMsg, $WinErrMsg and $WinDebugMessage . The first
  213.   two are meant to be called after an API function call to display the error
  214.   number for the function used. Information on the success of the call is
  215.   returned in EAX and this must be tested. Note EAX returns differently for
  216.   DOS than for WIN calls. The user passes the text string for the Function
  217.   used on the parameter line for the $XXXErrMsg. $DosErrMsg can only be used
  218.   in Text Windows while $WinErrMsg only in PM windows.
  219.  
  220.   Finally there are several macros and procedures used for Binary <-> ASCII
  221.   conversion for both Decimal and Hex, and also for displaying numerical
  222.   results in Binary form. Not all of these are used but are included as a part
  223.   of the overall package. Note that in 32 bit mode, it is most convenient to
  224.   do all these conversion as DWORDS. These are required for numerical to ASCII
  225.   conversion for the error messages.
  226.  
  227.   hook_dll.DEF
  228.  
  229.   This file is required by both IMPLIB and LINK386 in the creation of
  230.   hook_dll.dll. It identifies the function(s) exported from the DLL.
  231.  
  232.   hook_dll.ASM
  233.  
  234.   This file represents the dynamic link code. It contains one function, named
  235.   InputHook whose syntax is defined by OS/2 on page 30-2 of the Programming
  236.   Guide, Vol II of the OS/2 Technical Library. This DLL monitors the system
  237.   message queue and looks for the message WM_CHAR.
  238.  
  239.   Since I decided to use WinPostMsg to return information to hook_kb, its
  240.   handle is required in this program. The simplest way seemed to be to pass it
  241.   in a shared memory region established by hook_kb. Thus the first task done
  242.   by the function InputHook, after setting itself up, is to get the address of
  243.   the shared memory region and to obtain the handle of hook_kb that was placed
  244.   there by hook_kb. After that is done, the shared memory is released.
  245.  
  246.   The program then waits for a message WM_CHAR and when that is detected it is
  247.   posted to hook_kb using WinPostMsg with the message ID of WM_USER+200h and
  248.   sending the parameters mp1 and mp2 that were contained in message WM_CHAR.
  249.   This DLL is released from memory when hook_kb is closed.
  250.  
  251.   hook_kb
  252.  
  253.   The first four WIN... function calls are a standard calling sequence in
  254.   setting up a PM program. Since a PM program cannot display text using DOS
  255.   write calls, error messages cannot be displayed with Window Message Calls
  256.   until the Window is initialized with the first call.
  257.  
  258.   After the window is established a test is done to see if HOOK_DLL is loaded.
  259.   If it is a message is given and the program terminates. A Shared Memory area
  260.   is then established. Its sole use in this program is to furnish a method of
  261.   passing hook_kb's handle to hook_dll. This is done following the call to
  262.   DosAllocSharedMem. Note that eax is now tested for a non-zero value
  263.   indicating an error, as contrasted to Win calls where a 0 returned in eax
  264.   indicates an error.
  265.  
  266.   Next the program attempts to load the data file c:\os2\hook_kb.dat. If it
  267.   does not exist, an error message is displayed and the program terminates. If
  268.   it loads, its size is obtained (note the calls are rather similar to what
  269.   you would do in DOS) and that value is used to create a buffer to hold the
  270.   file in memory. The file is read into the buffer and then closed. The big
  271.   .WHILE loop reads the buffer and assigns the Addresses of the Executable
  272.   program name and Command Line parameters and the Session type to the
  273.   appropriate member of the Structure ExecOnKb and places a 0 at the end of
  274.   strings in order that they meet the requirement of being ASCIIZ strings. If
  275.   the count of characters read in the buffer does not equal the file size or
  276.   if the data file was not properly formatted, an error message is displayed
  277.   and the program terminated; the error message displays the number of bytes
  278.   of the buffer processed when the program terminated.
  279.  
  280.   If everything is in order, the HOOK is now established with the next three
  281.   calls to DosLoadModule, DosQueryProcAddr and WinSetHook.
  282.  
  283.   The Main Message Loop is next established. Normally this loop is exited when
  284.   WM_QUIT is received and the exit code is executed to gracefully terminate
  285.   the program. However, in this program, to ensure that it is terminated only
  286.   by the Key Combination Alt-Del, the Main Message Loop is not exitable (I
  287.   have commented out the normal tests) and I have included the Exit code only
  288.   for purposes of demonstration of what a more normal program would look like.
  289.  
  290.   The procedure MainWinProc examines the message queue. It first sets up to
  291.   get the parameters passed on the stack and goes through a series of tests
  292.   for specific messages. In a C program this would usually be a Case
  293.   statement. There is no requirement for these tests to do anything in this
  294.   case since the window is invisible but they are required to respond to
  295.   certain system calls.
  296.  
  297.   The heart of the program is the test for WM_USER+200h . WM_USER defines a
  298.   lower limit for message IDs that is (presumably) guaranteed not to conflict
  299.   with any system messages. I have arbitrarily used WM_USER + 200h. HOOK_DLL
  300.   uses this message ID in posting its information to this programs message
  301.   queue. First a test is done to see whether Alt-Del was struck and if so, the
  302.   system is closed and exited. If not, tests are done to see whether the Alt
  303.   or Ctrl Key was down along with one of the keys 1,2,,,0. If so, the Scan
  304.   Code of the keys 1,2,...,0 is then decremented by two so that ScanCode*10
  305.   acts as an index into either of the structures based on ExecOnKB where
  306.   information from the file hook_kb.dat is stored.
  307.  
  308.   Depending on the key combination struck, the address of the program, address
  309.   of the command line parameters and the Session Type for the Key Combination
  310.   identified in the message is obtained and inserted into the StartData
  311.   structure required for the function. DosStartSession is then called with
  312.   appropriate parameters.
  313.  
  314.   Note that WinSetFocus is called before DosStartSession. The programs started
  315.   by DosStartSession will not be in the foreground unless the program calling
  316.   DosStartSession is in the foreground and it seems reasonable that programs
  317.   called with a "HotKey" want to be in the foreground.
  318.  
  319.   The four procedures at the very end are just routines used by parts of the
  320.   code in the program.
  321.  
  322.   It should be noted that hook_kb can be adopted to other uses. Hook_dll can
  323.   be used unchanged but by making appropriate changes to hook_kb.asm, you can
  324.   tailor it to your needs. In the listing of the program flow, comments
  325.   indicate code sections that are optional for customization for other
  326.   requirements.
  327.  
  328.   I have found this program very useful, particularly with respect to programs
  329.   using COM ports. Since OS/2 will not allow you to have two programs open at
  330.   the same time that use the same COM port, this affords a rapid means of
  331.   serially accessing programs sharing a common COM port. Another use I have
  332.   found effective is to assign MENUS to some of the Hot Keys. In my sample
  333.   hook_kb.dat file, the assignment to Alt-5, "loadq", is a CMD file that
  334.   displays a menu for editing a variety of different files. You can readily
  335.   assign any program assigned to an ICON to a hot key, presuming the program
  336.   has an executable form or can be called as a parameter to another program.
  337.   But by far I have found it an efficient expediter for rapidly accessing
  338.   programs without changing anything on your DeskTop.
  339.  
  340.   As it was with TSR's in DOS, you must be careful of your assignments so that
  341.   required keys in programs are not made unavailable. That stricture was
  342.   reflected in my choice of keys to assign and reflects my particular
  343.   concerns. A natural question to ask is - are there any problems with other
  344.   programs that may be sampling the system message queue? Two such programs
  345.   that I am aware of are CMDLINE and KWIKINF. CMDLINE is a commercial program
  346.   that hooks the Keyboard and KWIKINF which also hooks the Keyboard is a
  347.   program included with IBM's Toolkit - it offers a quick search facility.
  348.  
  349.   I have observed no problems with HOOK_KB loaded and both CMDLINE and KWIKINF
  350.   also loaded.
  351.  
  352.