{******************************************************************************
*  Copyright  2002-2008 Dipl.-Ing. H.-D. Kassl  All rights reserved.
*
*  Kassl GmbH
*  27607 Langen (Germany)
*  phone: +49 4743 911021
*  fax  : +49 4743 911022
*
*  http://www.dwinlock.kassl.de
*  e-mail: support@Kassl.de
*
*  this unit includes all interface functions to the dWinlock dwlGina3.dll
*
******************************************************************************}
unit dwlCore;
interface

uses
  windows;

const
  MOD_ALL          = 255;  // constant to disable Key with all modifiers (Ctrl,Shift,Alt,Win)
  MOD_ALT          = 1;    // defined in unit windows
  MOD_CONTROL      = 2;
  MOD_SHIFT        = 4;
  MOD_WIN          = 8;


  DWL_MAJORVERSION = 3;    // actual version of dwlcore
  DWL_SUBVERSION   = 02;
  DWL_VERSION      = (DWL_MAJORVERSION shl 16) or DWL_SUBVERSION;

  wlTaskBar         = 1;   // Constants for disable Desktop items
  wlDesktop         = 2;   // see also procedure wlDisableItem
  wlStartbutton     = 3;
  wlTaskLinks       = 4;
  wlTaskTray        = 5;
  wlTaskRebar       = 6;
  wlAccessibility   = 7;
  wlAccHighContrast = 8;
  wlAccFilterKeys   = 9;
  wlAccMouseKey     = 10;
  wlAccStickyKeys   = 11;
  wlAccToggleKeys   = 12;
  wlShutdown        = 13;
  wlStartmenu       = 14;

  // dwlInstallFlags to use with wlInstallDwl and wlUninstallDwl
  giForceNothing   = 0;
  giForceInstall   = 1;
  giForceUninstall = 2;
  giForceReboot    = 4;
  giNoReboot       = 8;
  giNoWarnings     =16;

  vWinunknown      = 1;
  vWin95           = 2;
  vWin98           = 3;
  vWinMe           = 4;
  vWinNT           = 5;
  vWin2000         = 6;
  vWinXP           = 7;
  vWinVista        = 8;
  vWin7            = 9;

  kDownEvents      = 1;
  kUpEvents        = 2;

  VK_STARTMENU     = 400;
  dwldll           = 'dwlgina3.dll';


type
  TdwlKeyCallbackMethod =  procedure (Wnd: hwnd; Down,vk,mf: integer) of object; {$IFNDEF CLR} stdcall; {$ENDIF}
  TdwlKeyCallbackFunc   =  procedure(UserData: integer; Wnd: hwnd; Down,vk,mf: integer); stdcall;

  TdwlQueryEndSessionCallbackFunc = function(UserData: integer; wParam,lParam: integer): integer; stdcall;
  TdwlQueryEndSessionCallbackMethod = function (wParam,lParam: integer): integer of object; stdcall;

  procedure wlDisableItem(item: integer; disable: integer);
  function  wlIsItemDisabled(item: integer): integer;
  function  wlDisableKey(window: hwnd; vk, mf: integer; disable: integer):integer;
  function  wlIsKeyDisabled(window: hwnd; vk, mf: integer):integer;
  procedure wlSetKeySendMessage(window: hwnd; keyDownMessageId: integer; keyUpMessageId: integer);
  procedure wlSetKeyPostMessage(window: hwnd; keyDownMessageId: integer; keyUpMessageId: integer);
  function  wlGetDisabledKey(index: integer; var window: hwnd; var vk,mf,vkout,mfout: integer): integer;

  function  wlGetDisabledMessage(i: integer; var window: hwnd; var msgId: integer): integer;
  function  wlIsMessageDisabled(window: hwnd; msgId: integer): integer;
  function  wlDisableMessage(window: hwnd; msgId: integer; disable: integer): integer;

  function  wlDisableMouseArea(window: hwnd; mouseButton: integer; mf: integer; x,y,h,w,id: integer; disable: integer): integer;
  function  wlSetStartMenu(window: hwnd): integer;

  {$IFNDEF CIL}
  procedure wlSetKeyCallback(callback: TdwlKeyCallbackFunc; Flags: integer);
  procedure wlSetShutdownCallback(callback: TdwlQueryEndSessionCallbackMethod);
  {$ENDIF}
  procedure wlSetObjKeyCallback(callback: TdwlKeyCallbackMethod;Flags: integer);
  function  wlInstallDwl(flags: integer):integer;
  function  wlUninstallDwl(flags: integer):integer;
  function  wlIsDwlInstalled:integer;
  function  wlIsNTSystem: integer;
  function  wlIs64BitWindows: integer;
  function  wlNeedDwlInstall: integer;
  function  wlExitWindows(flags: integer): integer;
  function  wlWinVersion: integer;
  function  wlVersion(requestedVersion: integer = DWL_VERSION): integer;
  function  wlGetKeyState(vk: Integer): integer;
  procedure wlSetKeyState(vk: Integer; turnOn: integer);
  procedure wlRestoreAll;
  function  wlIsAdmin: boolean;
  function  wlEnableAutologin(defUser: string; pass: string; enable: integer; domain: string): integer;
  function  wlWriteReg(key: HKey; subKey, item: string;value: string): integer;
  function  wlMapScancode(inputCode: integer; outputCode: integer): integer; // returns old mapping
  procedure wlDisableDesktopIcon(index: integer);
  function  wlDesktopIconCount: integer;
  procedure wlRestoreDesktopIcons;
  function  wlReplaceKey(window: hwnd; vk: integer; mf: integer; vkout: integer; mfout: integer): integer;
  function  wlIsKeyReplaced(window: hwnd; vk: integer; mf: integer):integer;
  procedure wlStrToVk(keyStr: string; var window: string; var vk, mf: integer);
  procedure wlVkToStr(window: string; vk, mf: integer; var keyStr: string);
  function  wlGetItemHandle(Item: integer): hwnd;
  procedure wlSendKeyDown(vk: word; mf: integer );
  procedure wlSendKeyUp(vk: word; mf: integer );

  procedure wlExit;
  function  GetClassName(Handle: hwnd): string;

 implementation


