Scalability of Frames

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

Scalability of Frames
Office 2010 to Office 365 Frames Compatibility 
Michael Kaden


Guest


Hello Andrei,

The Add In Express I developed for Office 2010. The ADX addIn solutions are set up for Office 2010 or newer. Now I have users with 2 specifications:

1. Windows 7 Office 2010 Display 1920 x 1080

With our original code the frame looks like this = perfect

User added an image

2. Windows 10 Office 365 Display 3840 x 2160

Display scaling is set to 150 % - change the setting to 100 % or Restart Visual Studio as a DPI-unaware process, or change to any other resolution on the HDPI Monitors does not resolve the problem:

User added an image

If I now change the code for the solution to give me a reasonable but tight as possible setup in 365 I get

http://www.alerasoftlib.de/ADX/Frame03.jpg


which is good, but if I use this AddIn in Office 2010, I get

http://www.alerasoftlib.de/ADX/Frame04.jpg

This unfortunately looks very unprofessional. Do you have an easy solution to that?

Or should I actually put an IF ("Office Version") in the code to have different spacing for different Office Versions and if yes, how would I define that, i.e. how many different setups and how to check programmatically the office version?

Example

If (Office Version = 365) Then Label1.top = Label1.top*1.3

As I have about 100 frames in my AdInn a general solution without rewriting the positioning for each frame component would be most welcome.

Thank you very much & kind regards

Michael
Posted 11 Mar, 2021 13:46:55 Top
Michael Kaden


Guest


Ok something went wrong with my links;

Original Office 2010

User added an image


Original in Office 365

User added an image


New Office 365

User added an image

New Code in Office 2010

User added an image

Hope this works

Thank you & kind regards

Michael
Posted 11 Mar, 2021 13:54:32 Top
Andrei Smolin


Add-in Express team


Posts: 18821
Joined: 2006-05-11
Hello Michael,

This is a DPI-related issue, not Office-related.

You can set the current thread's DPI awareness context as explained at https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-improvements-for-desktop-applications:

A common scenario for the use of SetThreadDpiAwarenessContext is as follows: Begin with a thread that is running with one context (such as DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE) temporarily switch to a different context (DPI_AWARENESS_CONTEXT_UNAWARE), create a window, and then immediately switch the thread context back to its previous state. The created window will have a DPI context of DPI_AWARENESS_CONTEXT_UNAWARE, while the calling thread s context will be restored to DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE with a subsequent call to SetThreadDpiAwarenessContext. In this scenario, the window associated with the calling thread would run with a per-monitor context (and therefore not be bitmap-stretched by the operating system) while the newly-created window would not be DPI aware (and therefore would be automatically bitmap stretched on a display set to >100% scaling).


If you use DPI_AWARENESS_CONTEXT_UNAWARE or DPI_AWARENESS_CONTEXT_SYSTEM_AWARE or maybe DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED, Windows will stretch your form thus making it a bit blurry. If you don't like this, you would need to adapt your form to the current DPI: you'll need to change the position, size, margins, padding, font size, etc. of your controls depending on the current DPI. Note that some controls - and I suppose the option button is among them - won't scale well thus making you use other controls (e.g. custom drawn ones).

This may be a huge lot of work. To simplify it, you can use WPF - it scales well.

Remember that DPI awareness contexts is a relatively new feature and it doesn't exist on all Windows versions.


Andrei Smolin
Add-in Express Team Leader
Posted 12 Mar, 2021 04:09:13 Top
Michael Kaden


Guest


Dear Andrei,

thank you very much for the prompt reply and the information.

First I looked and tried an example for a WPF. If I understand right this would mean that I have to redo all my Forms from scratch. This also would be a steep learning curve as the coding is different. I also found some Google that the scaling does not always work.

Furthermore I tried to find out where the problem comes from:

Please note that there is no problem with font sizes or tool sizes etc. there is only a problem with the Form size and with the positioning of the tools in the Form. I think the following document addresses the issue:

https://docs.microsoft.com/en-us/visualstudio/designers/disable-dpi-awareness?view=vs-2019

However none of he suggested remedies solved the problem

