How to Speed Up Remote Desktop Applications
March 9, 2021 By Stephen Ball
One feature update to RAD Studio 10.4.2, driven by analysis showing an increase in the number of developers using remote desktop to development during Covid, has been a speed up to the IDE rendering over Remote Desktop.
The main issues focused on were the IDE freezing in some situations (such as when connecting or disconnecting remote desktop), flickering, and a few AV’s.
The QP items looked at for 10.4.2 include:
While I’ve not got a sample project that can be shared, I have got permission to share a few notes the R&D team at Embarcadero provided based on their experiences, and I hope this will be useful to other developers too.
The root cause for all those issues is that any RDP session change (lock, unlock, connect, disconnect) sent a system-wide setting change (WM_SETTINGCHANGE) causing a message cascade that leads to multiple redraws in the IDE. This was the cause of some of the AV’s as between the cascade messages sent by the OS it included the WM_THEMECHANGED message that was triggering the handle recreation for some controls. This was affecting the VCL/FMX designers when they were left open and a session was reconnected via RDP.
The Для просмотра ссылки Войдиили Зарегистрируйся provides a way to receive the RDP session change notifications (WM_WTSSESSION_CHANGE). Managing this enables the IDE to become notified when the session is locked, unlocked, connected, disconnected, and from here we can choose how the WM_SETTINGCHANGE is handled and avoid the flickering/repainting issues.
One note from the R&D team was using VCL styles on terminal services is more likely to cause an application to see flicker under normal circumstances.
This skeleton sample of code (untested) should hopefully provide pointers in the right direction for anyone looking to add similar support into their applications.
March 9, 2021 By Stephen Ball
One feature update to RAD Studio 10.4.2, driven by analysis showing an increase in the number of developers using remote desktop to development during Covid, has been a speed up to the IDE rendering over Remote Desktop.
The main issues focused on were the IDE freezing in some situations (such as when connecting or disconnecting remote desktop), flickering, and a few AV’s.
The QP items looked at for 10.4.2 include:
- Reconnect an Existing RDP session using the same screen settings (same machine) RS-99048
- Reconnect an Existing RDP session using different screen settings (e.g from a different machine) RS-103339
- Reconnect an Existing RDP session with the FMX designer opened causes AV.
While I’ve not got a sample project that can be shared, I have got permission to share a few notes the R&D team at Embarcadero provided based on their experiences, and I hope this will be useful to other developers too.
The root cause for all those issues is that any RDP session change (lock, unlock, connect, disconnect) sent a system-wide setting change (WM_SETTINGCHANGE) causing a message cascade that leads to multiple redraws in the IDE. This was the cause of some of the AV’s as between the cascade messages sent by the OS it included the WM_THEMECHANGED message that was triggering the handle recreation for some controls. This was affecting the VCL/FMX designers when they were left open and a session was reconnected via RDP.
The Для просмотра ссылки Войди
One note from the R&D team was using VCL styles on terminal services is more likely to cause an application to see flicker under normal circumstances.
This skeleton sample of code (untested) should hopefully provide pointers in the right direction for anyone looking to add similar support into their applications.
Код:
type
TFormMain = class(TForm)
TimerEnableMetricSettings : TTimer;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure TimerEnableMetricSettingsOnTimer(Sender: TObject);
private
FMethodWnd: HWND;
procedure WTS_SessionWndProc(var Message: TMessage);
procedure DoHandleRDPLock;
procedure DoHandleRDPUnLock;
end;
var
FormMain: TFormMain;
implementation
{$R *.dfm}
procedure TFormMain.DoHandleRDPLock;
begin
// Prevent the VCL App reacting to WM_SETTINGCHANGE when a rdp session is locked/disconnected.
// Stop the timer if it's already running
if TimerEnableMetricSettings.Enabled then
TimerEnableMetricSettings.Enabled := False;
Application.UpdateMetricSettings := False;
end;
procedure TFormMain.DoHandleRDPUnLock;
begin
// Stop the timer if it's already running
if TimerEnableMetricSettings.Enabled then
TimerEnableMetricSettings.Enabled := False;
// Re-start the timer.
TimerEnableMetricSettings.Enabled := True;
end;
procedure TFormMain.FormCreate(Sender: TObject);
begin
TimerEnableMetricSettings.Interval := 30000;
TimerEnableMetricSettings.Enabled := False;
// This hooks to the method WTS_SessionWndProc below to control the Lock
FMethodWnd := AllocateHWnd(WTS_SessionWndProc);
WTSRegisterSessionNotification(FMethodWnd, NOTIFY_FOR_THIS_SESSION);
end;
procedure TFormMain.FormDestroy(Sender: TObject);
begin
if FMethodWnd <> 0 then
begin
WTSUnRegisterSessionNotification(FMethodWnd);
DeallocateHWnd(FMethodWnd);
end;
end;
procedure TFormMain.WTS_SessionWndProc(var Message: TMessage);
begin
if Message.Msg = WM_WTSSESSION_CHANGE then
begin
case Message.wParam of
WTS_SESSION_LOCK,
WTS_REMOTE_DISCONNECT: DoHandleRDPLock;
WTS_REMOTE_CONNECT,
WTS_SESSION_UNLOCK: DoHandleRDPUnLock;
end;
end;
Message.Result := DefWindowProc(FMethodWnd, Message.Msg, Message.WParam, Message.LParam);
end;
procedure TFormMain.TimerEnableMetricSettingsOnTimer(Sender : TObject);
begin
// stop the timer
TimerEnableMetricSettings.Enabled := False;
// it is recommended to wait a few seconds before this is run
// hence setting the timer interval to 30000 in FormCreate
Application.UpdateMetricSettings := True;
end;
end.