{$IFDEF CIL} // if Delphi .Net

//----------------------------------------------------------------------------
// Begin Delphi .NET source code
//----------------------------------------------------------------------------
  uses System.Security.Permissions,
       System.Text,
       System.Windows.Forms,
       System.Runtime.InteropServices;

  const
    WM_DWLKEYDOWN = $0400 + 444;
    WM_DWLKEYUP   = $0400 + 445;

 // [DllImport('user32.dll', CharSet = CharSet.Auto, SetLastError = True, EntryPoint = 'GetClassName')]
 // function WinGetClassName(hwnd: hwnd; lpClassName: StringBuilder; nMaxCount: Integer): Integer; external;

  // pascal implemention of windows get classname method
  function GetClassName(Handle: hwnd): string;
  var
    Buffer: StringBuilder;
  begin
    Buffer := StringBuilder.Create(255);
    Windows.GetClassName(Handle, Buffer, 255);
    Result := Buffer.ToString;
  end;

  [DllImport(dwldll, EntryPoint = 'wlDisableItem')]
  procedure wlDisableItem(Item: integer; disable: integer); external;

  [DllImport(dwldll, EntryPoint = 'wlIsItemDisabled')]
  function  wlIsItemDisabled(Item: integer): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlDisableKey')]
  function  wlDisableKey(window: hwnd; vk, mf: integer; disable: integer):integer; external;

  [DllImport(dwldll, EntryPoint = 'wlIsKeyDisabled')]
  function  wlIsKeyDisabled(window: hwnd; vk, mf: integer):integer; external;

  [DllImport(dwldll, EntryPoint = 'wlSetKeySendMessage')]
  procedure wlSetKeySendMessage(window: hwnd; KeyDownMessageID: integer; KeyUpMessageID: integer); external;

  [DllImport(dwldll, EntryPoint = 'wlSetKeyPostMessage')]
  procedure wlSetKeyPostMessage(window: hwnd; KeyDownMessageID: integer; KeyUpMessageID: integer); external;

  [DllImport(dwldll, EntryPoint = 'wlGetDisabledKey')]
  function  wlGetDisabledKey(index: integer; var window: hwnd; var vk,mf, vkout, mfout: integer): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlInstallDwl')]
  function  wlInstallDwl(Flags: integer):integer; external;

  [DllImport(dwldll, EntryPoint = 'wlUninstallDwl')]
  function  wlUninstallDwl(Flags: integer):integer; external;

  [DllImport(dwldll, EntryPoint = 'wlIsDwlInstalled')]
  function  wlIsDwlInstalled:integer; external;

  [DllImport(dwldll, EntryPoint = 'wlIsNTSystem')]
  function  wlIsNTSystem: integer; external;
  
  [DllImport(dwldll, EntryPoint = 'wlIs64BitWindows')]
  function  wlIs64BitWindows: integer; external;

  [DllImport(dwldll, EntryPoint = 'wlNeedDwlInstall')]
  function  wlNeedDwlInstall: integer; external;

  [DllImport(dwldll, EntryPoint = 'wlExitWindows')]
  function  wlExitWindows(Flags: integer): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlWinVersion')]
  function  wlWinVersion: integer; external;

  [DllImport(dwldll, EntryPoint = 'wlVersion')]
  function  wlVersion(RequestedVersion: integer): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlGetKeyState')]
  function  wlGetKeyState(vk: Integer): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlSetKeyState')]
  procedure wlSetKeyState(vk: Integer; TurnOn: integer); external;

  [DllImport(dwldll, EntryPoint = 'wlRestoreAll')]
  procedure wlRestoreAll(); external;

  [DllImport(dwldll, EntryPoint = 'wlEnableAutologin')]
  function wlEnableAutologin(defUser: string; pass: string; enable: integer; domain: string): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlWriteReg')]
  function wlWriteReg(Key: HKey; SubKey, Item: string; Value: string): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlMapScancode')]
  function  wlMapScancode(InputCode: integer; OutputCode: integer): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlDisableDesktopIcon')]
  procedure wlDisableDesktopIcon(index: integer); external;

  [DllImport(dwldll, EntryPoint = 'wlDesktopIconCount')]
  function  wlDesktopIconCount: integer; external;

  [DllImport(dwldll, EntryPoint = 'wlRestoreDesktopIcons')]
  procedure wlRestoreDesktopIcons(); external;

  [DllImport(dwldll, EntryPoint = 'wlExit')]
  procedure wlExit(); external;

  [DllImport(dwldll, EntryPoint = 'wlIsAdmin')]
  function  wlIsAdmin: boolean; external;

  [DllImport(dwldll, EntryPoint = 'wlIsKeyReplaced')]
  function  wlIsKeyReplaced(window: hwnd; vk: integer; mf: integer):integer; external;

  [DllImport(dwldll, EntryPoint = 'wlReplaceKey')]
  function wlReplaceKey(Window: hwnd; vk: integer; mf: integer; vkout: integer; mfout: integer): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlGetDisabledMessage')]
  function wlGetDisabledMessage(i: integer; var window: hwnd; var msgId: integer): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlIsMessageDisabled')]
  function wlIsMessageDisabled(window: hwnd; msgId: integer): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlDisableMessage')]
  function wlDisableMessage(window: hwnd; msgId: integer; disable: integer): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlDisableMouseArea')]
  function  wlDisableMouseArea(window: hwnd; MouseButton: integer; mf: integer; x,y,h,w,id: integer; disable: integer): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlGetItemHandle')]
  function  wlGetItemHandle (Item: integer): hwnd; external;

  [DllImport(dwldll, EntryPoint = 'wlSetStartMenu')]
  function  wlSetStartMenu (window: hwnd): integer; external;

  [DllImport(dwldll, EntryPoint = 'wlStrToVk')]
  procedure _wlStrToVk(keyStr: string; window: StringBuilder; maxCount: integer; var vk, mf: integer); external;

  procedure wlStrToVk(keyStr: string; var window: string; var vk, mf: integer);
  var
     K: StringBuilder;
  begin
    K := StringBuilder.Create(255);
    _wlStrToVk(keyStr, K, 255, vk, mf);
    KeyStr := K.ToString;
    K.Free;
  end;

  [DllImport(dwldll, EntryPoint = 'wlVkToStr')]
  procedure _wlVkToStr(window: string; VK, MF: integer; KeyStr: StringBuilder; MaxCount: integer); external;

  procedure wlVkToStr(window: string; VK, MF: integer; var KeyStr: string);
  var
     K: StringBuilder;
  begin
    K := StringBuilder.Create(255);
    _wlVkToStr(window,vk,mf,K, 255);
    KeyStr := K.ToString;
    K.Free;
  end;

  [DllImport(dwldll, EntryPoint = 'wlSendKeyDown')]
  procedure wlSendKeyDown(vk: Word; mf: integer ); external;

  [DllImport(dwldll, EntryPoint = 'wlSendKeyUp')]
  procedure wlSendKeyUp(vk: Word; mf: integer ); external;

  type
    TWndCallback = class(NativeWindow)
     OnKeyEvent: TdwlKeyCallbackMethod;
     constructor create(Callback: TdwlKeyCallbackMethod);
     procedure CallCallback(down: integer; m: Message);
     procedure WndProc(var m:  Message); override;
    end;

    constructor TWndCallback.create(Callback: TdwlKeyCallbackMethod);
    begin
      inherited create;
      CreateHandle(CreateParams.create);
      OnKeyEvent := Callback;
    end;

    procedure TWndCallback.CallCallback(down: integer; m: Message);
    var
      Wnd,Key,Shift: integer;
    begin
      Wnd   := m.WParam.ToInt32();
      Key   := LoWord(m.LParam.ToInt32());
      Shift := HiWord(m.LParam.ToInt32());
      if assigned(OnKeyEvent) then
        OnKeyEvent(Wnd,down,Key,Shift);
    end;

   [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name='FullTrust')]
   procedure TWndCallback.WndProc(var m: Message);
   begin
     try
       case m.Msg of
          WM_DWLKEYDOWN: CallCallback(1,m);
          WM_DWLKEYUP  : CallCallback(0,m);
       end;
       inherited WndProc(m);
     except
      // Just ignore it for now...
     end;
   end;