Running Visual Studio with DPI scaling on or off does not make any difference
Running the monitors on 100 % or DPI scaling (150%) does not make any difference
Running the monitors on different resolutions does not make any difference

Interesting that setting the Forms AutoScale property to inherit changes the behavior and gives better results, but still not completely acceptable.

As I define the Form dimension and tools position anyhow in the Load procedure and not in the Form and Tools properties I can easily add a scaling factor. In this example I can get good results with a factor of 1.3

I know, that this is not an office or AddInExpress topic, but perhaps you can give me an idea how i can retrieve, in code, the necessary scaling, in this case 1.3, for a specific monitor? So far 1 day of search in the internet did not make me succeed.

If I use the resolution of the monitors, in this case 3840x2160 against 1920x1080 does not result in 1.3 ?

Thank you very much for your help & kind regards

Michael
Posted 12 Mar, 2021 09:56:10 Top
Andrei Smolin


Add-in Express team


Posts: 18821
Joined: 2006-05-11
Michael,

Michael Kaden writes:
Running Visual Studio with DPI scaling on or off does not make any difference
Running the monitors on 100 % or DPI scaling (150%) does not make any difference
Running the monitors on different resolutions does not make any difference


I've talked about Office, not Visual Studio. I've talked about DPIs, not resolutions: after you change the DPI, restart the Office application. Test 200%, not 150%. Test on two monitors with different DPIs to see the difference. Start Office on a monitor and drag the Office application to another monitor; start Office on the second monitor and drag it to the first one. There's a lot of difference here.

Did you try to use DPI_AWARENESS_CONTEXT_UNAWARE? This is the simplest (and yet the most terribly looking) way of dealing with DPIs: the form will be stretched but you won't deal with the factor you're talking about.

Michael Kaden writes:
Please note that there is no problem with font sizes or tool sizes etc. there is only a problem with the Form size and with the positioning of the tools in the Form.


On the contrary. The problem is: your form and the controls on it must adjust itself to the current DPI. I've listed the properties to be adjusted, see above: do not ignore paddings and margins.

Adjusting to the current DPI also means that the form must be designed with a specific DPI in mind (= in code). To avoid issues, it's UI design should also be created and updated on a monitor with that DPI. If you have DPI=96 on your development machine and if your form is designed against DPI=96, theFactor = currentDPI/96.

I'd suggest that you create/update your form on a monitor with DPI=96 (=100%). In this case, your form will have this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F) in the InitializeComponent method. Also, the AutoscaleMode should be set to "DPI".

You would need to be informed about DPI changes: imagine your form dragged on another monitor with a different DPI. The factor you've found out reflects the difference between the DPI on the monitor where your form was designed and the DPI of the target machine.

You may also need to set the required DPI awareness context.

Do not expect to find a simple way to solve this. The topic is far more complex than it seems. However difficult WPF looks like, it doesn't let you run in such issues. It should be easy to create a single form in WPF. In future, it would be easy to change its design so that your code isn't affected. This will also broaden your experience.

Ignore the above and have a relaxing weekend.


Andrei Smolin
Add-in Express Team Leader
Posted 12 Mar, 2021 11:37:25 Top
Michael Kaden


Guest


Hello Andrei,

I finally started to convert my Windows to WPF. However I am encountering some issues which I even with very extensive search I cannot resolve:

1.) I have a button on the WPS window which starts (on_Click) a lengthy data transfer from an Excel sheet to the RAM memory (between 2.000.000 and 10.000.000 cell values) This can take up to 3 minutes and I would like to inform the user of the progress, such as changing to wait cursor, changing the button color and text, updating a progress bar etc. Whatever I tried, the update only happens on completion of the On_Click procedure. I also tried to open a new Window. Still no success.

2.) Cannot open Window on Center Owner (DATAX is the WPF Window)

DATAX.WindowStartupLocation = WindowStartupLocation.CenterScreen does work

This does not work

DATAX.Owner = AddinModule.CurrentInstance.ExcelApp

DATAX.WindowStartupLocation = WindowStartupLocation.CenterOwner

Thank you for your support & kind regards

Michael
Posted 07 Apr, 2021 05:43:21 Top
Andrei Smolin


