Andrei Smolin

Add-in Express version 9 adds support for multiple monitors in Office

Add-in Express 9 supports a recent change in Office 2016: support of multiple monitors having different DPI settings.

This story started with Windows 10 Fall Creators Update that allowed using different DPIs on different monitors. As said on this page at support.office.com, starting from version 1803, Word, PowerPoint and Visio support multiple monitors having different DPI settings. According to that page, other Office applications will support multiple DPIs in Spring 2018. That’s all. No more official Office-related information is available.

How does the above affect Office extensions? Not affected are non-UI extensions such as Excel UDFs and RTD servers. Affected are COM add-ins that show 1) panes/forms and 2) icons in the Ribbon UI.

What happens if you don’t react to this change? The previous Add-in Express versions are DPI unaware and the panes/forms they create are bitmap-stretched by Windows. Such a stretch makes your form/pane/Ribbon icons blurry. To see how this looks, drag an Office window showing your add-in’s UI to another monitor.

To avoid bitmap-stretching, you need to get notified about the DPI change and update the UI of your form/pane: resize the form/pane and controls on it, use a different font size, different images (optional) and the form icon.

To do this, you handle the ADXDPIChanged event available on Add-in Express task panes and forms starting from Add-in Express version 9.

This event is raised when the host application has reacted to a DPI change and now it’s your turn to update the UI of your pane. A trivial variant of updating your controls when reacting to a DPI change is the method shown below; you call this method from the ADXDPIChanged event as demonstrated in the code of the sample add-in:

C#

private void UpdateDPI(Control root, int dpi, float dpiFactor)
{
    foreach (Control cl in root.Controls)
    {
        cl.Bounds = Rectangle.Round(new RectangleF(cl.Left * dpiFactor, cl.Top * dpiFactor, cl.Width * dpiFactor, cl.Height * dpiFactor));
        if (cl.Controls.Count > 0)
            UpdateDPI(cl, dpi, dpiFactor);
        cl.Font = new Font(cl.Font.FontFamily, cl.Font.Size * dpiFactor, cl.Font.Unit);
    }
}

VB.NET

Private Sub UpdateDPI(ByVal root As Control, ByVal dpi As Integer, ByVal dpiFactor As Single)
    For Each cl As Control In root.Controls
        cl.Bounds = Rectangle.Round(New RectangleF(cl.Left * dpiFactor, cl.Top * dpiFactor, cl.Width * dpiFactor, cl.Height * dpiFactor))
        If cl.Controls.Count > 0 Then UpdateDPI(cl, dpi, dpiFactor)
        cl.Font = New Font(cl.Font.FontFamily, cl.Font.Size * dpiFactor, cl.Font.Unit)
    Next
End Sub

Your variant of this method will consider the actual controls used on your forms. Say, you may apply different images/controls or update your controls in a complex way to conform with the current DPI.

You may also want to get some controls hidden when you update them to minimize visual artefacts. You use the ADXBeforeDPIChanged event to hide these controls. In this case, in the code of the ADXDPIChanged event, you make the controls visible again after you update them.

Finally, about icons that you use on your Ribbon controls. If you use a multiple-image icon on your Ribbon control specifying the icon in the Glyph property of the control, Add-in Express 9 retrieves the best suited image when responding to a DPI change.

Below are two screenshots showing the same Add-in Express-based add-in in Excel 2016. Please notice the difference between the images: the controls are updated using the UpdateDPI() method above and the icon in the Ribbon is retrieved from the multi-image .ICO specified in the Glyph property of the Ribbon button. The information shown on the pane is updated using a separate method not shown above; see the sample project.

Good luck!

Add-in Express based add-in on 100% DPI

Add-in Express based add-in on 200% DPI

Post a comment

Have any questions? Ask us right now!