var
  CallbackWnd : TWndCallback = nil;

procedure wlSetObjKeyCallback(Callback: TdwlKeyCallbackMethod;Flags: integer);
var
 KeyDown : integer;
 KeyUP   : integer;
begin
   if not assigned(Callback) then
   begin
     if CallbackWnd <> nil then
       CallbackWnd.Free;
   end
   else
   begin
     if CallbackWnd = nil then
       CallbackWnd := TWndCallback.create(Callback);
     KeyDown := 0;
     KeyUp   := 0;
     if (Flags and  kDownEvents  > 0) then  KeyDown := WM_DWLKEYDOWN;
     if (Flags and  kUpEvents  > 0) then    KeyUp := WM_DWLKEYUP;
     wlSetKeyPostMessage(CallbackWnd.Handle.ToInt32,KeyDown,KeyUp);
   end;
end;

{$ELSE}
//----------------------------------------------------------------------------
// Begin Delphi 5,6,7, 2005,6,7  Win32 source code
//----------------------------------------------------------------------------

uses
  sysutils,dialogs, registry;

const
  GINAREGSAVE  = '\Software\Kassl\dWinlock\Gina';

type
{$IFDEF UNICODE}
  wlAnsiChar  = AnsiChar;
  wlPAnsiChar = PAnsiChar;
{$ELSE}
  wlAnsiChar  = Char;
  wlPAnsiChar = PChar;
{$ENDIF}

