capslock wide hook
The solution is creating a .dll with a Keyboard hook. I have one installed
on this pc which helps me avoid turning on CapsLock. Beware that I didn't
find a way to stop the CapsLock from being processed, so I had to send
another one ;-)
Here it goes (.Exe file loading the .dll:):
program CapsLock;
{$R *.RES}
uses
Windows;
var
HDLL: HMODULE;
HookAddr: pointer;
const
AHook: HHOOK = 0;
begin
HDLL:=LoadLibrary('keybhook.dll');
if HDLL > HINSTANCE_ERROR then begin
HookAddr:=GetProcAddress(HDLL, 'KeybHookCallback');
if Assigned(HookAddr) then
AHook:=SetWindowsHookEx(WH_KEYBOARD, HookAddr, HDLL, 0);
end;
Sleep(INFINITE);
if AHook > 0 then
UnhookWindowsHookEx(AHook);
if HDLL > HINSTANCE_ERROR then
FreeLibrary(HDLL);
end.
------------
(.dll code):
library KeybHook;
uses
Windows,
Messages,
UHook in 'UHook.pas';
exports
KeybHookCallback;
{$R *.RES}
begin
end.
------------
unit UHook;
interface
uses Windows, Messages, SysUtils;
function KeybHookCallback(Code, wParam, lParam: integer): integer; stdcall;
implementation
const
gFilterCapsLock: boolean = TRUE;
gInSettingCaps: boolean = false;
procedure SetCapsLockState(Value: boolean);
var
KeyState: TKeyboardState;
begin
GetKeyboardState(keyState);
if (Value xor boolean(keyState[VK_CAPITAL])) then begin
gInSettingCaps:=true;
keybd_event(VK_CAPITAL, $45, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(VK_CAPITAL, $45, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP,
0);
end;
end;
function KeybHookCallback(Code, wParam, lParam: integer): integer; stdcall;
var
AKeyFlag: Word;
begin
result:=0;
AKeyFlag:=(lParam shr 16);
if gFilterCapsLock
and (Code = HC_ACTION)
and ((wParam and $FFFF) = VK_CAPITAL) then begin
if ((AKeyFlag and $FF00) = $C100) then // True only when key is sent
from keybd_event
gInSettingCaps:=false
else begin
if not gInSettingCaps then begin
beep;
SetCapsLockState(false);
end;
end;
end
CallNextHookEx(0, Code, wParam, lParam);
end;
end.
--
Regards,
Bj�rge S�ther
bjorge@haha_itte.no