home *** CD-ROM | disk | FTP | other *** search
- {.$DEFINE DFS_DEBUG}
-
- { Interface to the DFSKbMon.DLL library. }
- { Intended for use with the TDFSStatusBar component (DFSStatusBar.pas) }
-
- unit DFSKb;
-
- interface
-
- uses
- {$IFDEF DFS_DEBUG}
- DFSDebug,
- {$ENDIF}
- Windows;
-
- {
- DFSKbDLLName contains the full filepath to the DLL to be loaded. It defaults
- to just 'DFSKbMon.dll' so that the path is searched. Change before calling
- InitDFSKbDLL if you want to specify a location.
- DFSKbDLL_Loaded indicates whether the DLL was loaded or not.
- }
- var
- DFSKbDLLName: string;
- DFSKbDLL_Loaded: boolean;
-
- { Call before anything else to load the DLL and set up everything. }
- procedure InitDFSKbDLL;
- { Call if you want to manually unload the DLL. Don't normally need since it
- will do it automatically at app exit. }
- procedure UnloadDFSKbDLL;
- { Ask to be notified of Caps, Num, Scroll lock changes. Return value is the
- window message that will be sent to notify of change, or 0 if failed. }
- function DLLRegisterKeyboardHook(Handle: HWND): UINT;
- { Remove from notification list. }
- procedure DLLDeregisterKeyboardHook(Handle: HWND);
-
- implementation
-
- uses
- Classes, SysUtils;
-
- var
- DLLRegisterKeyboardHookPtr: function (Handle: HWND): UINT; stdcall;
- DLLDeregisterKeyboardHookPtr: procedure (Handle: HWND); stdcall;
- hDFSKbDLL: THandle; { DLL handle }
- RegisteredClients: TList;
-
- { Load the DLL and get all the procedure addresses. }
- function LoadDFSKbDLL: boolean;
- var
- OldMode: UINT;
- begin
- {$IFDEF DFS_DEBUG}
- DFSDebug.Log('DFSKb: LoadDFSKbDLL start', TRUE);
- {$ENDIF}
- if hDFSKbDLL <> 0 then
- FreeLibrary(hDFSKbDLL);
- OldMode := SetErrorMode(SEM_NOOPENFILEERRORBOX); { No system messages if can't load. }
- hDFSKbDLL := LoadLibrary(PChar(DFSKbDLLName));
- Result := hDFSKbDLL <> 0;
- SetErrorMode(OldMode);
- if not Result then exit;
-
- { Get all the function addresses }
- @DLLRegisterKeyboardHookPtr := GetProcAddress(hDFSKbDLL, 'RegisterKeyboardHook');
- @DLLDeregisterKeyboardHookPtr := GetProcAddress(hDFSKbDLL, 'DeregisterKeyboardHook');
- {$IFDEF DFS_DEBUG}
- DFSDebug.Log('DFSKb: LoadDFSKbDLL end', TRUE);
- {$ENDIF}
- end;
-
- { Procedure called when unit is finished, i.e. app exiting. }
- procedure CleanupDLL;
- var
- x: integer;
- begin
- {$IFDEF DFS_DEBUG}
- DFSDebug.Log('DFSKb: CleanupDLL start', TRUE);
- {$ENDIF}
- if hDFSKbDLL <> 0 then
- begin
- // Paranoia check
- if RegisteredClients.Count > 0 then
- begin
- {$IFDEF DFS_DEBUG}
- DFSDebug.Log('DFSKb: Paranoia failed', TRUE);
- {$ENDIF}
- for x := RegisteredClients.Count-1 downto 0 do
- DLLDeregisterKeyboardHook(HWND(RegisteredClients[x]));
- end;
-
- {$IFDEF DFS_DEBUG}
- DFSDebug.Log('DFSKb: attempting FreeLibrary', TRUE);
- {$ENDIF}
- if FreeLibrary(hDFSKbDLL) then
- begin
- {$IFDEF DFS_DEBUG}
- DFSDebug.Log('DFSKb: unloaded DLL', TRUE);
- {$ENDIF}
- hDFSKbDLL := 0;
- DFSKbDLL_Loaded := FALSE;
- end;
- end;
- {$IFDEF DFS_DEBUG}
- DFSDebug.Log('DFSKb: CleanupDLL end', TRUE);
- {$ENDIF}
- end;
-
- procedure InitDFSKbDLL;
- begin
- DFSKbDLL_Loaded := LoadDFSKbDLL;
- end;
-
- procedure UnloadDFSKbDLL;
- begin
- CleanupDLL;
- end;
-
- function DLLRegisterKeyboardHook(Handle: HWND): UINT;
- begin
- if @DLLRegisterKeyboardHookPtr <> NIL then
- begin
- RegisteredClients.Add(Pointer(Handle));
- Result := DLLRegisterKeyboardHookPtr(Handle);
- end else
- Result := 0;
- end;
-
- procedure DLLDeregisterKeyboardHook(Handle: HWND);
- begin
- if @DLLDeregisterKeyboardHookPtr <> NIL then
- begin
- RegisteredClients.Remove(Pointer(Handle));
- DLLDeregisterKeyboardHookPtr(Handle);
- end;
- end;
-
-
- initialization
- {$IFDEF DFS_DEBUG}
- DFSDebug.Log('DFSKb: init begin', TRUE);
- {$ENDIF}
- RegisteredClients := TList.Create;
- DFSKbDLLName := 'DFSKbMon.dll';
- hDFSKbDLL := 0;
- {$IFDEF DFS_DEBUG}
- DFSDebug.Log('DFSKb: init end.', TRUE);
- {$ENDIF}
-
- finalization
- {$IFDEF DFS_DEBUG}
- DFSDebug.Log('DFSKb: finalization begin.', TRUE);
- {$ENDIF}
- CleanupDLL;
- RegisteredClients.Free;
- {$IFDEF DFS_DEBUG}
- DFSDebug.Log('DFSKb: finalization end.', TRUE);
- {$ENDIF}
-
- end.
-
-
-