Controls Disappear/Don't Refresh when moving between different scaling screens

Add-in Express™ Support Service
That's what is more important than anything else

Controls Disappear/Don't Refresh when moving between different scaling screens
 
Richard Stevens




Posts: 63
Joined: 2007-01-24
Increasingly we have customers who run 2 monitors at different scaling, eg. a surface pro with 200% scaling attached to a standard monitor which is at 100%.

Our Outlook Addin often fails to refresh/repaint properly in this situation.

We have replicated this in a test project.

http://www.boe-systems.co.uk/clients/AddInExpress/ScalingTest.zip

To replicate:

- Build and Register Addin. It should add a pane above the reading pane for an email
- Run Outlook on a system with 2 monitors similar to the one described - we can replicate with 2 desktop monitors, one at 100% and one at 150%
- Move Outlook from the 100% screen to the 150% screen
- Move between different emails in your inbox with the reading pane open, and you'll see the label and edit controls should disappear

Any advice welcome

Thanks
Richard
Posted 06 Oct, 2020 02:37:28 Top
Andrei Smolin


Add-in Express team


Posts: 18823
Joined: 2006-05-11
Hello Richard,

Are you saying you see this with build 9.3.1660?


Andrei Smolin
Add-in Express Team Leader
Posted 06 Oct, 2020 04:49:28 Top
Richard Stevens




Posts: 63
Joined: 2007-01-24
Andrei - yes, sorry should have said. Delphi Rio 10.3.3 with latest ADX 9.3.1660
Posted 06 Oct, 2020 05:58:37 Top
Andrei Smolin


Add-in Express team


Posts: 18823
Joined: 2006-05-11
Hello Richard,

Add-in Express doesn't scale forms: the developer should do this. You are expected to handle the OnAdxDPIChanged event.

Find an idea of what is behind the scenes in the .NET-oriented description at https://www.add-in-express.com/creating-addins-blog/2018/05/08/add-in-express-multiple-dpi-monitors/. Alas, no Delphi-oriented description exists.


Andrei Smolin
Add-in Express Team Leader
Posted 06 Oct, 2020 08:29:16 Top
Richard Stevens




Posts: 63
Joined: 2007-01-24
Were you able to replicate the issue in my test project?

The scaling of items and their initial visual appearance seems fine and correct. It's just that the controls start to disappear when we try and do other interface changes on the form.
Posted 07 Oct, 2020 04:26:58 Top
Andrei Smolin


Add-in Express team


Posts: 18823
Joined: 2006-05-11
Hello Richard,

No, I wasn't able to.

The thread in which the controls are created must have the same DPI context as the window in which the controls are created. You use GetWindowDpiAwarenessContext() to get the DPI context; say, you can pass the handle of the Add-Express form or the Outlook Explorer window to it. Then you pass the context to SetThreadDpiAwarenessContext() and create your controls.


Andrei Smolin
Add-in Express Team Leader
Posted 07 Oct, 2020 09:46:57 Top
Richard Stevens




Posts: 63
Joined: 2007-01-24
Unfortunately we're on the edge of giving up with this, and telling our customer that we can't support screens at different scaling. This will probably mean we will no longer be able to do business with them.

Our Addin seems to struggle massively in this situation, with controls disappearing and out of resources errors also appearing.

For once Andrei I have to say your advice has not been very helpful. When should we GetWindowDpiAwarenessContext? When should we pass the handle to the form? We really need some sample Delphi code to help us, and not just a link to a .NET article.

Have you actually tried our sample application on two monitors with different scaling? I can send a video to illustrate the issue if it's not clear what steps to take.

Thanks,
Richard
(Premium Customer)
Posted 13 Oct, 2020 15:20:05 Top
Andrei Smolin


Add-in Express team


Posts: 18823
Joined: 2006-05-11
Hello Richard,

I'm sorry to be that careless.

The article provides a link to the API reference; see https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-improvements-for-desktop-applications.

Right before the window (its handle) is created, you call GetWindowDpiAwarenessContext() to get the context; that method requires a window handle; use the handle of the Outlook active window. Then you pass the context to SetThreadDpiAwarenessContext(). Then let the window create.

To get the starting DPI, use GetDpiForWindow; see https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdpiforwindow. Finally, you need to handle the OnAdxDPIChanged event to react to DPI changes.

Here's an example: http://temp.add-in-express.com/projects_pub/vcl_dpichanged.zip. It comes with a comment: "Some controls don't scale well. You may need to create a new custom-drawn control or inherit the source control and override the ChangeScale method."

Actually, this example missing was my fault, too: I should have noticed this a whole while back.


Andrei Smolin
Add-in Express Team Leader
Posted 14 Oct, 2020 04:54:50 Top