unit mx_hookedit;
{ GetMsgProc }
function GetMsgProc(nCode: Integer; wParam, lParam: Integer): LResult;
stdcall;
{ process messages:
WM_KEYUP
VK_CONTROL
WM_KEYDOWN
VK_CONTROL
VK_BACK
VK_DELETE
VK_ENTER
WM_CHAR
}
const
VChar = $38;
var
VMsg : PMsg;
VMess : Cardinal;
VWndValid : Boolean;
VStartSel : Integer;
VEndSel : Integer;
VKeyState : TKeyBoardState;
VVirtKey : Integer;
VScanCode : Integer;
VCharCode :
array[0..3]
of Char;
VRetVal : Smallint;
VKBLayout : HKL;
S :
string;
begin
Result := 0;
//
if (nCode < 0)
then
Result := CallNextHookEx(FHook_GetMsg, nCode, wParam, lParam)
else if (nCode = HC_ACTION)
then begin
VMsg := PMsg(Pointer(lParam));
VWndValid := IsWindow(FHookWnd)
and (VMsg.hwnd = FHookWnd);
if VWndValid
and (FSecretLines <>
nil)
and (FSecretLineID >= 0)
and (FSecretLineID < FSecretLines.Count)
then begin
S := FSecretLines[FSecretLineID];
VMess := VMsg.
message;
case VMess
of
// WM_KEYUP
WM_KEYUP :
begin
VVirtKey := VMsg.wParam;
case VVirtKey
of
// VK_CONTROL
VK_CONTROL :
begin
FCTRLDown := false;
end;
end;
end;
// WM_KEYDOWN
WM_KEYDOWN :
begin
GetKeyBoardState(FKeyState);
//
VVirtKey := VMsg.wParam;
case VVirtKey
of
// VK_CONTROL
VK_CONTROL :
begin
FCTRLDown := true;
end;
// VK_BACK
VK_BACK :
begin
GetStartEndSel(VStartSel, VEndSel);
Delete(S, VStartSel, VEndSel - VStartSel + 1);
end;
// VK_DELETE
VK_DELETE :
begin
GetStartEndSel(VStartSel, VEndSel);
if (VEndSel = VStartSel)
then Delete(S, VStartSel + 1, VEndSel - VStartSel + 1)
else Delete(S, VStartSel + 1, VEndSel - VStartSel);
end;
// VK_RETURN
VK_RETURN :
begin
GetStartEndSel(VStartSel, VEndSel);
Delete(S, VStartSel + 1, VEndSel - VStartSel);
end;
// VK_...
else begin
if not FCTRLDown
then begin
GetKeyBoardState(VKeyState);
VScanCode := VMsg.lParam
and $FF0000;
//
ZeroMemory(@VCharCode, SizeOf(VCharCode));
VKBLayout := GetKeyBoardLayout(GetCurrentThreadID);
VRetVal := ToASCIIEx(VVirtKey, VScanCode, VKeyState, @VCharCode, 0, VKBLayout);
//
if (VRetVal <> 0)
then begin
GetStartEndSel(VStartSel, VEndSel);
Delete(S, VStartSel + 1, VEndSel - VStartSel);
Insert(VCharCode, S, VStartSel + 1);
//
if ProcessStr(S, FSecretTextMaxLength)
then begin
VKeyState[VK_SHIFT] := 0; SetKeyBoardState(VKeyState);
VMsg.wParam := VChar;
end
else VMsg.wParam := 0
end;
end;
end;
end;
end;
// WM_CHAR
WM_CHAR :
begin
case VMsg.wParam
of
$09 : S := S + #09;
$0D : S := S + #$0D#$0A;
VChar : VMsg.wParam := Ord(FSecretChar);
end;
//
SetKeyBoardState(FKeyState);
end;
end;
//
SetSecretLine(FSecretLineID, S);
end;
end;
//
if (FMX_HookEdit <>
nil)
and Assigned(FMX_HookEdit.FOnGetMsg)
then FMX_HookEdit.FOnGetMsg(nCode, wParam, lParam);
end;