var
  HookLib   : integer = 0;
  DwlDllPath: string = '';

  pDisableItem       : procedure(Key:integer; disable: integer) stdcall = nil;
  pIsItemDisabled    : function (Item:integer): integer stdcall = nil;
  pVersion           : function (RequestedVersion: integer): integer stdcall = nil;
  pDisableKey        : function (window: hwnd; vk, Modifiers: integer; disable: integer): integer; stdcall = nil;
  pIsKeyDisabled     : function (window: hwnd; vk: integer; shift: integer): integer; stdcall = nil;
  pSetKeySendMessage : procedure(WindowHandle: hwnd; KeyDownMessageID: integer; KeyUpMessageID: integer); stdcall = nil;
  pSetKeyPostMessage : procedure(WindowHandle: hwnd; KeyDownMessageID: integer; KeyUpMessageID: integer); stdcall = nil;
  pGetDisabledKey    : function (i: integer; var window: hwnd; var vk,shift, vkout,shiftout: integer): integer; stdcall;
  pSetKeyCallback    : procedure(CallbackFunc: TdwlKeyCallbackFunc; UserData: integer; Flags: integer); stdcall;
  pInstallDwl        : function (Flags: integer): integer; stdcall = nil;
  pUninstallDwl      : function (Flags: integer): integer; stdcall = nil;
  pIsDwlInstalled    : function : integer; stdcall = nil;
  pNeedDwlInstall    : function : integer; stdcall;
  pIsNTSystem        : function : integer; stdcall;
  pIs64BitWindows    : function : integer; stdcall;
  pExitWindows       : function (Flags: integer): integer stdcall;
  pWinVersion        : function : integer; stdcall;
  pGetKeyState       : function  (Key: Integer): integer; stdcall;
  pSetKeyState       : procedure (Key: Integer; TurnOn: integer); stdcall;
  pRestoreAll        : procedure; stdcall;
  pExit              : procedure; stdcall;
  pIsAdmin           : function : integer; stdcall;
  pEnableAutologin   : function(DefUser: wlPAnsiChar; Pass: wlPAnsiChar; Enable: integer; Domain: wlPAnsiChar): integer; stdcall;
  pWriteReg          : function(Key: HKey; SubKey, Item: wlPAnsiChar; Value: wlPAnsiChar): integer; stdcall;
  pMapScancode       : function (InputCode: integer; OutputCode: integer): integer; stdcall; // returns old mapping
  pDisableDesktopIcon: procedure (index: integer);stdcall;
  pDesktopIconCount  : function : integer; stdcall;
  pRestoreDesktopIcons:procedure;stdcall;
  pGetDisabledMessage: function(i: integer; var window: hwnd; var MsgID: integer): integer; stdcall;
  pIsMessageDisabled : function(window: hwnd; MsgID: integer): integer; stdcall;
  pDisableMessage    : function(WindowHandle: hwnd; MsgID: integer; disable: integer): integer; stdcall; //returns 1 if Message is disabled
  pReplaceKey        : function(WindowHandle: hwnd; vk: integer; fsModifiers: integer; vk_out: integer; fsMod_out: integer): integer;stdcall;
  pIsKeyReplaced     : function (WindowHandle: hwnd; vk: integer; fsModifiers: integer):integer; stdcall;
  pSetShutdownCallback : procedure (QueryEndSessionCallback: TdwlQueryEndSessionCallbackFunc; UserData: integer);stdcall;
  pDisableMouseArea  : function (WindowHandle: hwnd; MouseButton: integer; shift: integer; x,y,h,w,id: integer; disable: integer): integer; stdcall;
  pGetItemHandle     : function (Item: integer): hwnd; stdcall;
  pSetStartMenu      : function (WindowHandle: hwnd): integer; stdcall;
  pStrToVk           : procedure (KeyStr: wlPAnsiChar; Window: wlPAnsiChar; MaxCount: integer; var VK, MF: integer); stdcall;
  pVkToStr           : procedure (Window: wlPAnsiChar; VK, MF: integer; KeyStr: wlPAnsiChar; MaxCount: integer); stdcall;
  pSendKeyDown       : procedure (Key: Word; Modifiers: integer ); stdcall;
  pSendKeyUp         : procedure (Key: Word; Modifiers: integer ); stdcall;


