unit UnitThreadAttach;
//
// Easy way to attach to an external process and automatically detach
// Used mainly to change focus to another window
//
interface


uses Windows, Classes, System.Types;

type TThreadAttach = class(TObject)
    private
        ThreadTarget : cardinal;
        ThreadOurs : cardinal;
        ThreadAttached : boolean;
    public
        constructor Create(TargetWindow: cardinal);
        function IsAttached : boolean;
        procedure Detach;
        destructor Destroy; override;
end;


implementation


constructor TThreadAttach.Create(TargetWindow: cardinal);
begin
    inherited Create;

    ThreadAttached := false;

    ThreadTarget := Windows.GetWindowThreadProcessId(TargetWindow, nil);
    ThreadOurs := Windows.GetCurrentThreadId();

    if (ThreadTarget <> ThreadOurs) then begin
        ThreadAttached := Windows.AttachThreadInput(ThreadTarget, ThreadOurs, true);
    end else begin
        ThreadAttached := true;
    end;
end;
destructor TThreadAttach.Destroy;
begin
    Detach;
    inherited;
end;

function TThreadAttach.IsAttached : boolean;
begin
    result := ThreadAttached;
end;
procedure TThreadAttach.Detach;
begin
    if (ThreadTarget <> ThreadOurs) and (ThreadAttached) then begin
        Windows.SetLastError(ERROR_SUCCESS);
        Windows.AttachThreadInput(ThreadTarget, ThreadOurs, false);
    end;
    ThreadAttached := false;
end;

end.
