www.pudn.com > dfs.zip > DFSKb.pas, change:1998-11-25,size:4221b


{.$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.