キー入力のサブルーチンはわかりました。
このサブルーチンをどのようなタイミングで呼び出しているかが鍵だと思います。
下記はDelphiでのWindowsプログラムの一例です。
メインフォームには、Memo1とMomo2という窓があります。
F5のキーが押されたときに、フォーカスがある方に
文字fを追加します。
このコードをタイマーで繰り返し呼び出しています。
Memo1からMemo2にフォーカスを移したとき、
文字が余分にプリントされることはありませんでした。
MS-DOSとは考え方が異なるかもしれませんが、
少しでも参考になれば幸いです。
procedure TForm1.Timer1Timer(Sender: TObject);
var
f: integer;
begin
f := GetAsyncKeyState(VK_F5);
if f<>0 then
if Memo1.Focused then Memo1.Text := Memo1.Text + 'f'
else if Memo2.Focused then Memo2.Text := Memo2.Text + 'f';
end;