unit Main;

interface
uses
  Windows, Messages,Forms,ImgList, Controls, Menus, Buttons, StdCtrls, Classes,
  ExtCtrls, Dialogs, Graphics, ComCtrls, sysutils, inifiles,
  registry, Startmenu, DisableKeys, dwlcore,
  {$IFDEF CLR}
  System.Text,
  System.ComponentModel,
  {$ENDIF}
  CommCtrl, SHFolder, ShlObj, ShellApi;

const
  WM_HIDEWinlock = WM_USER + 10;

type
  TdWinlockForm = class(TForm)
    TreeView1: TTreeView;
    Splitter1: TSplitter;
    PanelClient: TPanel;
    Panel2: TPanel;
    LCaption: TLabel;
    Image1: TImage;
    PageControl1: TPageControl;
    TabDisable: TTabSheet;
    TabKeyMon: TTabSheet;
    TabAbout: TTabSheet;
    lVersion: TLabel;
    ListView1: TListView;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    TabOptions: TTabSheet;
    Password: TLabel;
    ePassword: TEdit;
    bHide: TButton;
    cHideOnStart: TCheckBox;
    bSaveConfig: TButton;
    bUninstall: TButton;
    Label5: TLabel;
    Label6: TLabel;
    eHotChar: TEdit;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    cAutoStart: TCheckBox;
    ImageList1: TImageList;
    StatusPanel: TPanel;
    lNumLock: TLabel;
    Label12: TLabel;
    LCapsLock: TLabel;
    LScrollLock: TLabel;
    LInfo: TLabel;
    TabWelcome: TTabSheet;
    Label10: TLabel;
    Memo1: TMemo;
    TabDisableDesktop: TTabSheet;
    Button2: TButton;
    TabReplace: TTabSheet;
    TabAccess: TTabSheet;
    cReplaceTabRet: TCheckBox;
    cReplaceYZ: TCheckBox;
    cDisableAHC: TCheckBox;
    cDisableAFK: TCheckBox;
    cDisableAKM: TCheckBox;
    cDisableASK: TCheckBox;
    cDisableATK: TCheckBox;
    TabMouse: TTabSheet;
    cDisableRButton: TCheckBox;
    cDisableLButton: TCheckBox;
    cDisableMButton: TCheckBox;
    Label4: TLabel;
    Label11: TLabel;
    cDisableDesktop: TCheckBox;
    cDisableStartButton: TCheckBox;
    cDisableTaskbar: TCheckBox;
    cDisableStartMenu: TCheckBox;
    cDisableTaskLinks: TCheckBox;
    cDisableSysTray: TCheckBox;
    cDisableShutdown: TCheckBox;
    cDisableALT_TAB: TCheckBox;
    cDisableALT_RETURN: TCheckBox;
    cDisableALT_ESC: TCheckBox;
    cDisableAppKey: TCheckBox;
    cDisableAlt_F4: TCheckBox;
    cDisableCTRL_ESC: TCheckBox;
    cDisableWinKeys: TCheckBox;
    bDisableKeys: TButton;
    cDisableCTRL_ALT_DEL: TCheckBox;
    cReplacePause: TCheckBox;
    Image2: TImage;
    TabStartmenu: TTabSheet;
    Panel1: TPanel;
    StartMenuListView: TListView;
    bApply: TButton;
    bAdd: TButton;
    bDelete: TButton;
    Panel3: TPanel;
    cReplaceStartmenu: TCheckBox;
    StartmenuImageList: TImageList;
    OpenDialog1: TOpenDialog;
    procedure cDisableTaskbarClick(Sender: TObject);
    procedure cDisableDesktopClick(Sender: TObject);
    procedure cDisableStartButtonClick(Sender: TObject);
    procedure cDisableSysTrayClick(Sender: TObject);
    procedure cDisableRButtonClick(Sender: TObject);
    procedure Exit1Click(Sender: TObject);
    procedure cDisableALT_TABClick(Sender: TObject);
    procedure cDisableALT_ESCClick(Sender: TObject);
    procedure cDisableCTRL_ESCClick(Sender: TObject);
    procedure cDisableWinKeysClick(Sender: TObject);
    procedure cDisableAppKeyClick(Sender: TObject);
    procedure bCancelClick(Sender: TObject);
    procedure cDisableCTRL_ALT_DELClick(Sender: TObject);
    procedure cDisableTaskLinksClick(Sender: TObject);
    procedure bUninstallClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure cDisableAlt_F4Click(Sender: TObject);
    procedure cDisableALT_RETURNClick(Sender: TObject);
    procedure TreeView1Changing(Sender: TObject; Node: TTreeNode;
      var AllowChange: Boolean);
    procedure WinLockKeyDown(ReceivingWnd: HWND; Key: Word;
      Shift: TShiftState);
    procedure bHideClick(Sender: TObject);
    procedure eHotCharExit(Sender: TObject);
    procedure bSaveConfigClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure eHotCharChange(Sender: TObject);
    procedure cAutoStartClick(Sender: TObject);
    procedure cDisableShutdownClick(Sender: TObject);
    procedure cDisableStartMenuClick(Sender: TObject);
    procedure cReplaceTabRetClick(Sender: TObject);
    procedure cReplaceStartmenuClick(Sender: TObject);
    procedure TreeView1CustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode;
      State: TCustomDrawState; var DefaultDraw: Boolean);
    procedure Button2Click(Sender: TObject);
    procedure cReplaceYZClick(Sender: TObject);
    procedure cDisableAHCClick(Sender: TObject);
    procedure cDisableAFKClick(Sender: TObject);
    procedure cDisableAKMClick(Sender: TObject);
    procedure cDisableASKClick(Sender: TObject);
    procedure cDisableATKClick(Sender: TObject);
    procedure cDisableLButtonClick(Sender: TObject);
    procedure cDisableMButtonClick(Sender: TObject);
    procedure cReplacePauseClick(Sender: TObject);
    procedure bDisableKeysClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure bAddClick(Sender: TObject);
    procedure bDeleteClick(Sender: TObject);
    procedure StartMenuListViewCustomDrawItem(Sender: TCustomListView;
      Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
    procedure bApplyClick(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure cHideOnStartClick(Sender: TObject);
    procedure Label3Click(Sender: TObject);
  private
    InputBoxActive: boolean;
    DataChanged : boolean;
    DataFolder: string;
    wasShown : boolean;
    wlHotChar: char;
    DisabledKeys : TStringlist;
    procedure ShowInfo;
    procedure ShowdWinlock;
    procedure LoadConfiguration;
    procedure SaveConfiguration;
    procedure SetKeyLockInfo;
    procedure DwlKeyEvent(Wnd: Hwnd; Down, VK, MF: integer);  {$IFNDEF CLR} stdcall; {$ENDIF}
    procedure CheckBoxDisableItem(CheckBox: TObject; Item: integer);
    procedure CheckBoxDisableKey(CheckBox: TObject; Key, Modi: integer);
    procedure UpdateStartMenu;
    procedure AddStartMenuList(FileName: string);
    procedure LoadStartmenu;
    procedure SaveStartmenu;
    procedure ShowDwlButton;
    procedure AddMenuItem(MenuStr: string; Icon: integer);
  public
   {$IFNDEF CLR}
    procedure WMSysCommand (var Message: TMessage); message WM_SYSCOMMAND;
    {$ENDIF}
    procedure WMHideWinlock(var Message: TMessage); message WM_HideWinlock;
    procedure WMEndSession (var Message: TWMEndSession); message WM_ENDSESSION;
  end;

var
  dWinlockForm: TdWinlockForm;

implementation
{$R *.dfm}


{$IFDEF CLR}
type
  pchar = string;

// returns Path to given folder type
// to use this function you have to include unit SHFolder
// see also constants CSIDL_... e.g. CSIDL_PROGRAMS
function GetFolderPath(Folder: integer): string;
var
  SB : StringBuilder;
begin
  SB := System.Text.StringBuilder.Create(255);
  SHGetFolderPath(0, Folder, 0, 0, SB);
  result := SB.ToString();
  Sb.Free;
end;
{$ELSE}

function GetFolderPath(Folder: integer): string;
var
  Path: array [0..MAX_PATH] of char;
begin
  SHGetFolderPath(0, Folder, 0, 0, @Path[0]);
  result := string(Path);
end;
{$ENDIF}


// Path to store application data
// to use this function you have to include unit SHFolder
function GetDataPath(AllUsers: boolean = false): string;
const
  Company = 'Kassl';
var
  DataPath : string;
  AppName  : string;
  P        : integer;
  V        : integer;
begin
  V := CSIDL_APPDATA;
  if AllUsers then
    V := CSIDL_COMMON_APPDATA;
  DataPath := GetFolderPath(V)+'\'+Company;
  if not DirectoryExists(DataPath) then
    CreateDir(DataPath);
  AppName := ExtractFileName(Application.ExeName);
  P := Pos('.',AppName);
  if P > 0 then
    Delete(AppName,P,Length(AppName));
  DataPath := DataPath+'\'+AppName+'\';
  if not DirectoryExists(DataPath) then
    CreateDir(DataPath);
  Result := DataPath;
end;



procedure TdWinlockForm.ShowInfo;
begin
  DataChanged := true;
  if wasShown then exit;
  wasShown := true;
  if wlisNtSystem = 0 then
     showMessage('You don''t have a Windows NT or XP system!'+#10#13+#10#13+
                 'dWinlock component is designed for Windows NT, XP and Vista.'+#10#13+
                 'But dWinlock works under Windows 95,98,ME.'+#10#13+
                 'The only restriction is, if you disable'+#10#13+
                 'Ctrl+Alt+Del, Alt+Tab or Alt+Esc'+#10#13+
                 'also following keys are disabled:'+#10#13+
                 'Ctrl+Alt+Del, Alt+Tab, Alt+Esc, Ctrl+Esc and Winkeys');
end;

function isAutostart : boolean;
var
  KEY : DWORD;
begin
  result := false;
  Key := HKEY_CURRENT_USER;
  with TRegistry.Create do
  begin
    RootKey := KEY;
    Access := KEY_READ;
    if OpenKey('\Software\Microsoft\Windows\CurrentVersion\Run',false) then
      result := ValueExists('dWinlock');
    Free;
  end;
end;

procedure SetAutoStart(Value: boolean);
var
  KEY : DWORD;
begin
  Key := HKEY_CURRENT_USER;
  if Value then
  begin
    wlWriteReg(KEY,
               'Software\Microsoft\Windows\CurrentVersion\Run',
               'dWinlock',
               Paramstr(0));
  end else
  begin
    wlWriteReg(KEY,
               'Software\Microsoft\Windows\CurrentVersion\Run',
               'dWinlock',
               '');
  end;
end;

function IsOk(Question: string; Caption : string= ''): boolean;
begin
  if Caption = '' then
    Caption := Application.Title;
  result :=  MessageBox(0,pchar(Question),pchar(Caption),MB_YESNO or MB_ICONQUESTION) = IdYes;
end;


procedure TdWinlockForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
 if Visible then
 begin
   if IsOk('Do you want to shut down dWinlock?','Shut down dWinlock') then
   begin
    if Datachanged then
    begin
      if IsOk('you have changed data,' +#10#13+
              'do you want save configuration before exiting program?',
              'Save data') then
      begin
        SaveConfiguration;
      end;
    end;
    wlExit;
   end
   else
     CanClose := false;
 end;
end;


procedure TdWinlockForm.AddMenuItem(MenuStr: string; Icon: integer);
var
  Item : TTreeNode;
begin
  Item := TreeView1.Items.Add(nil,MenuStr);
  Item.ImageIndex := Icon;
end;


procedure TdWinlockForm.FormCreate(Sender: TObject);
begin
  InputBoxActive := false;
  DataFolder := GetDataPath(false);
  DisabledKeys := TStringlist.Create;
  wasShown := true;
  LoadConfiguration;
  wasShown := false;
  AddMenuItem('Welcome',0);
  AddMenuItem('Disable Desktop',1);
  AddMenuItem('Own Start Menu',2);
  AddMenuItem('Disable Keys',3);
  AddMenuItem('Replace Keys',4);
  AddMenuItem('Key Monitor',5);
  AddMenuItem('Accessibility Keys',6);
  AddMenuItem('Disable Mouse',7);
  AddMenuItem('Options',8);
  AddMenuItem('About',9);

  Application.ShowMainForm := false;
  if cHideOnStart.Checked then
  begin
    wasShown := true;
    Visible := false;
  end
  else
    Visible := true;

  cAutostart.Checked :=  isAutostart;
  {$IFNDEF VER130}
  {$IFNDEF VER140}
  Panel2.ControlStyle := Panel2.ControlStyle - [csParentBackground];
  StatusPanel.ControlStyle := StatusPanel.ControlStyle - [csParentBackground];
  {$ENDIF}
  {$ENDIF}
  wlSetObjKeyCallback(dwlKeyEvent,kDownEvents or kUpEvents); // we want key down events but and key up events
  DataChanged := false;
end;

procedure TdWinlockForm.FormDestroy(Sender: TObject);
begin
   DisabledKeys.Free;
end;

procedure TdWinlockForm.ShowDwlButton;
begin
  if wlIsDwlInstalled = 1 then
    bUninstall.Caption := 'Uninstall dwl'
  else
    bUninstall.Caption := 'Install dwl';
end;


procedure TdWinlockForm.FormShow(Sender: TObject);
var
  i : integer;
begin
   for i := 0 to PageControl1.PageCount -1 do
     PageControl1.Pages[i].TabVisible := false;
   LVersion.Caption := format('dWinlock API version: %d.%d',[HIWORD(wlVersion),LOWORD(wlVersion)]);
   ShowDwlButton;

   if wlIsDwlInstalled = 1 then
     bUninstall.Caption := 'Uninstall dwl'
   else
     bUninstall.Caption := 'Install dwl';

   TreeView1.Items[0].Selected := true;
   SetKeyLockInfo;
   DataChanged := false;
end;

procedure TdWinlockForm.Exit1Click(Sender: TObject);
begin
  Close;
end;

procedure TdWinlockForm.cDisableALT_TABClick(Sender: TObject);
var
  Value : integer;
begin
  Value := 0;
  if TCheckBox(Sender).Checked then
    Value := 1;
  wlDisableKey(0,VK_TAB,MOD_ALT,Value);
  wlDisableKey(0,VK_TAB,MOD_ALT or MOD_SHIFT,Value);
  wlDisableKey(0,VK_TAB,MOD_ALT or MOD_WIN,Value);
  ShowInfo;
end;

procedure TdWinlockForm.CheckBoxDisableKey(CheckBox: TObject; Key, Modi : integer);
begin
  DataChanged := true;
   if TCheckBox(CheckBox).Checked then
     wlDisableKey(0,Key,Modi,1)
  else
     wlDisableKey(0,Key,Modi,0)
end;



procedure TdWinlockForm.CheckBoxDisableItem(CheckBox: TObject; Item : integer);
begin
   DataChanged := true;
   if TCheckBox(CheckBox).Checked then
     wlDisableItem(Item,1)
  else
     wlDisableItem(item,0);
end;


procedure TdWinlockForm.cDisableAHCClick(Sender: TObject);
begin
  CheckBoxDisableItem(sender,wlAccHighContrast);
end;

procedure TdWinlockForm.cDisableALT_ESCClick(Sender: TObject);
begin
  CheckBoxDisableKey(sender,VK_ESCAPE,MOD_ALT);
  ShowInfo;
end;

procedure TdWinlockForm.cDisableCTRL_ESCClick(Sender: TObject);
begin
  CheckBoxDisableKey(sender,VK_ESCAPE,MOD_CONTROL);
end;

procedure TdWinlockForm.cDisableWinKeysClick(Sender: TObject);
begin
  CheckBoxDisableKey(sender,0,MOD_WIN);
end;

procedure TdWinlockForm.cDisableAFKClick(Sender: TObject);
begin
  CheckBoxDisableItem(sender,wlAccFilterKeys);
end;


procedure TdWinlockForm.cDisableAKMClick(Sender: TObject);
begin
  CheckBoxDisableItem(sender,wlAccMouseKey);
end;

procedure TdWinlockForm.cDisableASKClick(Sender: TObject);
begin
  CheckBoxDisableItem(sender,wlAccStickyKeys);
end;

procedure TdWinlockForm.cDisableATKClick(Sender: TObject);
begin
 CheckBoxDisableItem(sender,wlAccToggleKeys);
end;

procedure TdWinlockForm.cDisableRButtonClick(Sender: TObject);
begin
  CheckBoxDisableKey(sender,VK_RBUTTON,0);
end;

procedure TdWinlockForm.cDisableLButtonClick(Sender: TObject);
begin
  CheckBoxDisableKey(sender,VK_LBUTTON,0);
end;

procedure TdWinlockForm.cDisableMButtonClick(Sender: TObject);
begin
  CheckBoxDisableKey(sender,VK_MBUTTON,0);
end;


procedure TdWinlockForm.cDisableAppKeyClick(Sender: TObject);
begin
  CheckBoxDisableKey(sender,VK_APPS,0);
end;

procedure TdWinlockForm.cDisableAlt_F4Click(Sender: TObject);
begin
  CheckBoxDisableKey(sender,VK_F4,MOD_ALT);
end;

procedure TdWinlockForm.cDisableALT_RETURNClick(Sender: TObject);
begin
  CheckBoxDisableKey(sender,VK_RETURN,MOD_ALT);
end;

procedure TdWinlockForm.cDisableCTRL_ALT_DELClick(Sender: TObject);
begin
  CheckBoxDisableKey(sender,VK_DELETE,MOD_CONTROL or MOD_ALT);
  ShowDwlButton;
  if wlIsDwlInstalled = 0 then
  begin
     if cDisableCTRL_ALT_DEL.Checked then
       cDisableCTRL_ALT_DEL.Checked := false;
  end;
  ShowInfo;
end;

procedure TdWinlockForm.cDisableTaskbarClick(Sender: TObject);
begin
  CheckBoxDisableItem(Sender,wlTASKBAR);
end;

procedure TdWinlockForm.cDisableDesktopClick(Sender: TObject);
begin
  CheckBoxDisableItem(Sender,wlDesktop);
end;

procedure TdWinlockForm.cDisableStartButtonClick(Sender: TObject);
begin
 CheckBoxDisableItem(Sender,wlStartbutton);
end;

procedure TdWinlockForm.cDisableSysTrayClick(Sender: TObject);
begin
  CheckBoxDisableItem(Sender,wlTaskTray);
end;

procedure TdWinlockForm.cDisableTaskLinksClick(Sender: TObject);
begin
 CheckBoxDisableItem(Sender,wlTaskLinks);
end;



procedure TdWinlockForm.bApplyClick(Sender: TObject);
begin
  UpdateStartMenu;
end;

procedure TdWinlockForm.bCancelClick(Sender: TObject);
begin
  close;
end;

procedure TdWinlockForm.bUninstallClick(Sender: TObject);
begin
  if wlIsDwlInstalled = 1 then
    wlUninstallDwl(0)
  else
    wlInstallDwl(0);
  ShowDwlButton;
end;


procedure TdWinlockForm.TreeView1Changing(Sender: TObject; Node: TTreeNode;
  var AllowChange: Boolean);
var
  B : TBitmap;
begin

  B := TBitmap.Create;
  ImageList1.GetBitmap(Node.AbsoluteIndex,B);  // set image in info line
  Image1.Picture.Bitmap  := B;
  B.Free;

  PageControl1.ActivePageIndex := Node.AbsoluteIndex;
  LCaption.Caption := Node.Text;
  LInfo.Caption := '';
  case Node.AbsoluteIndex of
    0: LInfo.Caption := 'to dWinlock, the easy to use API to lock Windows';
    1: LInfo.Caption := 'here you can disable several desktop items';
    2: LInfo.Caption := 'with dWinlock you can create your own start menu';
    3: LInfo.Caption := 'here you can disable every key you want ';
    4: LInfo.Caption := 'with dWinlock you can swap keys';
    5: LInfo.Caption := 'with dWinlock you can trap every key you want';
    6: LInfo.Caption := 'with dWinlock you can disable accessibility keystrokes';
    7: LInfo.Caption := 'with dWinlock you can disable mouse buttons';
    8: LInfo.Caption := 'if you want to use this program to protect your system'; // options
    9: LInfo.Caption := '© 2002-2008 Kassl GmbH'; // About
  end;
end;


procedure TreeViewCustomSelect(Item: TTreeNode);
var
  LV     : TTreeView;
  Pt, P1, P2 : TPoint;
begin

  LV := TTreeView(Item.Owner.Owner);
  if not assigned(LV.Canvas) then
    exit;
  if Item.Selected then
  begin
    LV.Canvas.Brush.Color := rgb(199,213,239);
    LV.Canvas.Font.Color  := LV.Font.Color;
    LV.Canvas.Pen.Color   := clInactiveCaption;
  end
  else
  begin
    LV.Canvas.Brush.Color := LV.Color;
    LV.Canvas.Font.Color  := LV.Font.Color;
    LV.Canvas.Pen.Color   := LV.Canvas.Brush.Color;
  end;

  P1.X := Item.DisplayRect(false).Left;
  P1.Y := Item.DisplayRect(false).Top;
  P2.X := Item.DisplayRect(false).Right;
  P2.Y := Item.DisplayRect(false).Bottom;

  LV.Canvas.RoundRect(P1.X,P1.Y, P2.X,P2.Y,4,4);
  if assigned(LV.Images) then
  begin
    PT := P1;
    P1.X := Item.DisplayRect(false).Left;
    P1.Y := Item.DisplayRect(false).Top;
    LV.Images.Draw(LV.Canvas,P1.X,P1.Y, Item.ImageIndex,dsTransparent,itImage);
    P1.x := Item.DisplayRect(true).Left+4;
    P1.y := Item.DisplayRect(true).Top+10;
  end
  else
  begin
    P1.x := Item.DisplayRect(true).Left+4;
    P1.y := Item.DisplayRect(true).Top+1;
  end;

  LV.Canvas.TextOut(P1.x,P1.y,Item.Text);
end;



procedure TdWinlockForm.TreeView1CustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
  TreeViewCustomSelect(Node);
  DefaultDraw := false;
end;

procedure TdWinlockForm.ShowdWinlock;
var
  Pass : string;
begin
  if trim(ePassword.Text) <> '' then
  begin
    if InputBoxActive then
      exit;
    InputBoxActive := true;
    Pass :=  InputBox('dWinlock', 'Password', '');
    InputBoxActive := false;
    if Pass = ePassword.Text then
    begin
      Application.Restore;
      visible := true;
    end;
  end
  else
  begin
    Application.Restore;
    visible := true;
  end;
  Application.BringToFront;
end;




// shows pressed key in key monitor
procedure TdWinlockForm.WinLockKeyDown(ReceivingWnd: HWND; Key: Word;
  Shift: TShiftState);
var
  Item : TListItem;
  S    : string;
begin
  if (ssAlt in shift) and (ssCtrl in shift) and (Key = ord(wlHotChar)) then
  begin
    Application.BringToFront;
    if visible then
      bHideClick(self)
    else
      ShowdWinlock;
  end;

  if Listview1.Items.Count >= 15 then
    Listview1.Items.Clear;
  Item := Listview1.Items.Add;
  Item.Caption := 'down';
  Item.SubItems.Add(IntToStr(key));
  Item.SubItems.Add(ShortCutToText(ShortCut(Key,Shift)));
  Item.SubItems.Add(IntToStr(ReceivingWnd));
  S := GetClassName(ReceivingWnd);
  Item.SubItems.Add(S);
end;

procedure TdWinlockForm.WMEndSession(var Message: TWMEndSession);
begin
  if Message.EndSession = TRUE then
  begin
    Application.Terminate;
  end;
  inherited;
end;

procedure TdWinlockForm.WMHideWinlock(var Message: TMessage);
begin
  bHideClick(self);
end;

{$IFNDEF CLR}
procedure TdWinlockForm.WMSysCommand(var Message: TMessage);
begin
  if(Message.Msg = WM_SYSCOMMAND) and (Message.wParam = SC_MINIMIZE) then
    PostMessage(Handle,WM_HideWinlock,0,0)
  else
   inherited;
end;
{$ENDIF}

procedure TdWinlockForm.SetKeyLockInfo;
begin
  LNumLock.Font.Color := clSilver;
  LScrollLock.Font.Color := clSilver;
  LCapsLock.Font.Color := clSilver;
  if wlGetKeyState(VK_NUMLOCK) = 1then
    LNumLock.Font.Color := clBtnText;
  if wlGetKeyState(VK_SCROLL) = 1 then
    LScrollLock.Font.Color := clBtnText;
  if wlGetKeyState(VK_CAPITAL) = 1 then
    LCapsLock.Font.Color := clBtnText;
end;

procedure TdWinlockForm.bDisableKeysClick(Sender: TObject);
begin
  if DisableKeyDlg(DisabledKeys) then
     DataChanged := true;
end;

procedure TdWinlockForm.bHideClick(Sender: TObject);
begin
  if InputBoxActive then exit;
  InputBoxActive := true;
  ShowMessage('to show dWinlock press hotkey: CTRL+ALT+'+wlHotChar);
{  MessageBox(handle,pchar('to show dWinlock press hotkey: CTRL+ALT+'+wlHotChar),
             'hiding dWinlock',MB_OK or MB_ICONINFORMATION);}
  visible := false;
  InputBoxActive := false;
end;

procedure TdWinlockForm.UpdateStartMenu;
begin
  if DwlStartmenu <> nil then
  begin
     DwlStartmenu.ImageList1.Assign(StartmenuImageList);
     DwlStartmenu.ListView1.Items.Assign(StartMenuListView.Items);
     DwlStartmenu.ListView1.Invalidate;
     (*
     if DwlStartmenu.ListView1.Items.Count > 0 then
     begin
       DwlStartmenu.ListView1.ItemIndex := 0;
       DwlStartmenu.ListView1.SetFocus;
     end
     *)
  end;
end;

procedure TdWinlockForm.eHotCharExit(Sender: TObject);
begin
   if eHotChar.Text = '' then
     eHotChar.Text := wlHotChar;
end;

procedure TdWinlockForm.eHotCharChange(Sender: TObject);
begin
  if eHotChar.Text <> '' then
    wlHotChar := eHotChar.Text[1]
end;


procedure TdWinlockForm.LoadStartmenu;
var
  ItemList : TStringList;
  i : integer;
  FileName: string;
  StartMenuFile : string;
begin
  StartMenuFile := DataFolder + 'dwlSM.ini';
  if FileExists(StartMenuFile) then
  begin
    StartMenuListView.Items.Clear;
    ItemList := TStringList.Create;
    ItemList.LoadFromFile(StartMenuFile);
    for i := 0 to ItemList.Count - 1 do
    begin
       FileName := ItemList[i];
       AddStartMenuList(FileName);
    end;
    UpdateStartMenu;
    Itemlist.Free;
  end;
end;

procedure TdWinlockForm.SaveStartmenu;
var
  i : integer;
  ItemList : TStringList;
  Item : TListItem;
  StartMenuFile : string;
begin
  ItemList := TStringList.create;
  for i := 0 to StartMenuListView.Items.Count - 1 do
  begin
    Item := StartMenuListView.Items[i];
    if Item.SubItems.Count > 0 then
     ItemList.Add(Item.SubItems[0]);  // save file name
  end;
  StartMenuFile := DataFolder + 'dwlSM.ini';
  Itemlist.SaveToFile(StartMenuFile);
  Itemlist.Free;
end;


function CallBrowser(Handle: Hwnd; URL : string): boolean;
begin
 // ShellExecute(Handle, 'open', URL, nil, nil, SW_SHOWNORMAL);
  result := ShellExecute(Handle, 'open', pchar(URL), '', '', SW_SHOWNORMAL) <> 0;
end;

procedure TdWinlockForm.Label3Click(Sender: TObject);
begin
 CallBrowser(Handle,'http://www.kassl.de');
end;


procedure TdWinlockForm.LoadConfiguration;
var
  i : integer;
  VK, MF : integer;
  W : string;
begin
  with TIniFile.Create( DataFolder + 'dwl.ini')do
  begin
    cDisableCtrl_Alt_Del.Checked:= ReadBool('settings','noCtrlAltDel',false);
    cDisableAlt_Tab.Checked     := ReadBool('settings','noAltTab',false);
    cDisableAlt_Esc.Checked     := ReadBool('settings','noAltEsc',false);
    cDisableAlt_F4.Checked      := ReadBool('settings','noAltF4',false);
    cDisableCtrl_Esc.Checked    := ReadBool('settings','noCtrlEsc',false);
    cDisableWinkeys.Checked     := ReadBool('settings','noWinkeys',false);
    cDisableAppkey.Checked      := ReadBool('settings','noAppkey',false);
    cDisableRButton.Checked     := ReadBool('settings','noRButton',false);
    cDisableLButton.Checked     := ReadBool('settings','noLButton',false);
    cDisableMButton.Checked     := ReadBool('settings','noMButton',false);
    cDisableTaskbar.Checked     := ReadBool('settings','noTaskbar',false);
    cDisableTaskLinks.Checked   := ReadBool('settings','noTaskLinks',false);
    cDisableSysTray.Checked     := ReadBool('settings','noTaskTray',false);
    cDisableStartButton.Checked := ReadBool('settings','noStartbutton',false);
    cDisableAlt_Return.Checked  := ReadBool('settings','noAltReturn',false);
    cDisableDesktop.Checked     := ReadBool('settings','noDesktop',false);
    cDisableShutdown.Checked    := ReadBool('settings','noShutDown',false);
    cReplaceStartmenu.Checked   := ReadBool('settings','dStartmenu',false);
    cReplaceTabRet.Checked      := ReadBool('settings','replacetabret',false);
    cReplaceYZ.Checked          := ReadBool('settings','replaceyz',false);
    cReplacePause.Checked       := ReadBool('settings','replacepause',false);
    cHideOnStart.Checked        := ReadBool('settings','Hideonstart',false);
    ePassWord.Text              := ReadString('settings','Password','');
    wlHotChar                   := ReadString('settings','Hotchar','W')[1];
    cDisableAHC.Checked         := ReadBool('settings','AccHC',false);
    cDisableATK.Checked         := ReadBool('settings','AccTK',false);
    cDisableAFK.Checked         := ReadBool('settings','AccFK',false);
    cDisableAKM.Checked         := ReadBool('settings','AccKM',false);
    cDisableASK.Checked         := ReadBool('settings','AccSK',false);
    eHotChar.Text := wlHotChar;
  end;

  if FileExists(DataFolder+ 'dwldkeys.ini') then
  begin
     DisabledKeys.LoadFromFile(DataFolder+ 'dwldkeys.ini');
     for i:= 0 to DisabledKeys.Count-1 do
     begin
       wlStrToVk(DisabledKeys[i],w,VK,MF);
       wlDisableKey(0,VK,MF,1);
     end;
  end;
  LoadStartmenu;
  DataChanged := false;
end;

procedure TdWinlockForm.SaveConfiguration;
begin
  with TIniFile.Create(DataFolder+ 'dwl.ini')do
  begin
    WriteBool('settings','noCtrlAltDel', cDisableCtrl_Alt_Del.Checked);
    WriteBool('settings','noAltTab',     cDisableAlt_Tab.Checked     );
    WriteBool('settings','noAltEsc',     cDisableAlt_Esc.Checked     );
    WriteBool('settings','noAltF4',      cDisableAlt_F4.Checked      );
    WriteBool('settings','noCtrlEsc',    cDisableCtrl_Esc.Checked    );
    WriteBool('settings','noWinkeys',    cDisableWinkeys.Checked     );
    WriteBool('settings','noAppkey',     cDisableAppkey.Checked      );
    WriteBool('settings','noRButton',    cDisableRButton.Checked       );
    WriteBool('settings','noLButton',    cDisableLButton.Checked     );
    WriteBool('settings','noMButton',    cDisableMButton.Checked     );
    WriteBool('settings','noTaskbar',    cDisableTaskbar.Checked     );
    WriteBool('settings','noTaskLinks',  cDisableTaskLinks.Checked   );
    WriteBool('settings','noTaskTray',   cDisableSysTray.Checked     );
    WriteBool('settings','noStartbutton',cDisableStartButton.Checked );
    WriteBool('settings','noAltReturn',  cDisableAlt_Return.Checked  );
    WriteBool('settings','noDesktop',    cDisableDesktop.Checked     );
    WriteBool('settings','noShutdown',   cDisableShutdown.Checked    );
    WriteBool('settings','dStartmenu',   cReplaceStartmenu.Checked    );
    WriteBool('settings','replacetabret',cReplaceTabRet.Checked    );
    WriteBool('settings','replaceyz',    cReplaceYZ.Checked    );
    WriteBool('settings','replacepause', cReplacePause.Checked    );
    WriteBool('settings','Hideonstart',  cHideOnStart.Checked);
    WriteBool('settings','AccHC',        cDisableAHC.Checked);
    WriteBool('settings','AccTK',        cDisableATK.Checked);
    WriteBool('settings','AccFK',        cDisableAFK.Checked);
    WriteBool('settings','AccKM',        cDisableAKM.Checked);
    WriteBool('settings','AccSK',        cDisableASK.Checked);
    WriteString('settings','Password',   ePassWord.Text);
    WriteString('settings','Hotchar',    wlHotChar);
  end;
  DisabledKeys.SaveToFile(DataFolder+ 'dwldkeys.ini');
  SaveStartmenu;
  DataChanged := false;
end;

procedure TdWinlockForm.bSaveConfigClick(Sender: TObject);
begin
  SaveConfiguration;
  ShowMessage('Configuration saved');
end;

{$IFNDEF CIL}
  function HtmlHelp(hwndCaller: HWND; pszFile: pchar; uComannd: integer;
                  dwData: dword) :HWND; stdcall; external 'hhctrl.ocx' name 'HtmlHelpA';
{$ENDIF}  

procedure TdWinlockForm.Button2Click(Sender: TObject);
var
  Helpfile : string;
begin
  Helpfile := ExtractFilePath(Application.ExeName)+'dwlreference.chm';
  if HTMLHelp(Handle,pchar(Helpfile),1,0) = 0 then
    ShowMessage('can not open '+Helpfile);
end;

procedure TdWinlockForm.cAutoStartClick(Sender: TObject);
begin
  SetAutoStart(cAutoStart.Checked);
  DataChanged := true;
end;

procedure TdWinlockForm.cDisableShutdownClick(Sender: TObject);
begin
  CheckBoxDisableItem(Sender,wlShutdown);
end;

procedure TdWinlockForm.cDisableStartMenuClick(Sender: TObject);
begin
  CheckBoxDisableItem(Sender,wlSTARTMENU);
end;

procedure TdWinlockForm.cReplaceTabRetClick(Sender: TObject);
begin
  if cReplaceTabRet.Checked then begin
    wlReplaceKey(0,VK_TAB,0,VK_RETURN,0);
    wlReplaceKey(0,VK_RETURN,0,VK_TAB,0);
  end else begin
    wlReplaceKey(0,VK_TAB,0,0,0);
    wlReplaceKey(0,VK_RETURN,0,0,0);
  end;
end;

procedure TdWinlockForm.cReplaceYZClick(Sender: TObject);
begin
  if cReplaceYZ.Checked then begin
    wlReplaceKey(0,Ord('Y'),0,Ord('Z'),0);
    wlReplaceKey(0,Ord('Z'),0,Ord('Y'),0);
  end else begin
    wlReplaceKey(0,Ord('Y'),0,0,0);
    wlReplaceKey(0,Ord('Z'),0,0,0);
  end;
end;
procedure TdWinlockForm.cHideOnStartClick(Sender: TObject);
begin
  DataChanged := true;
end;

procedure TdWinlockForm.cReplacePauseClick(Sender: TObject);
begin
  if cReplacePause.Checked then begin
    wlReplaceKey(0,VK_PAUSE,0,VK_BACK,0);
  end else begin
    wlReplaceKey(0,VK_PAUSE,0,0,0);
  end;
end;



procedure TdWinlockForm.cReplaceStartmenuClick(Sender: TObject);
begin
  if cReplaceStartmenu.Checked then
  begin
    wlSetStartMenu(CreateStartmenu);
    UpdateStartmenu;
    cDisableStartMenu.Checked := true;
  end
  else
  begin
    wlSetStartMenu(0);
    cDisableStartMenu.Checked := false;
  end;
end;


procedure ShortCutToVK(ShortCut: TShortCut; var VK,MF: integer);
begin
  VK := ShortCut and not (scShift + scCtrl + scAlt);
  MF := 0;
  if ShortCut and scShift <> 0 then MF := MF or MOD_SHIFT;
  if ShortCut and scCtrl  <> 0 then MF := MF or MOD_CONTROL;
  if ShortCut and scAlt   <> 0 then MF := MF or MOD_ALT;
end;

(*
function VkToShortCut(Key: Word; MF: integer): TShortCut;
begin
  Result := 0;
  if WordRec(Key).Hi <> 0 then Exit;
  Result := Key;
  if MOD_SHIFT and MF <> 0   then Inc(Result, scShift);
  if MOD_CONTROL and MF <> 0 then Inc(Result, scCtrl);
  if MOD_ALT and MF <> 0 then     Inc(Result, scAlt);
end;
*)

procedure TdWinlockForm.DwlKeyEvent(Wnd: Hwnd; Down, VK, MF: integer);
var
  Item : TListItem;
  S: String;
  D : TDlgDisableKeys;
begin
  if down = 0  then  // if Key up
  begin
     if (VK = VK_SHIFT)   or
        (VK = VK_CAPITAL) or
        (VK = VK_NUMLOCK) or
        (VK = VK_SCROLL) then
       SetKeyLockInfo;
  end
  else
  begin
    // show and hide dWinlock
    if ( MF = MOD_ALT or MOD_CONTROL ) and (VK = ord(wlHotChar)) then
    begin
      Application.BringToFront;
      if visible then
        bHideClick(self)
      else
        ShowdWinlock;
    end;

    // Open dWinlock
    if ( MF = MOD_SHIFT or MOD_ALT or MOD_CONTROL ) and (VK = ord('W')) then
    begin
      Application.BringToFront;
      if Visible = false then
        ShowdWinlock;
    end;

    if Listview1.Items.Count >= 15 then
      Listview1.Items.Clear;
    Item := Listview1.Items.Add;
    Item.Caption := 'down';
    Item.SubItems.Add(IntToStr(Vk));
    wlVkToStr('',VK,MF,S);
    Item.SubItems.Add(S);
    //  Item.SubItems.Add(ShortCutToText(VkToShortCut(Vk,MF)));
    Item.SubItems.Add(IntToStr(Wnd));
    S := GetClassName(Wnd);
    Item.SubItems.Add(S);

    D := GetDisableKeyDlg;
    if D <> nil then
      D.OnNewKey(VK,MF);
  end;
end;

procedure TdWinlockForm.AddStartMenuList(FileName: string);
var
  Item : TListItem;
  FInfo : TSHFILEINFO;
begin
  Item := StartMenuListView.Items.Add;
  Item.SubItems.Add(FileName);
  if SHGetFileInfo(pchar(FileName), 0, fInfo, SizeOf(fInfo), SHGFI_ICON or SHGFI_LARGEICON or SHGFI_DISPLAYNAME) <> 0 then
  begin
    Item.Caption := ChangeFileExt(FInfo.szDisplayName,'');
    Item.ImageIndex := ImageList_AddIcon(StartmenuImageList.Handle, FInfo.hIcon);
  end
  else
  begin
    Item.Caption := ChangeFileExt(ExtractFileName(FileName),'');
    Item.ImageIndex := 0;
  end;
end;

procedure TdWinlockForm.bAddClick(Sender: TObject);
begin
  if OpenDialog1.InitialDir = '' then
    OpenDialog1.InitialDir := GetFolderPath(CSIDL_PROGRAMS);
  if OpenDialog1.Execute then
  begin
    DataChanged := true;
    AddStartMenuList(OpenDialog1.FileName);
  end;
end;

procedure TdWinlockForm.bDeleteClick(Sender: TObject);
begin
  if StartMenuListView.ItemIndex >= 0 then
  begin
    DataChanged := true;
    StartMenuListView.Items.Delete(StartMenuListView.ItemIndex);
  end;
end;

procedure TdWinlockForm.StartMenuListViewCustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
var
  x,y    : integer;
  LV     : TListView;
  P1, P2 : TPoint;
begin
  LV := Sender as TListView;
  if Item.Selected then
  begin
    LV.Canvas.Brush.Color := rgb(199,213,239);
    LV.Canvas.Pen.Color   := clInactiveCaption;
  end
  else
  begin
    LV.Canvas.Brush.Color := clWhite;
    LV.Canvas.Pen.Color   := LV.Canvas.Brush.Color;
  end;

  P1.X := Item.DisplayRect(drBounds).Left;
  P1.Y := Item.DisplayRect(drBounds).Top;
  P2.X := Item.DisplayRect(drBounds).Right;
  P2.Y := Item.DisplayRect(drBounds).Bottom;

  LV.Canvas.RoundRect(P1.X,P1.Y, P2.X,P2.Y,4,4);

  P1.X := Item.DisplayRect(drIcon).Left;
  P1.Y := Item.DisplayRect(drIcon).Top;
  LV.SmallImages.Draw(LV.Canvas,P1.X,P1.Y, Item.ImageIndex,dsTransparent,itImage);

  x := Item.DisplayRect(drLabel).Left+4;
  y := Item.DisplayRect(drLabel).Top+10;
  LV.Canvas.TextOut(x,y,Item.Caption);

  DefaultDraw := false;
end;


end.


