В процедуру (HostPorts):

PROCEDURE (rd: Rider) Input* (OUT x, y: INTEGER; OUT modifiers: SET; OUT isDown: BOOLEAN);
VAR msg: USER32.Message; wnd, mw: USER32.Handle; pt: USER32.Point; res: INTEGER; set: SET;
BEGIN
wnd := rd.port.wnd; mw := USER32.GetCapture();
IF USER32.PeekMessageA(msg, mw, USER32.WMMouseMove, USER32.WMMButtonDblClk, 1) # 0 THEN
mx := (msg.lParam + 32768) MOD 65536 - 32768; my := msg.lParam DIV 65536;
IF (mw # 0) & (wnd # mw) THEN
pt.x := mx; pt.y := my; res := USER32.ClientToScreen(mw, pt);
res := USER32.ScreenToClient(wnd, pt); mx := pt.x; my := pt.y
END;
mb := {};
set := SYSTEM.VAL(SET, msg.wParam);
IF WinApi.MK_LBUTTON * set # {} THEN INCL(mb, left) END;
IF WinApi.MK_MBUTTON * set # {} THEN INCL(mb, middle) END;
IF WinApi.MK_RBUTTON * set # {} THEN INCL(mb, right) END;
IF WinApi.MK_CONTROL * set # {} THEN INCL(mb, ctrl) END;
IF WinApi.MK_SHIFT * set # {} THEN INCL(mb, shift) END;
IF USER32.GetAsyncKeyState(12H) < 0 THEN INCL(mb, alt) END;
(*
Windows.dir.Update(NIL)
*)
END;
IF WinApi.GetSystemMetrics(WinApi.SM_SWAPBUTTON) # 0 THEN
IF USER32.GetAsyncKeyState(1) >= 0 THEN EXCL(mb, right) END;
IF USER32.GetAsyncKeyState(2) >= 0 THEN EXCL(mb, left) END
ELSE
IF USER32.GetAsyncKeyState(1) >= 0 THEN EXCL(mb, left) END;
IF USER32.GetAsyncKeyState(2) >= 0 THEN EXCL(mb, right) END
END;
IF USER32.GetAsyncKeyState(4) >= 0 THEN EXCL(mb, middle) END;
IF WinApi.GetAsyncKeyState(WinApi.VK_SHIFT) < 0 THEN
mb := mb + {shift, extend} ELSE  mb := mb - {shift, extend}
END;
IF WinApi.GetAsyncKeyState(WinApi.VK_CONTROL) < 0 THEN
mb := mb + {ctrl, modify} ELSE  mb := mb - {ctrl, modify}
END;
IF WinApi.GetAsyncKeyState(WinApi.VK_MENU) < 0 THEN INCL(mb, alt) ELSE EXCL(mb, alt) END;

(*
(* alt handling *)
res := USER32.PeekMessageA(msg, 0, USER32.WMSysKeyDown, USER32.WMSysKeyDown, 1);
*)
x := mx; y := my; modifiers := mb; isDown := mb * {left, middle, right} # {};

IF USER32.PeekMessageA(msg, 0, USER32.WMTimer, USER32.WMTimer, 1) #0 THEN
res := USER32.TranslateMessage(msg);
res := USER32.DispatchMessageA(msg)
END;

END Input;

необходимо добавить
IF USER32.PeekMessageA(msg, 0, USER32.WMTimer, USER32.WMTimer, 1) #0 THEN
res := USER32.TranslateMessage(msg);
res := USER32.DispatchMessageA(msg)
END;
иначе, если в клиентской области окна редактирования нажать мышь и не отпускать, то отображение также  замораживается.

Вообще-то WM_Timer не очень надежное сообщение. В некоторые моменты оно вообще может не посылаться или посылаться с большими задержками, чем установлено.
Можно подумать над реализацией кокого-нибудь thread таймера.