Всегда думал, что ББ работает в одном потоке Windows. Однако это не так
Обработка клавиатуры сделана в отдельном потоке.

## Код:
```
(* -------------------- keyboard interrupt handling --------------------- *)

   PROCEDURE KeyboardWatcher (main: INTEGER): INTEGER;   (* runs in a thread *)
      TYPE P = PROCEDURE(w: INTEGER): INTEGER;
      VAR res, a: INTEGER; top, h: WinApi.HANDLE; done: BOOLEAN;
         context: WinApi.CONTEXT; mod: Module; isHungAppWindow: P;
   BEGIN
      done := FALSE;
      isHungAppWindow := NIL;
      h := WinApi.LoadLibraryA("user32.dll");
      IF h # 0 THEN
         isHungAppWindow := S.VAL(P, WinApi.GetProcAddress(h, "IsHungAppWindow"))
      END;
      LOOP
         res := WinApi.GetAsyncKeyState(WinApi.VK_CANCEL);
         IF res >= 0 THEN   (* key released *)
            done := FALSE;
            WinApi.Sleep(10);
         ELSIF ~done THEN   (* key pressed *)
            top := WinApi.GetForegroundWindow();
            IF (mainWnd # top) & (isHungAppWindow # NIL)
                  & (top # 0) & (isHungAppWindow(top) # 0)
                  & (mainWnd # 0) & (isHungAppWindow(mainWnd) # 0) THEN
               (* main window replaced by ghost window *)
               (* check if application window is topmost nonresponding window *)
               REPEAT
                  top := WinApi.GetWindow(top, WinApi.GW_HWNDNEXT)
               UNTIL (top = 0) OR (isHungAppWindow(top) # 0) & (WinApi.IsWindowVisible(top) # 0)
            END;
            IF mainWnd = top THEN
               res := WinApi.SuspendThread(main);
               context.ContextFlags := {0, 16};
               res := WinApi.GetThreadContext(main, context);
               mod := modList; a := context.Eip;
               WHILE (mod # NIL) & ((a < mod.code) OR (a >= mod.code + mod.csize)) DO
                  mod := mod.next
               END;
               IF (mod # NIL) & (mod.name = "Kernel") THEN mod := NIL END;
               IF mod # NIL THEN
                  interrupted := TRUE;
                  INCL(S.VAL(SET, context.EFlags), 8);   (* set trap flag *)
                  res := WinApi.SetThreadContext(main, context);
                  done := TRUE
               END;
               res := WinApi.ResumeThread(main);
               WinApi.Sleep(1);
               interrupted := FALSE
            END
         END
      END;
      RETURN 0
   END KeyboardWatcher;

   PROCEDURE InstallKeyboardInt;
      VAR res, id: INTEGER; t, main: WinApi.HANDLE;
   BEGIN
      res := WinApi.DuplicateHandle(WinApi.GetCurrentProcess(), WinApi.GetCurrentThread(),
               WinApi.GetCurrentProcess(), main, {1, 3, 4, 16..19}, 0, {});
      t := WinApi.CreateThread(NIL, 4096, KeyboardWatcher, main, {}, id);
   END InstallKeyboardInt;
```