function  wlDwlDllPath: string;
begin
  result := DwlDllPath;
end;

// pascal implemention of windows get classname method
function GetClassName(Handle: hwnd): string;
var
  Buffer: array[0..255] of Char;
begin
  SetString(Result, Buffer, windows.GetClassName(Handle, Buffer, SizeOf(Buffer)))
end;


function GetProcAdr(hModule: HMODULE; lpProcName: LPCSTR): FARPROC;
begin
  result := GetProcAddress(hModule,lpProcName);
  if result = nil then
    raise exception.Create('error: method not found: '+lpProcName);
end;

procedure dwlLoad;
var
  Reg : TRegistry;
  OpenDlg  : TOpenDialog;
begin
  if HookLib > 0 then
    exit;

  DwlDllPath := '';
  HookLib := LoadLibrary(dwldll);
  if Hooklib = 0 then
  begin
    Reg := TRegistry.create;
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKeyReadOnly(GINAREGSAVE) then
      DwlDllPath := Reg.ReadString('Path');
    Reg.Free;
    if trim(DwlDllPath) <> '' then
      HookLib := LoadLibrary(pchar(DwlDllPath+dwldll));
    if Hooklib = 0 then
    begin
      ShowMessage('can not find '+dwldll+#10#13+'please select path to '+dwldll);
      OpenDlg := TOpenDialog.create(nil);
      OpenDlg.Filter := dwldll+'|'+dwldll;
      if OpenDlg.Execute then
      begin
        if lowercase(ExtractFileName(OpenDlg.FileName)) = dwldll then
        begin
          DwlDllPath :=  ExtractFilePath(OpenDlg.FileName);
          Reg := TRegistry.create;
          Reg.RootKey := HKEY_LOCAL_MACHINE;
          if Reg.OpenKey(GINAREGSAVE,true) then
            Reg.WriteString('Path',DwlDllPath);
          Reg.Free;
        end;
        HookLib := LoadLibrary(pchar(DwlDllPath+dwldll));
      end;
      OpenDlg.Free;
    end;
    if Hooklib = 0 then
      Hooklib := -1;    // user has canceled gina search
  end;

  if HookLib > 0 then
  begin
     try
       pVersion            := GetProcAdr(HookLib,'wlVersion');
       pVersion(DWL_VERSION);
       pDisableItem        := GetProcAdr(HookLib,'wlDisableItem');
       pIsItemDisabled     := GetProcAdr(HookLib,'wlIsItemDisabled');
       pDisableKey         := GetProcAdr(HookLib,'wlDisableKey');
       pIsKeyDisabled      := GetProcAdr(HookLib,'wlIsKeyDisabled');
       pSetKeySendMessage  := GetProcAdr(HookLib,'wlSetKeySendMessage');
       pSetKeyPostMessage  := GetProcAdr(HookLib,'wlSetKeyPostMessage');
       pInstallDwl         := GetProcAdr(HookLib,'wlInstallDwl');
       pUninstallDwl       := GetProcAdr(HookLib,'wlUninstallDwl');
       pIsDwlInstalled     := GetProcAdr(HookLib,'wlIsDwlInstalled');
       pNeedDwlInstall     := GetProcAdr(HookLib,'wlNeedDwlInstall');
       pIsNTSystem         := GetProcAdr(HookLib,'wlIsNTSystem');
       pIs64BitWindows     := GetProcAdr(HookLib,'wlIs64BitWindows');
       pExitWindows        := GetProcAdr(HookLib,'wlExitWindows');
       pWinVersion         := GetProcAdr(HookLib,'wlWinVersion');
       pGetKeyState        := GetProcAdr(HookLib,'wlGetKeyState');
       pSetKeyState        := GetProcAdr(HookLib,'wlSetKeyState');
       pSetKeyCallback     := GetProcAdr(HookLib,'wlSetKeyCallback');
       pRestoreAll         := GetProcAdr(HookLib,'wlRestoreAll');
       pGetDisabledKey     := GetProcAdr(HookLib,'wlGetDisabledKey');
       pIsAdmin            := GetProcAdr(HookLib,'wlIsAdmin');
       pEnableAutologin    := GetProcAdr(HookLib,'wlEnableAutologin');
       pWriteReg           := GetProcAdr(HookLib,'wlWriteReg');
       pMapScancode        := GetProcAdr(HookLib,'wlMapScancode');
       pDisableDesktopIcon := GetProcAdr(HookLib,'wlDisableDesktopIcon');
       pRestoreDesktopIcons:= GetProcAdr(HookLib,'wlRestoreDesktopIcons');
       pDesktopIconCount   := GetProcAdr(HookLib,'wlDesktopIconCount');
       pExit               := GetProcAdr(HookLib,'wlExit');
       pDisableMessage     := GetProcAdr(HookLib,'wlDisableMessage');
       pGetDisabledMessage := GetProcAdr(HookLib,'wlGetDisabledMessage');
       pIsMessageDisabled  := GetProcAdr(HookLib,'wlIsMessageDisabled');
       pReplaceKey         := GetProcAdr(HookLib,'wlReplaceKey');
       pIsKeyReplaced      := GetProcAdr(HookLib,'wlIsKeyReplaced');
       pSetShutdownCallback:= GetProcAdr(HookLib,'wlSetShutdownCallback');
       pDisableMouseArea   := GetProcAdr(HookLib,'wlDisableMouseArea');
       pGetItemHandle      := GetProcAdr(HookLib,'wlGetItemHandle');
       pSetStartMenu       := GetProcAdr(HookLib,'wlSetStartMenu');
       pStrToVk            := GetProcAdr(HookLib,'wlStrToVk');
       pVkToStr            := GetProcAdr(HookLib,'wlVkToStr');
       pSendKeyDown        := GetProcAdr(HookLib,'wlSendKeyDown');
       pSendKeyUp          := GetProcAdr(HookLib,'wlSendKeyUp');
     except
       on e: Exception do
       begin
         ShowMessage('can not load '+dwldll+ ' '+E.Message);
         halt(1);
       end;
     end;
  end
  else
  begin
    if GetLastError <> 0 then
       ShowMessage('can not load '+dwldll+#13#10+SysErrorMessage(GetLastError))
    else
       ShowMessage('can not load '+dwldll);
    halt(1);
  end;
end;

procedure wlDisableItem(Item: integer; disable: integer);
begin
  dwlLoad;
  pDisableItem(Item,disable);
end;

function wlDisableKey(window: hwnd; vk, mf: integer; disable: integer): integer;
begin
  dwlLoad;
  result:=pDisableKey(window,vk,mf,disable);
end;

function wlIsKeyDisabled(window: hwnd; vk, mf: integer):integer;
begin
  dwlLoad;
  result:=pIsKeyDisabled(window,vk,mf);
end;

function wlIsItemDisabled(item: integer): integer;
begin
  dwlLoad;
  result := pIsItemDisabled(item);
end;

procedure wlSetKeySendMessage(window: hwnd; KeyDownMessageID: integer; KeyUpMessageID: integer);
begin
  dwlLoad;
  pSetKeySendMessage(Window,KeyDownMessageID,KeyUpMessageID);
end;

procedure wlSetKeyPostMessage(window: hwnd; KeyDownMessageID: integer; KeyUpMessageID: integer);
begin
  dwlLoad;
  pSetKeyPostMessage(window,KeyDownMessageID,KeyUpMessageID);
end;

function wlInstallDwl(Flags: integer):integer;
begin
  dwlLoad;
  result:= pInstallDwl(Flags);
end;

function wlUninstallDwl(Flags: integer):integer;
begin
  dwlLoad;
  result:= pUninstallDwl(Flags);
end;

function wlIsDwlInstalled:integer;
begin
  dwlLoad;
  result:= pIsDwlInstalled;
end;

function  wlIsNTSystem: integer;
begin
  dwlLoad;
  result:= pIsNTSystem;
end;

function  wlIs64BitWindows: integer;
begin
  dwlLoad;
  result:= pIs64BitWindows;
end;

function  wlNeedDwlInstall: integer;
begin
  dwlLoad;
  result:= pNeedDwlInstall;
end;

function  wlVersion(RequestedVersion: integer): integer;
begin
  dwlLoad;
  result:= pVersion(0);
end;

function  wlExitWindows(Flags: integer): integer;
begin
  dwlLoad;
  result:= pExitWindows(Flags);
end;

function wlWinVersion: integer;
begin
  dwlLoad;
  result:= pWinVersion;
end;

function  wlGetKeyState(vk: Integer): integer;
begin
  dwlLoad;
  result:= pGetKeyState(vk);
end;

procedure wlSetKeyState(vk: Integer; TurnOn: integer);
begin
  dwlLoad;
  pSetKeyState(vk,TurnOn);
end;

procedure wlSetKeyCallback(Callback: TdwlKeyCallbackFunc; Flags: integer);
begin
  dwlLoad;
  pSetKeyCallback(Callback,0,Flags);
end;

procedure wlSetObjKeyCallback(Callback: TdwlKeyCallbackMethod; Flags: integer);
begin
  dwlLoad;
  with TMethod(Callback) do begin
    pSetKeyCallback(Code,integer(Data),Flags);
  end;
end;

function wlGetDisabledKey(index: integer; var window: hwnd; var vk,mf,vkout,mfout: integer): integer;

begin
 dwlLoad;
 result := pGetDisabledKey(index,window,vk,mf,vkout,mfout);
end;

procedure wlRestoreAll;
begin
  if HookLib > 0 then
   pRestoreAll;
end;

procedure wlExit;
begin
 if HookLib > 0 then
   pExit;
end;


function wlIsAdmin: boolean;
begin
 dwlLoad;
 result:= pIsAdmin = 1;
end;

function ToPChar(Str: string): wlPAnsiChar;
begin
  {$IFDEF UNICODE}
  result := wlPAnsiChar(AnsiString(Str));
  {$ELSE}
  result := wlPAnsiChar(Str);
  {$ENDIF}
end;


function wlEnableAutologin(DefUser: string; Pass: string; Enable: integer; Domain: string): integer;
begin
 dwlLoad;
 result := pEnableAutologin(ToPChar(DefUser),ToPChar(Pass),Enable,ToPChar(Domain))
end;


function  wlWriteReg(Key: HKey; SubKey, Item: string; Value: string): integer;
begin
 dwlLoad;
 result := pWriteReg(Key,ToPChar(SubKey),ToPChar(Item), ToPChar(Value));
end;


function wlMapScancode(InputCode: integer; OutputCode: integer): integer; // returns old mapping
begin
 dwlLoad;
 result:=pMapScancode(InputCode,OutputCode);
end;


procedure wlStrToVk(KeyStr: string; var Window: string; var VK, MF: integer);
var
  K : array[0..255] of wlAnsiChar;
begin
  dwlLoad;
  pStrToVk(ToPChar(KeyStr),@K[0],255,VK,MF);
  Window := string(K);
end;

procedure wlVkToStr(Window: string; VK, MF: integer; var KeyStr: string);
var
  K : array[0..255] of wlAnsiChar;
begin
  dwlLoad;
  pVkToStr(ToPChar(Window),VK,MF,@K[0],255);
  KeyStr := string(K);
end;

procedure wlDisableDesktopIcon(index: integer);
begin
 dwlLoad;
 pDisableDesktopIcon(index);
end;

function wlDesktopIconCount: integer;
begin
 dwlLoad;
 result := pDesktopIconCount;
end;

procedure wlRestoreDesktopIcons;
begin
 dwlLoad;
 pRestoreDesktopIcons;
end;

function wlGetDisabledMessage(i: integer; var window: hwnd; var MsgID: integer): integer;
begin
 dwlLoad;
 result := pGetDisabledMessage(i, window, MsgID);
end;

function wlIsMessageDisabled(window: hwnd; MsgID: integer): integer;
begin
 dwlLoad;
 result := pIsMessageDisabled(window, MsgID);
end;

function wlDisableMessage(window: hwnd; MsgID: integer; disable: integer): integer;
begin
 dwlLoad;
 result := pDisableMessage(window, MsgID, disable);
end;

function  wlDisableMouseArea(window: hwnd; MouseButton: integer; mf: integer; x,y,h,w,id: integer; disable: integer): integer;
begin
 dwlLoad;
 result := pDisableMouseArea(Window, MouseButton,mf,x,y,h,w,id,disable);
end;

function wlGetItemHandle(Item: integer): hwnd;
begin
 dwlLoad;
 result := pGetItemHandle(Item);
end;

function wlSetStartMenu(Window: hwnd): integer;
begin
 dwlLoad;
 result := pSetStartMenu(Window);
end;

procedure wlSetShutdownCallback(Callback: TdwlQueryEndSessionCallbackMethod);
begin
  dwlLoad;
  with TMethod(Callback) do begin
    pSetShutdownCallback(Code, integer(Data));
  end;
end;

function wlReplaceKey(window: hwnd; vk: integer; mf: integer; vkout: integer; mfout: integer): integer;
begin
  dwlLoad;
  result := pReplaceKey(window,vk,mf,vkout,mfout);
end;


function  wlIsKeyReplaced(window: hwnd; vk: integer; mf: integer):integer;
begin
  dwlLoad;
  result := pIsKeyReplaced(window,vk,mf);
end;

procedure wlSendKeyDown(VK: Word; MF: integer );
begin
  dwlLoad;
  pSendKeyDown(VK,MF);
end;

procedure wlSendKeyUp(VK: Word; MF: integer );
begin
  dwlLoad;
  pSendKeyUp(VK,MF);
end;

initialization

finalization
  if Hooklib > 0 then
    FreeLibrary(HookLib);
{$ENDIF}

end.



