home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* HOTKEY.PAS *)
- (* Turbo-Fünfnull-Unit zur Verwaltung von "heißen Tasten" *)
- (* (c) 1989 Jan Hargens & TOOLBOX *)
- (* ------------------------------------------------------ *)
- UNIT HotKey;
-
- INTERFACE
-
- USES Dos; { IMPORT FROM Dos: GetIntVec, SetIntVec }
-
- CONST
- MaxHotkey = 16; { im Grunde reichen wohl auch 8 }
- TYPE
- HotkeyProc = PROCEDURE;
- HotkeyArray = ARRAY[1..MaxHotkey] OF
- RECORD
- HotkeyCode : WORD;
- Proc : HotkeyProc;
- END;
-
- PROCEDURE AddHotkey (KeyCode : WORD;
- ProcToCall : HotkeyProc);
- PROCEDURE DeleteHotkey (KeyCode : WORD);
- PROCEDURE GetHotkeyList (VAR List : HotkeyArray;
- VAR Size : BYTE);
-
- IMPLEMENTATION
-
- TYPE { Registersatz für Interrupt-Prozeduren }
- IntrReg = RECORD CASE BOOLEAN OF
- true : (bp, es, ds, di, si, dx, cx, bx, ax,
- ip, cs, flags : WORD);
- false: (xx : ARRAY [1..10] OF BYTE;
- dl, dh, cl, ch, bl, bh, al, ah : BYTE);
- END;
- VAR Hotkeys : HotkeyArray;
- NumberOfHotkeys : 0..MaxHotkey;
- SaveInt16,
- SaveExit : POINTER;
-
- (* -------------- Interrupt-Serviceroutinen ------------- *)
- PROCEDURE ChainInt(Regs : IntrReg; Address : POINTER);
- INLINE ($5b/$58/$5e/$1f/$87/$5c/$0e/$87/$44/$10/$8b/
- $54/$16/$52/$9d/$8c/$da/$fa/$8e/$d2/$89/$f4/
- $fb/$5d/$07/$1f/$5f/$5e/$5a/$59/$cb);
-
- FUNCTION KeyFromOldInt16 : Word;
- INLINE ($31/$C0/$9C/$FF/$1E/SaveInt16);
-
- FUNCTION HotkeyPos(Code : WORD) : BYTE;
- VAR
- Count : BYTE;
- BEGIN
- Count := NumberOfHotkeys;
- WHILE (Count>0) AND (Hotkeys[Count].HotkeyCode<>Code) DO
- Dec(Count);
- HotkeyPos := Count;
- END;
-
- PROCEDURE AddHotkey(KeyCode : WORD;
- ProcToCall : HotkeyProc);
- BEGIN
- IF (NumberOfHotkeys < MaxHotkey) AND
- (HotkeyPos(KeyCode) = 0) THEN BEGIN
- Inc(NumberOfHotkeys);
- WITH Hotkeys[NumberOfHotkeys] DO BEGIN
- HotkeyCode := KeyCode;
- Proc := ProcToCall;
- END;
- END;
- END;
-
- PROCEDURE DeleteHotkey(KeyCode : WORD);
- VAR
- Position : BYTE;
- BEGIN
- Position := HotkeyPos(KeyCode);
- IF Position <> 0 THEN BEGIN
- Hotkeys[Position] := Hotkeys[NumberOfHotkeys];
- FillChar(Hotkeys[NumberOfHotkeys],
- SizeOf(Hotkeys[1]), 0);
- Dec(NumberOfHotkeys);
- END;
- END;
-
- PROCEDURE GetHotkeyList(VAR List : HotkeyArray;
- VAR Size : BYTE);
- BEGIN
- List := Hotkeys;
- Size := NumberOfHotkeys;
- END;
-
- PROCEDURE CheckHotkey(bp : WORD); INTERRUPT {16h};
- VAR
- r : IntrReg ABSOLUTE bp;
- HotkPtr : 0..MaxHotkey;
- BEGIN { wird vor BIOS-Interrupt $16 «geklemmt». }
- IF r.ah = 0 THEN REPEAT
- r.ax := KeyFromOldInt16;
- HotkPtr := HotkeyPos(r.ax);
- IF HotkPtr <> 0 THEN BEGIN
- SetIntVec($16, SaveInt16);
- { nicht rekursiv (tödlich!) }
- Hotkeys[HotkPtr].Proc;
- { Prozeduraufruf (!!), erst ab TP 5.0 }
- SetIntVec($16, @CheckHotkey); { wieder einhaken }
- END;
- UNTIL HotkPtr = 0 ELSE
- ChainInt(r, SaveInt16);
- END;
-
- {$F+} { Exit-Prozedur; MUSS als FAR compiliert werden }
- PROCEDURE DeInstall;
- BEGIN
- SetIntVec($16, SaveInt16);
- ExitProc := SaveExit;
- END;
- {$F-}
-
- PROCEDURE Install;
- BEGIN
- GetIntVec($16, SaveInt16);
- SaveExit := ExitProc;
- ExitProc := @DeInstall;
- SetIntVec($16, @CheckHotkey);
- END;
-
- BEGIN
- NumberOfHotkeys := 0;
- FillChar(Hotkeys, Sizeof(Hotkeys), 0);
- Install;
- END.
- (* ------------------------------------------------------ *)
- (* Ende von HOTKEY.PAS *)