pyscripter 689 Posted March 5, 2021 (edited) Delphi 10.4.2 is advertised to be "Remote desktop friendly". Does anyone know what it takes to make Delphi applications remote desktop friendly? Edited March 5, 2021 by pyscripter Share this post Link to post
dummzeuch 1505 Posted March 5, 2021 We have been using our inhouse Delphi (2007, XE and lately 10.2) applications almost exclusively via remote Desktop since the start of the Corona pandemic without any problems at all. There is a bug in the Delphi 2007 VCL which can cause an AV when switching between local display and Remote Desktop. After I found and fixed it several years ago (don't remember the specifics), everything just worked. Also, I have been using Delphi 2007, XE2 and 10.2 (and sometimes other versions) via Remote Desktop for years. No problem either. So, my guess would be that this is just marketing. If I had to guess: A Remote Desktop friendly program does not create too many redraws. So: Use double buffering. Share this post Link to post
Attila Kovacs 629 Posted March 5, 2021 18 minutes ago, dummzeuch said: If I had to guess: A Remote Desktop friendly program does not create too many redraws. So: Use double buffering. RDP is a kind of a double buffering, do not use double buffering with RDP 1 Share this post Link to post
Der schöne Günther 316 Posted March 5, 2021 The IDE has (or had?) terrible problems with resolution changes, like changing the size of your remote desktop window which also includes connections to Hyper-V VMs. It often got stuck for a minute or completely locked up. It seems they have fixed that with 10.4.2: Quote Sometimes, the IDE did not handle the resolution change caused by Remote Desktop and became unresponsive. That thankfully is a thing of the past. Delphi 10.4.2: Improvements for Microsoft Remote Desktop sessions – FlixEngineering LLC 1 Share this post Link to post
David Heffernan 2345 Posted March 5, 2021 (edited) 3 hours ago, Attila Kovacs said: RDP is a kind of a double buffering, do not use double buffering with RDP Double buffering is absolutely one of the things that you don't do when over RDP. Because then you give up app the benefit of transmitting the logical drawing instructions and instead have to send raster images. But I wouldn't say RDP is double buffering. You don't draw to off screen bitmap and the flip it or blit it. If you want to draw text, you send the text and instructions of where to draw it, and then the actual rendering happens at the other side. But yeah, advice to double buffer is wrong. Correct advice is the opposite. Don't ever double buffer in a remote session. More on that here: https://devblogs.microsoft.com/oldnewthing/20060103-12/?p=32793 This may come as a shock to a lot of Delphi devs for whom the standard reaction to flicker seems to be to enabled DoubleBuffered on the form/control. Edited March 5, 2021 by David Heffernan 1 1 Share this post Link to post
Vincent Parrett 750 Posted March 5, 2021 17 minutes ago, David Heffernan said: This may come as a shock to a lot of Delphi devs for whom the standard reaction to flicker seems to be to enabled DoubleBuffered on the form/control. So what should the standard reaction be? I code my custom controls using my own double buffering and ignore the vcl's double buffering, which tends to be rather buggy and variable (different implementations of it throughout the vcl) - especially when vcl themes are enabled. 1 Share this post Link to post
Guest Posted March 5, 2021 Not to mention that Embarcadero is constantly correcting its own corrections ... patch patches! Until the engineers become aware that the only possible solution is a complete remastering of the system, which I think would only happen if a hacker broke into the servers (including the backups), encrypted everything, asked for an unpayable ransom, forcing the company to break for good. But we know, that in fact, it will not happen ... so, fix the fix! hug Share this post Link to post
pyscripter 689 Posted March 5, 2021 (edited) @David MillingtonMaybe you could enlighten us as to the nature of the changes that made the Delphi IDE behave better with RD. Are there any lessons to be learnt by Delphi developers? Edited March 5, 2021 by pyscripter 1 Share this post Link to post
Guest Posted March 6, 2021 hey @Darian Miller, just a good ransom-ware, it would be nice don't you think? New matrix, new bugs! new RSP!!! Then, no one could say that something is not being done there. hug Share this post Link to post
Darian Miller 361 Posted March 6, 2021 1 hour ago, emailx45 said: it would be nice don't you think? Um... no. To be "nicer", all the replacement code would have to be better than the existing Delphi code. At least much of the current Delphi code is stable. Rewrite your biggest project in a hurry and see if it's better. 1 1 Share this post Link to post
Guest Posted March 6, 2021 I don't know how is this relevant as i didn't see the last few IDE's, but the most impactful thing in Microsoft RDP protocol and its image RLE (Run-Length Encoding) that does affect speed and CPU usage is gradient colors, less color means faster performance and responsiveness, more color or less long sequence of pixels of the same colors means more traffic and more CPU usage on both side, Delphi 2009 have the worst performance over RDP (for me at least). Also may be the RDP shared drives feature may be have a some tweaks, never used it with an IDE, always copied folders and accessed them locally. Share this post Link to post
dummzeuch 1505 Posted March 6, 2021 15 hours ago, emailx45 said: would only happen if a hacker broke into the servers (including the backups), encrypted everything, asked for an unpayable ransom, forcing the company to break for good. They would abandon Delphi for good in that case. There is no way Embarcadero would start that tool from scratch. Share this post Link to post
Guest Posted March 6, 2021 57 minutes ago, dummzeuch said: There is no way Embarcadero would start that tool from scratch. for sure, not for short time... but, just call Elon Musk and all it's solved! A new company in 0day! hug Share this post Link to post
David Millington 79 Posted March 8, 2021 On 3/6/2021 at 1:31 AM, pyscripter said: @David MillingtonMaybe you could enlighten us as to the nature of the changes that made the Delphi IDE behave better with RD. Are there any lessons to be learnt by Delphi developers? We were thinking of writing a blog post about it, I'll ping the person who was looking at doing so. For more detail I'll need to ask our engineers. My level of oversight here was to ask we fix RD bugs, I did not dig into the details of what changes we made or why. 1 Share this post Link to post
pyscripter 689 Posted March 8, 2021 1 hour ago, David Millington said: We were thinking of writing a blog post about it Looking forward to reading it! Share this post Link to post
Fr0sT.Brutal 900 Posted March 9, 2021 On 3/5/2021 at 8:43 PM, pyscripter said: Does anyone know what it takes to make Delphi applications remote desktop friendly? F.ex., my 10.3 is veeery lazy on scrolling via RDP. Share this post Link to post
mvanrijnen 123 Posted March 9, 2021 here is some (old) explanation (don't know it's current though): winforms - Using .NET desktop application with DevExpress over Remote Desktop - Stack Overflow (someone known to all of us here, has responded there also back then : ) ). Share this post Link to post
Stephen Ball 3 Posted March 9, 2021 As @David Millington mentioned, we have been working with the R&D team to share tips learned to help speed up VCL applications under remote desktop - to read about it, including a code sample see: https://blogs.embarcadero.com/how-to-speed-up-remote-desktop-applications/ 3 Share this post Link to post
Fr0sT.Brutal 900 Posted March 9, 2021 (edited) Good subject BTW - I learned GetSystemMetrics(SM_REMOTESESSION) and redesigned DoubleBuffered usage in my apps that are running on remote PC's Edited March 9, 2021 by Fr0sT.Brutal 1 Share this post Link to post
pyscripter 689 Posted March 9, 2021 (edited) 2 hours ago, Stephen Ball said: As @David Millington mentioned, we have been working with the R&D team to share tips learned to help speed up VCL applications under remote desktop - to read about it, including a code sample see: https://blogs.embarcadero.com/how-to-speed-up-remote-desktop-applications/ @Stephen BallThank you very much! Is there a need to have a separate window to receive the notifications? Isn't the code below equivalent to yours? type TForm1 = class(TForm) procedure FormDestroy(Sender: TObject); procedure FormCreate(Sender: TObject); procedure WMWTSSessionChange (var Message: TMessage); message WM_WTSSESSION_CHANGE ; private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormDestroy(Sender: TObject); begin WTSUnRegisterSessionNotification(Handle); end; procedure TForm1.WMWTSSessionChange(var Message: TMessage); begin inherited; case Message.wParam of WTS_SESSION_LOCK, WTS_REMOTE_DISCONNECT: Application.UpdateMetricSettings := False; WTS_REMOTE_CONNECT, WTS_SESSION_UNLOCK: TThread.ForceQueue(nil, procedure begin Application.UpdateMetricSettings := True; end, 30000); end; end; procedure TForm1.FormCreate(Sender: TObject); begin WTSRegisterSessionNotification(Handle, NOTIFY_FOR_THIS_SESSION); end; Edited March 9, 2021 by pyscripter Share this post Link to post
David Heffernan 2345 Posted March 9, 2021 43 minutes ago, pyscripter said: @Stephen BallThank you very much! Is there a need to have a separate window to receive the notifications? Isn't the code below equivalent to yours? type TForm1 = class(TForm) procedure FormDestroy(Sender: TObject); procedure FormCreate(Sender: TObject); procedure WMWTSSessionChange (var Message: TMessage); message WM_WTSSESSION_CHANGE ; private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormDestroy(Sender: TObject); begin WTSUnRegisterSessionNotification(Handle); end; procedure TForm1.WMWTSSessionChange(var Message: TMessage); begin inherited; case Message.wParam of WTS_SESSION_LOCK, WTS_REMOTE_DISCONNECT: Application.UpdateMetricSettings := False; WTS_REMOTE_CONNECT, WTS_SESSION_UNLOCK: TThread.ForceQueue(nil, procedure begin Application.UpdateMetricSettings := True; end, 30000); end; end; procedure TForm1.FormCreate(Sender: TObject); begin WTSRegisterSessionNotification(Handle, NOTIFY_FOR_THIS_SESSION); end; This code fails under VCL window recreation. Hence the Emba code. My answer to this old SO question presents a different way that may be simpler in the long run. https://stackoverflow.com/q/4854534/505088 1 Share this post Link to post
pyscripter 689 Posted March 9, 2021 36 minutes ago, David Heffernan said: My answer to this old SO question presents a different way that may be simpler in the long run. Thanks! DestroyWnd is not called when the application exits. Is this an issue here? You could call the WTSUnRegisterSessionNotification at the WM_DESTROY handler instead. Share this post Link to post
David Heffernan 2345 Posted March 9, 2021 18 minutes ago, pyscripter said: DestroyWnd is not called when the application exits. Really? That's upsetting. Although it rings some bells. But it won't matter here because process termination will lead to the system tidying up. Ill have a look tomorrow. Share this post Link to post
pyscripter 689 Posted March 9, 2021 3 hours ago, David Heffernan said: Really? That's upsetting. Although it rings some bells. But it won't matter here because process termination will lead to the system tidying up. Ill have a look tomorrow. See DestroyWnd not called at destruction of WinControls - VCL - Delphi-PRAXiS [en] Share this post Link to post
pyscripter 689 Posted March 9, 2021 (edited) In light of @David Heffernan remarks here is a shorter version of @Stephen Ball code: type TForm1 = class(TForm) procedure CreateWnd; override; procedure WMWTSSessionChange (var Message: TMessage); message WM_WTSSESSION_CHANGE ; procedure WMDestroy(var Message: TWMDestroy); message WM_DESTROY; private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.WMDestroy(var Message: TWMDestroy); begin inherited; WTSUnRegisterSessionNotification(Handle); end; procedure TForm1.WMWTSSessionChange(var Message: TMessage); begin case Message.wParam of WTS_SESSION_LOCK, WTS_REMOTE_DISCONNECT: Application.UpdateMetricSettings := False; WTS_REMOTE_CONNECT, WTS_SESSION_UNLOCK: TThread.ForceQueue(nil, procedure begin Application.UpdateMetricSettings := True; end, 30000); end; end; procedure TForm1.CreateWnd; begin inherited; WTSRegisterSessionNotification(Handle, NOTIFY_FOR_THIS_SESSION); end; Instead of CreateWnd you could override the CreateWindowHandle method. Edited March 10, 2021 by pyscripter Share this post Link to post