Add-in Express team


Posts: 18821
Joined: 2006-05-11
Hello Michael,

Since you process the cells on the main thread, you should show it on another thread to be able to update it on the fly. If you show it on the same thread, it will be able to update only after the operation stops. Another approach is to split the complete process so that it processes some cells, lets the UI thread (= the user) to do some tasks, process another chunk of cells, allows UI to work, process another chunk, etc.

Michael Kaden writes:
DATAX is the WPF Window


Visual Studio 2017 doesn't let me add a WPF Window to a Windows Desktop Class Library project (Add-in Express projects descend from it). I'm only allowed to add a WPF UserControl to the project. In this case I would show it on a Windows Forms form in an ElementHost control. Do I miss anything?


Andrei Smolin
Add-in Express Team Leader
Posted 07 Apr, 2021 06:33:28 Top
Michael Kaden


Guest


Hello Andrei

Thanks for the advice. I will try to put the data transfer from Excel to RAM into another thread. Unfortunately WPF does not have the Backgroundworker tool, so I will use Imports System.ComponentModel. Or would you rather use System.Threading.Tasks ?

I have installed the WPF Window in "New Items" following the

http://www.mobilemotion.eu/?p=1537


Do you see any problem in doing that? So far it works for me without any problem.

My question was that

XXX.WindowStartupLocation = WindowStartupLocation.CenterOwner

seems not to work with a WPF Windows, as far as I understand, the WPF does not recognise the owner? I found numerous postings where others have this problem also, but did not find a solution anywhere.

Thank you & kind regards

Michael
Posted 08 Apr, 2021 01:43:45 Top
Andrei Smolin


Add-in Express team


Posts: 18821
Joined: 2006-05-11
Hello Michael,

The approach that page suggests ignores the fact that Microsoft restricts doing this on purpose. Bypassing this restriction may be the cause of the issue.

A window in Windows is a complex thing with many obligations. I assume Microsoft doesn't except a WPF Window to be shown in your scenario.


Andrei Smolin
Add-in Express Team Leader
Posted 08 Apr, 2021 04:39:34 Top
Michael Kaden


Guest


Hello Andrei,

thank you for your prompt reply.

I tried the use of the WPF components via Element Host. It did not solve the

XXX.WindowStartupLocation = WindowStartupLocation.CenterOwner

problem, other then that I can set the hosting Frame to centerparent The description I found of how to use Host Element are very confusing, even on the Microsoft sites. Still I managed an example. However, I wanted to understand why the above (CenterOwner) does not work as WPF has the possibility of setting centerowner. As far as I can see a WPF component or Window does not recognize a NON-WPF-component (Window), such as an Excel Workbook as Parent (owner), I could however solve it in this way (DATAS is my WPF Window):


Dim DATAX As New DATAS
Dim Helper As New Interop.WindowInteropHelper(DATAX)
Helper.Owner = AddinModule.CurrentInstance.ExcelApp.Hwnd
DATAX.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner
DATAX.ShowDialog()


Do you see any problem with this, it seems to work perfect.

With regard to your comment about the non-availability of
NEW ITEM = WPF.WINDOW
in Visual Studio 2019. I did extensive Google research and found many many (100 +) posts also in the Microsoft forums etc. recommending either by renaming user control to window or changing the .csproj file. I however always take your advise seriously, so I continue searching for MS (official?) reasons not to have it as New Item in VS. I did not find even one post reporting problems or recommending not to do this.

On another point, I found quite a few posts where it is suggested that WPF is on its way out and might not be supported by MS in the near or middle term future? Do you know any information on this?

How does one get an official comment from Microsoft on the future of WPF and why only WPF user control and not WPF Window is available by default in Visual Studio?

I am very confused to judge if posts or forums are Microsoft endorsed. Such as this one:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/c09e0181-0926-4a36-bd7e-270d37a83e91/no-option-to-add-new-wpf-window?forum=wpf

Which has the "look and feel" of a Microsoft site, but I guess it is independent from MS??

Thank you very much for your continuous help and patience.

have a nice weekend & kind regards.

Michael
Posted 09 Apr, 2021 11:47:32 Top