unit UnitKeyboardQuery;

{
    Purpose:
        Query if a key is pressed or a lock key is on/off

    Updates:
        - new functionality
        - Mouse clickes added

    NOTES:
        Mouse clicks may not seem like a Keyboard function, but
        they are retreived from GetAsyncKeyState
}


{///////////}
{}interface{}
{///////////}
uses Windows, Dialogs, SysUtils;


type MouseButton = (leftButton, RightButton, MiddleButton);
type TKeyboardQuery = class(TObject)
    private
    public
        function IsPressed(VKConstant : integer) : boolean;
        function LockOn(VKConstant : integer) : boolean;
        function WaitUntilRelease(VKConstant : integer) : boolean; overload;
        procedure WaitUntilRelease(bi : MouseButton); overload;
        function IsClicked( bi : MouseButton ) : boolean;
end;


var KeyboardQuery : TKeyboardQuery;

{////////////////}
{}implementation{}
{////////////////}

uses Forms, UnitMisc;



function TKeyboardQuery.IsClicked( bi : MouseButton ) : boolean;
var VK : integer;
begin
    Windows.SetLastError(ERROR_SUCCESS);

    //
    // The Physical and Logical "Left Button" may not be the same
    //
    if (bi = LeftButton) and
        (GetSystemMetrics(SM_SWAPBUTTON) = 0) then begin
        vk := VK_LBUTTON;
    end else begin
        vk := VK_RBUTTON;
    end;

    if (bi = MiddleButton) then begin
        vk := VK_MBUTTON;
    end;

    // Async causes some windows to close - like the THintWindow
    //result := (Windows.GetAsyncKeyState(vk) and $8000) > 0;
    result := (Windows.GetKeyState(vk) and $8000) > 0;    
end;


function TKeyboardQuery.IsPressed(VKConstant : integer) : boolean;
begin
    Windows.SetLastError(ERROR_SUCCESS);

    result := (Windows.GetKeyState(VKConstant) and 128) <> 0;
end;


function TKeyboardQuery.LockOn(VKConstant : integer) : boolean;
begin
    Windows.SetLastError(ERROR_SUCCESS);

    result := (Windows.GetKeyState(VKConstant) and 1) <> 0;
end;


function TKeyboardQuery.WaitUntilRelease(VKConstant: integer) : boolean;
begin
    result := false;
    While self.IsPressed(VKConstant) do begin
        result := true;
        mysleep(10);
    end;
end;

procedure TKeyboardQuery.WaitUntilRelease(bi: MouseButton);
begin
    while IsClicked(bi) do begin
        Application.ProcessMessages;
        mysleep(10);
    end;
end;


{////////////////}
{}initialization{}
{////////////////}
Begin
    KeyboardQuery := TKeyboardQuery.Create;
end;

end.
