Одним из обновлений функции RAD Studio 10.4.2, основанным на анализе, показывающем рост числа разработчиков, использующих удаленный рабочий стол для разработки во время Covid, стало ускорение рендеринга IDE через удаленный рабочий стол.
Основными проблемами были зависание IDE в некоторых ситуациях (например, при подключении или отключении удаленного рабочего стола), мерцание и несколько AV.
Пункты QP, рассмотренные для 10.4.2, включают:
- Повторно подключите существующий сеанс RDP, используя те же настройки экрана (тот же компьютер) RS-99048
- Повторно подключите существующий сеанс RDP, используя другие настройки экрана (например, с другого компьютера) RS-103339
- Повторное подключение существующего сеанса RDP с открытым конструктором FMX вызывает AV.
Кроме того, был ряд внутренних отчетов.
Хотя у меня нет образца проекта, которым можно поделиться, у меня есть разрешение поделиться некоторыми заметками, которые команда разработчиков Embarcadero предоставила на основе своего опыта, и я надеюсь, что это будет полезно и другим разработчикам.
Основная причина всех этих проблем заключается в том, что любое изменение сеанса RDP (блокировка, разблокировка, подключение, отключение) вызывает изменение общесистемных настроек (WM_SETTINGCHANGE), вызывая каскад сообщений, который приводит к множеству перерисовок в среде IDE. Это было причиной некоторых антивирусных программ, поскольку между каскадными сообщениями, отправленными ОС, оно включало сообщение WM_THEMECHANGED, которое запускало воссоздание дескриптора для некоторых элементов управления. Это повлияло на разработчиков VCL / FMX, когда они были оставлены открытыми и сеанс был повторно подключен через RDP.
WTS API предоставляет возможность получать уведомление изменения RDP сессии (WM_WTSSESSION_CHANGE). Управление этим позволяет IDE получать уведомления, когда сеанс заблокирован, разблокирован, подключен, отключен, и отсюда мы можем выбрать, как обрабатывается WM_SETTINGCHANGE, и избежать проблем с мерцанием / перерисовкой.
Одно замечание от команды R&D заключалось в том, что использование стилей VCL в службах терминалов с большей вероятностью заставит приложение видеть мерцание при нормальных обстоятельствах.
Мы надеемся, что этот скелетный образец кода (непроверенный) предоставит указатели в правильном направлении для всех, кто хочет добавить аналогичную поддержку в свои приложения.
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.
Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder.
Design. Code. Compile. Deploy.
Free Delphi Community Edition Free C++Builder Community Edition







