Одним из обновлений функции 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 в службах терминалов с большей вероятностью заставит приложение видеть мерцание при нормальных обстоятельствах.
Мы надеемся, что этот скелетный образец кода (непроверенный) предоставит указатели в правильном направлении для всех, кто хочет добавить аналогичную поддержку в свои приложения.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
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. |
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition