Jump to content
aehimself

Delphi 12 VCL painting differs through RDP

Recommended Posts

Hello,

 

I have an application which utilizes DimPanels. A couple of days ago I was notified that there are some buttons barely visible; however they are supposed to be on a solid background. The issue is, something is being drawn different when the application is executed in an RDP window. Locally I receive a solid form while through RDP everything is transparent, revealing the component underneath:

 

image.png.d52fcea207f7a832ac4ae12eec254a0e.png image.png.fbda70fe2696fab579ac1b95a737af64.png

 

Attached is the minimum test case... it simply creates a DimPanel on the form and embeds an empty frame into it. The solution is rather easy: enable ParentBackground in the DimPanel or disable ParentBackground on the frame. My question is; does anyone know why drawing differs?

DimPanelTest.7z

Share this post


Link to post
3 hours ago, aehimself said:

Locally I receive a solid form while through RDP everything is transparent, revealing the component underneath:

Weird, I would expect just the opposite (solid in rdp and transparent locally).

 

What are the settings under the Experience tab in your RDP connection? Ser it to highest speed and disable bitmap caching and see if that helps.

 

 

 

Share this post


Link to post
1 hour ago, rvk said:

What are the settings under the Experience tab in your RDP connection? Ser it to highest speed and disable bitmap caching and see if that helps.

Settings are the highest possible as I was testing it on a local VM where connection speed isn't an issue. While the idea is good, disabling bitmap caching did not solve the issue.

 

What I am really interested of is that in DimPanel I am not calling inherited in the overridden Paint method. How come ParentBackground has any actual effect...? Probably some weird window message to set the color, I don't know...

Share this post


Link to post

PS. You testproject in your openingspost works for me (Compiled on Delphi 10.2, Windows 10 and RDP'ing to a Windows 10 Hyper-V).

Panel show solid (without memo1 bleeding through).

 

  • Like 1

Share this post


Link to post

Well that’s something I didn’t think of as a possible root cause, that’s why I did not mention that I am using D12 to compile.

 

I tried on remote Windows 10 and Server 2019, both behaved the same way.

 

I’ll check with some earlier Delphi versions.

Share this post


Link to post
Posted (edited)

Confirmed.

When building the same project with Delphi 11.2 the panel shows up solid, so this seems to be a Delphi 12 "issue".

 

...but why only through RDP?

 

Edit: updated topic title

Edited by aehimself

Share this post


Link to post

I don't know how much access to this server you have, but I would start by connecting to its console session either physically or via something like Anydesk and logging in there, then running your app to see how the base operating system settings are affecting your application. This will then determine if its ONLY via RDP or across the entire machine.

 

If you determine its only in RDP, review the settings in the remote desktop connection (MSTSC) app, by selecting LAN (10mbps or higher) and ensuring all are ticked ON

 

It is also possible for a system admin to disable some of these options server side via policy.

Share this post


Link to post

Logging on to the same machine with the console session does not reproduce the issue.

Also, I doubt RDP is at fault, as it only affects Delphi 12 binaries.

Share this post


Link to post

Didn't Embarcadero announce that they "improved the experience" of the IDE and Delphi programs when run in an RDP session? I'm not sure which Delphi version this was, but I think it wasn't 12. Maybe 11?

  • Like 1

Share this post


Link to post

In Delphi 12 EMB has changed the way DoubleBuffered works in DRP session and added DoubleBufferedMode property. So inspect the source/documentation on that or just play with those properties.

  • Like 1

Share this post


Link to post
4 hours ago, dummzeuch said:

Didn't Embarcadero announce that they "improved the experience" of the IDE and Delphi programs when run in an RDP session? I'm not sure which Delphi version this was, but I think it wasn't 12. Maybe 11?

 

I believe it was starting with 11 and "enhanced" in 12. I know that they wrote 12 should be much better than earlier versions.

Share this post


Link to post

Double buffering is a valid point as it's turned on in my main application. It is however is off in the test program, and unfortunately enabling it (and changing DoubleBufferedMode) doesn't change the behaviour.

Share this post


Link to post
Posted (edited)

I'm also facing issues with RDP and Delphi 12 (actionbar menus are messy). No problem at all with Delphi 11.

 

Found this workaround.

 

program xxxxx;

uses
  Vcl.Forms,
  WinAPI.Windows,
  ....;

{$R *.res}
begin
  Application.SingleBufferingInRemoteSessions := GetSystemMetrics(SM_REMOTESESSION) = 0;
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.Title := 'xxxxxxxxxxxxxxxx';
  Application.CreateForm(Tformxxxx, formxxxx);
  Application.Run;
end.


 

 

Edited by Stéphane Wierzbicki

Share this post


Link to post
30 minutes ago, rvk said:

Interesting read! Do I understand it correctly that if you do NOT override anything, themed and un-themed controls do not use double buffering (even if set in object inspector) if a remote session is detected?

 

If yes, it means we can completely exclude double buffering as a potentional suspect for this particular issue.

 

But, it actually reminded me to also note: the issue only appears on the system (Windows) style. If any custom style is selected, the frame (panel?) will become solid again.

Share this post


Link to post
On 1/8/2024 at 9:15 PM, aehimself said:

Interesting read! Do I understand it correctly that if you do NOT override anything, themed and un-themed controls do not use double buffering (even if set in object inspector) if a remote session is detected?

 

If yes, it means we can completely exclude double buffering as a potentional suspect for this particular issue.

Yes. So you could set SingleBufferingInRemoteSessions to true to test if enabling DoubleBuffering in RDP would help.

(turning on DoubleBuffering manually doesn't have effect if SingleBufferingInRemoteSessions is still set to false)

 

If it doesn't help, then it must be something else.

 

  • Like 1

Share this post


Link to post

Even if DoubleBuffered is on for the frame and the form, and Application.SingleBufferingInRemoteSessions is true, I still see the memo in the test application if I execute it in an RDP window.

No, double buffering seems to have no effect on this particular issue.

Share this post


Link to post
20 minutes ago, aehimself said:

Even if DoubleBuffered is on for the frame and the form, and Application.SingleBufferingInRemoteSessions is true

Woops, sorry. The Application.SingleBufferingInRemoteSessions is true as default.

You should try to set it to false so the RDP acts the same as without RDP regarding doublebuffering.

 

http://docwiki.embarcadero.com/Libraries/Alexandria/en/Vcl.Forms.TApplication.SingleBufferingInRemoteSessions

 

  • Thanks 1

Share this post


Link to post

Aaaaand jackpot! Adding Application.SingleBufferingInRemoteSessions := False solves the issue for good, no more dimmed memo is visible through RDP!

 

The only question which I have remaining - if DoubleBuffered is false everywhere in the test application, how come enforcing single buffering makes a difference? Shouldn't that be the default, if .DoubleBuffered is false on the form and on the frame?

Share this post


Link to post
8 minutes ago, aehimself said:

Aaaaand jackpot! Adding Application.SingleBufferingInRemoteSessions := False solves the issue for good, no more dimmed memo is visible through RDP!

 

The only question which I have remaining - if DoubleBuffered is false everywhere in the test application, how come enforcing single buffering makes a difference? Shouldn't that be the default, if .DoubleBuffered is false on the form and on the frame?

Likely interacts with the WS_EX_LAYERED style in some way as that style does do some extra work (composes and repaints layered windows and the windows of underlying applications).

 

Window Features - Layered Windows - Win32 apps | Microsoft Learn

Extended Window Styles (Winuser.h) - Win32 apps | Microsoft Learn

Share this post


Link to post
16 minutes ago, aehimself said:

The only question which I have remaining - if DoubleBuffered is false everywhere in the test application, how come enforcing single buffering makes a difference?

You didn't set DoubleBuffering to false for the TFrame itself (at least not in the code I saw). So if there (for TFrame) it is still true, then SingleBufferingInRemoteSessions = false would make the difference.

 

Share this post


Link to post
49 minutes ago, rvk said:

You didn't set DoubleBuffering to false for the TFrame itself (at least not in the code I saw). So if there (for TFrame) it is still true, then SingleBufferingInRemoteSessions = false would make the difference.

 

Talking about the small program I attached; it is not present in the code or in the DFM - you are right about that. That means it is using the default, which is False for DoubleBuffering.

At least this is how I believe it should work.

Share this post


Link to post
15 minutes ago, aehimself said:

That means it is using the default, which is False for DoubleBuffering.

Ah, ok. I thought the default for DoubleBuffered was true. But I am probably mistaken (it is true in Lazarus unless in a remote session but apparently not in Delphi).

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×