Share via


Beheben von DPI-Problemen

Eine zunehmende Anzahl von Geräten wird mit "hochauflösenden" Bildschirmen bereitgestellt. Diese Bildschirme haben in der Regel mehr als 200 Pixel pro Zoll (ppi). Wenn Sie mit einer Anwendung auf diesen Computern arbeiten, müssen Inhalte skaliert werden, um die Anforderungen des Anzeigens des Inhalts in einer normalen Anzeigeabstand für das Gerät zu erfüllen. Ab 2014 ist das primäre Ziel für Displays mit hoher Dichte mobile Computergeräte (Tablets, Clamshell-Laptops und Smartphones).

Windows 8.1 und höher enthält mehrere Features, mit denen diese Computer gleichzeitig mit Displays und Umgebungen arbeiten können, in denen der Computer sowohl mit hoher Dichte als auch mit Standarddichteanzeigen verbunden ist.

  • Mit Windows können Sie Inhalte auf das Gerät skalieren, indem Sie die Einstellung "Text und andere Elemente vergrößern oder verkleinern" (seit Windows XP verfügbar) verwenden.

  • Windows 8.1 und höher skalieren automatisch Inhalte, damit die meisten Anwendungen konsistent sind, wenn zwischen anzeige unterschiedlichen Pixeldichten verschoben wird. Wenn die primäre Anzeige eine hohe Dichte (Skalierung von 200 %) aufweist und die sekundäre Anzeige die Standarddichte (100 %) aufweist, skaliert Windows automatisch den Inhalt des Anwendungsfensters auf der sekundären Anzeige nach unten (1 Pixel, die für alle 4 Pixel von der Anwendung gerendert werden).

  • Windows verwendet standardmäßig die richtige Skalierung für die Pixeldichte und den Anzeigeabstand für die Anzeige (Windows 7 und höher, OEM-konfigurierbar).

  • Windows kann Inhalte auf neuen Geräten, die 280 ppi überschreiten, automatisch auf bis zu 250 % skalieren (ab Windows 8.1 S14).

    Windows hat eine Möglichkeit, die Benutzeroberfläche zu skalieren, um die Vorteile erhöhter Pixelanzahl zu nutzen. Eine Anwendung entscheidet sich für dieses System, indem sie sich selbst als "System-DPI-fähig" deklariert. Anwendungen, die dies nicht tun, werden vom System skaliert. Dies kann zu einer "Fuzzy"-Benutzeroberfläche führen, bei der die gesamte Anwendung einheitlich pixeldehnungiert ist. Beispiel:

    DPI Issues Fuzzy

    Visual Studio entscheidet sich für die DPI-Skalierung und ist daher nicht "virtualisiert".

    Windows (und Visual Studio) nutzen mehrere UI-Technologien, die unterschiedliche Möglichkeiten zum Umgang mit skalierungsfaktoren haben, die vom System festgelegt wurden. Beispiel:

  • WPF misst Steuerelemente auf geräteunabhängige Weise (Einheiten, keine Pixel). Die WPF-Benutzeroberfläche wird automatisch für den aktuellen DPI-Wert skaliert.

  • Alle Textgrößen, unabhängig vom UI-Framework, werden in Punkt ausgedrückt und daher vom System als DPI-unabhängig behandelt. Text in Win32, WinForms und WPF wird beim Zeichnen auf dem Anzeigegerät bereits ordnungsgemäß skaliert.

  • Win32/WinForms-Dialogfelder und -Fenster haben Mittel zum Aktivieren des Layouts, das die Größe mit Text ändert (z. B. durch Raster-, Fluss- und Tabellenlayoutbereiche). Dadurch werden hartcodierte Pixelpositionen vermieden, die nicht skaliert werden, wenn die Schriftgrade erhöht werden.

  • Symbole, die vom System oder von Ressourcen basierend auf Systemmetriken (z. B. SM_CXICON und SM_CXSMICON) bereitgestellt werden, werden bereits skaliert.

Ältere Win32 (GDI, GDI+) und WinForms-basierte UI

Während WPF bereits sehr dpi-fähig ist, wurde ein Großteil unseres Win32/GDI-basierten Codes ursprünglich nicht mit DPI-Bewusstsein geschrieben. Windows hat APIs zur DPI-Skalierung bereitgestellt. Korrekturen für Win32-Probleme sollten diese konsistent im gesamten Produkt verwenden. Visual Studio hat eine Hilfsklassenbibliothek bereitgestellt, um die Duplizierung von Funktionen zu vermeiden und die Konsistenz für das gesamte Produkt sicherzustellen.

Hochauflösende Bilder

Dieser Abschnitt richtet sich in erster Linie an Entwickler, die Visual Studio 2013 erweitern. Verwenden Sie für Visual Studio 2015 einen Bilddienst, der in Visual Studio integriert ist. Möglicherweise stellen Sie auch fest, dass Sie viele Versionen von Visual Studio unterstützen/als Ziel verwenden müssen und daher die Verwendung des Bilddiensts in 2015 keine Option ist, da sie in früheren Versionen nicht vorhanden ist. Dieser Abschnitt ist auch für Sie vorgesehen.

Hochskalieren von Bildern, die zu klein sind

Bilder, die zu klein sind, können mithilfe einiger gängiger Methoden auf GDI und WPF skaliert und gerendert werden. Verwaltete DPI-Hilfsklassen sind für interne und externe Visual Studio-Integratoren verfügbar, um Skalierungssymbole, Bitmaps, Bildertrips und Bildlisten zu adressieren. Win32-basierte native C/C++-Hilfsprogramme sind für die Skalierung von HICON, HBITMAP, HIMAGELIST und VsUI::GdiplusImage verfügbar. Für die Skalierung einer Bitmap ist in der Regel nur eine einzeilige Änderung erforderlich, nachdem ein Verweis auf die Hilfsbibliothek eingeschlossen wurde. Beispiel:

(WinForms) DpiHelper.LogicalToDeviceUnits(ref image);

Die Skalierung einer Bildliste hängt davon ab, ob die Bildliste zum Ladezeitpunkt abgeschlossen ist oder zur Laufzeit angefügt wird. Wenn sie zum Ladezeitpunkt abgeschlossen ist, rufen Sie LogicalToDeviceUnits() die Bildliste wie eine Bitmap auf. Wenn der Code vor dem Verfassen der Bildliste eine einzelne Bitmap laden muss, müssen Sie die Bildgröße der Bildliste skalieren:

imagelist.ImageSize = DpiHelper.LogicalToDeviceUnits(imagelist.ImageSize);

Im systemeigenen Code können die Dimensionen beim Erstellen der Bildliste wie folgt skaliert werden:

ImageList_Create(VsUI::DpiHelper::LogicalToDeviceUnitsX(16),VsUI::DpiHelper::LogicalToDeviceUnitsY(16), ILC_COLOR32|ILC_MASK, nCount, 1);

Funktionen in der Bibliothek ermöglichen das Angeben des Größenänderungsalgorithmus. Achten Sie beim Skalieren von Bildern, die in Bildlisten platziert werden sollen, unbedingt die Hintergrundfarbe an, die für Transparenz verwendet wird, oder verwenden Sie die NearestNeighbor-Skalierung (was zu Verzerrungen bei 125 % und 150 %).

Weitere Informationen finden Sie in der DpiHelper Dokumentation auf MSDN.

Die folgende Tabelle zeigt Beispiele dafür, wie Bilder bei entsprechenden DPI-Skalierungsfaktoren skaliert werden sollen. Die in Orange dargestellten Bilder bezeichnen unsere bewährte Methode ab Visual Studio 2013 (100%-200%-200%-DPI-Skalierung):

DPI Issues Scaling

Layoutprobleme

Häufige Layoutprobleme können in erster Linie vermieden werden, indem Punkte auf der Benutzeroberfläche skaliert und relativ zueinander gehalten werden, anstatt absolute Positionen (insbesondere in Pixeleinheiten) zu verwenden. Beispiel:

  • Layout-/Textpositionen müssen angepasst werden, um skalierte Bilder zu berücksichtigen.

  • Spalten in Rastern müssen für den skalierten Text angepasst werden.

  • Hartcodierte Größen oder Abstände zwischen Elementen müssen ebenfalls skaliert werden. Größen, die nur auf Textabmessungen basieren, sind in der Regel in Ordnung, da Schriftarten automatisch skaliert werden.

    Hilfsfunktionen sind in der DpiHelper Klasse verfügbar, um die Skalierung auf der X- und Y-Achse zu ermöglichen:

  • LogicalToDeviceUnitsX/LogicalToDeviceUnitsY (Funktionen ermöglichen skalierung auf der X/Y-Achse)

  • int space = DpiHelper.LogicalToDeviceUnitsX (10);

  • int height = VsUI::D piHelper::LogicalToDeviceUnitsY(5);

    Es gibt LogicalToDeviceUnits-Überladungen, um skalierungsfähige Objekte wie Rect, Point und Size zu ermöglichen.

Verwenden der DPIHelper-Bibliothek/-Klasse zum Skalieren von Bildern und Layouts

Die Visual Studio DPI-Hilfsbibliothek ist in systemeigenen und verwalteten Formularen verfügbar und kann außerhalb der Visual Studio-Shell von anderen Anwendungen verwendet werden.

Um die Bibliothek zu verwenden, wechseln Sie zu den Visual Studio VSSDK-Erweiterbarkeitsbeispielen , und klonen Sie das High-DPI_Images_Icons-Beispiel.

Fügen Sie in Quelldateien VsUIDpiHelper.h hinzu, und rufen Sie die statischen Funktionen der VsUI::DpiHelper Klasse auf:

#include "VsUIDpiHelper.h"

int cxScaled = VsUI::DpiHelper::LogicalToDeviceUnitsX(cx);
VsUI::DpiHelper::LogicalToDeviceUnits(&hBitmap);

Hinweis

Verwenden Sie die Hilfsfunktionen nicht in statischen Variablen auf Modul- oder Klassenebene. Die Bibliothek verwendet auch Statische für die Threadsynchronisierung, und Möglicherweise treten Probleme bei der Order-Initialisierung auf. Konvertieren Sie diese Statik entweder in nicht statische Membervariablen, oder umschließen Sie sie in eine Funktion (sodass sie auf dem ersten Zugriff erstellt werden).

So greifen Sie über verwalteten Code auf die DPI-Hilfsfunktionen zu, die in der Visual Studio-Umgebung ausgeführt werden:

  • Das verbrauchende Projekt muss auf die neueste Version von Shell MPF verweisen. Beispiel:

    <Reference Include="Microsoft.VisualStudio.Shell.14.0.dll" />
    
  • Stellen Sie sicher, dass das Projekt Verweise auf System.Windows.Forms, PresentationCore und PresentationUI hat.

  • Verwenden Sie im Code den Microsoft.VisualStudio.PlatformUI-Namespace , und rufen Sie statische Funktionen der DpiHelper-Klasse auf. Für unterstützte Typen (Punkte, Größen, Rechtecke usw.) gibt es Erweiterungsfunktionen, die neue skalierte Objekte zurückgeben. Beispiel:

    using Microsoft.VisualStudio.PlatformUI;
    double x = DpiHelper.LogicalToDeviceUnitsX(posX);
    Point ptScaled = ptOriginal.LogicalToDeviceUnits();
    DpiHelper.LogicalToDeviceUnits(ref bitmap);
    
    

Umgang mit WPF-Bildfuzzsigkeit in zoombarer UI

In WPF werden Bitmaps automatisch von WPF für den aktuellen DPI-Zoomfaktor mit einem qualitativ hochwertigen bicubischen Algorithmus (Standard) geändert, der gut für Bilder oder große Screenshots geeignet ist, aber für Menüelementsymbole ungeeignet ist, da sie wahrgenommene Fuzzlichkeit einführt.

Empfehlungen:

  • Für Logobilder und Bannergrafiken kann der Standardmodus BitmapScalingMode zum Ändern der Größe verwendet werden.

  • Bei Menüelementen und Symbolografiebildern sollte dies BitmapScalingMode verwendet werden, wenn sie keine anderen Verzerrungsartefakte verursacht, um Fuzzigkeit (bei 200 % und 300 %) zu beseitigen.

  • Bei großen Zoomstufen, die nicht mit 100 % (z. B. 250 % oder 350 %), führt die Skalierung von Symbolografiebildern mit bicubischen Ergebnissen zu fuzzy, ausgewaschener UI. Ein besseres Ergebnis wird erzielt, indem zuerst das Bild mit NearestNeighbor auf das größte Vielfache von 100 % (z. B. 200 % oder 300 %) skaliert und mit Bicubic von dort skaliert wird. Weitere Informationen finden Sie unter Sonderfall: Vorabskalieren von WPF-Bildern für große DPI-Ebenen.

    Die DpiHelper-Klasse im Microsoft.VisualStudio.PlatformUI-Namespace stellt ein Element BitmapScalingMode bereit, das für die Bindung verwendet werden kann. Es ermöglicht der Visual Studio-Shell, den Bitmapskalierungsmodus für das Produkt einheitlich zu steuern, abhängig vom DPI-Skalierungsfaktor.

    Um sie in XAML zu verwenden, fügen Sie Folgendes hinzu:

xmlns:vsui="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.14.0"

<Setter Property="RenderOptions.BitmapScalingMode" Value="{x:Static vs:DpiHelper.BitmapScalingMode}" />

Die Visual Studio-Shell legt diese Eigenschaft bereits in Fenstern und Dialogfeldern der obersten Ebene fest. WPF-basierte Ui, die in Visual Studio ausgeführt wird, erben sie bereits. Wenn die Einstellung nicht an bestimmte Ui-Elemente weitergegeben wird, kann sie für das Stammelement der XAML/WPF-Benutzeroberfläche festgelegt werden. Orte, an denen dies geschieht, sind Popups, elemente mit Win32-Eltern und Designerfenstern, die nicht mehr verarbeitet werden, z. B. Blend.

Einige Ui-Elemente können unabhängig vom vom System festgelegten DPI-Zoomfaktor skaliert werden, z. B. der Visual Studio-Text-Editor und WPF-basierte Designer (WPF Desktop und Windows Store). In diesen Fällen sollte DpiHelper.BitmapScalingMode nicht verwendet werden. Um dieses Problem im Editor zu beheben, hat das IDE-Team eine benutzerdefinierte Eigenschaft mit dem Titel RenderOptions.BitmapScalingMode erstellt. Legen Sie diesen Eigenschaftswert je nach kombinierter Zoomstufe des Systems und der Benutzeroberfläche auf HighQuality oder NearestNeighbor fest.

Sonderfall: Vorabkalieren von WPF-Bildern für große DPI-Ebenen

Bei sehr großen Zoomstufen, die nicht Vielfache von 100 % (z. B. 250 %, 350 % usw.) sind, führt die Skalierung von Symbolografiebildern mit bicubischen Ergebnissen zu fuzzy, ausgewaschener UI. Der Eindruck dieser Bilder neben scharfem Text ähnelt fast der optischen Illusion. Die Bilder scheinen näher am Auge zu sein und im Verhältnis zum Text nicht mehr im Fokus zu stehen. Das Skalierungsergebnis bei dieser vergrößerten Größe kann verbessert werden, indem zuerst das Bild mit NearestNeighbor auf das größte Vielfache von 100 % (z. B. 200 % oder 300 %) skaliert und mit Bicubic auf den Re Standard der skaliert wird (zusätzliche 50 %).

Im Folgenden sehen Sie ein Beispiel für die Unterschiede bei den Ergebnissen, bei denen das erste Bild mit dem verbesserten Doppelskalierungsalgorithmus 100%-200%->>250% skaliert wird, und der zweite mit bicubischen 100%->250%.

DPI Issues Double Scaling Example

Damit die Benutzeroberfläche dieses Doppelskalierung verwenden kann, muss das XAML-Markup zum Anzeigen jedes Bildelements geändert werden. Die folgenden Beispiele veranschaulichen die Verwendung der doppelten Skalierung in WPF in Visual Studio mithilfe der DpiHelper-Bibliothek und shell.12/14.

Schritt 1: Prescale the image to 200%, 300% and so on using NearestNeighbor.

Prescale the image using a converter applied on a binding, or with a XAML markup extension. Beispiel:

<vsui:DpiPrescaleImageSourceConverter x:Key="DpiPrescaleImageSourceConverter" />

<Image Source="{Binding Path=SelectedImage, Converter={StaticResource DpiPrescaleImageSourceConverter}}" Width="16" Height="16" />

<Image Source="{vsui:DpiPrescaledImage Images/Help.png}" Width="16" Height="16" />

Wenn das Bild auch designiert werden muss (sofern nicht alle, sollte), kann das Markup einen anderen Konverter verwenden, der zuerst das Design des Bilds durchführt und dann vorab skaliert wird. Das Markup kann abhängig von der gewünschten Konvertierungsausgabe entweder DpiPrescaleThemedImageConverter oder DpiPrescaleThemedImageSourceConverterverwendet werden.

<vsui:DpiPrescaleThemedImageSourceConverter x:Key="DpiPrescaleThemedImageSourceConverter" />

<Image Width="16" Height="16">
  <Image.Source>
    <MultiBinding Converter="{StaticResource DpiPrescaleThemedImageSourceConverter}">
      <Binding Path="Icon" />
      <Binding Path="(vsui:ImageThemingUtilities.ImageBackgroundColor)"
               RelativeSource="{RelativeSource Self}" />
      <Binding Source="{x:Static vsui:Boxes.BooleanTrue}" />
    </MultiBinding>
  </Image.Source>
</Image>

Schritt 2: Stellen Sie sicher, dass die endgültige Größe für den aktuellen DPI-Wert korrekt ist.

Da WPF die Benutzeroberfläche für den aktuellen DPI-Wert skaliert, indem die BitmapScalingMode-Eigenschaft für das UIElement festgelegt wird, sieht ein Bildsteuerelement, das ein vorskaliertes Bild verwendet, da die Quelle zwei- oder dreimal größer aussieht als es sollte. Im Folgenden finden Sie einige Möglichkeiten, um diesen Effekt zu bekämpfen:

  • Wenn Sie die Dimension des originalen Bilds mit 100 % kennen, können Sie die genaue Größe des Bildsteuerelements angeben. Diese Größen spiegeln die Größe der Benutzeroberfläche wider, bevor die Skalierung angewendet wird.

    <Image Source="{Binding Path=SelectedImage, Converter={StaticResource DpiPrescaleImageSourceConverter}}" Width="16" Height="16" />
    
  • Wenn die Größe des ursprünglichen Bilds nicht bekannt ist, kann ein LayoutTransform verwendet werden, um das endgültige Image-Objekt nach unten zu skalieren. Beispiel:

    <Image Source="{Binding Path=SelectedImage, Converter={StaticResource DpiPrescaleImageSourceConverter}}" >
        <Image.LayoutTransform>
            <ScaleTransform
                ScaleX="{x:Static vsui:DpiHelper.PreScaledImageLayoutTransformScale}"
                ScaleY="{x:Static vsui:DpiHelper.PreScaledImageLayoutTransformScale}" />
        </Image.LayoutTransform>
    </Image>
    

Aktivieren der HDPI-Unterstützung für webOC

Standardmäßig aktivieren WebOC-Steuerelemente (z. B. das WebBrowser-Steuerelement in WPF oder die IWebBrowser2-Schnittstelle) keine HDPI-Erkennung und -Unterstützung. Das Ergebnis ist ein eingebettetes Steuerelement mit Anzeigeinhalten, die auf einer hochauflösenden Anzeige zu klein sind. Im Folgenden wird beschrieben, wie Sie die Unterstützung mit hohem DPI-Wert in einer bestimmten WebOC-Instanz aktivieren.

Implementieren der IDocHostUIHandler-Schnittstelle (siehe MSDN-Artikel zum IDocHostUIHandler:

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
 Guid("BD3F23C0-D43E-11CF-893B-00AA00BDCE1A")]
public interface IDocHostUIHandler
{
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int ShowContextMenu(
        [In, MarshalAs(UnmanagedType.U4)] int dwID,
        [In] POINT pt,
        [In, MarshalAs(UnmanagedType.Interface)] object pcmdtReserved,
        [In, MarshalAs(UnmanagedType.IDispatch)] object pdispReserved);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int GetHostInfo([In, Out] DOCHOSTUIINFO info);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int ShowUI(
        [In, MarshalAs(UnmanagedType.I4)] int dwID,
        [In, MarshalAs(UnmanagedType.Interface)] object activeObject,
        [In, MarshalAs(UnmanagedType.Interface)] object commandTarget,
        [In, MarshalAs(UnmanagedType.Interface)] object frame,
        [In, MarshalAs(UnmanagedType.Interface)] object doc);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int HideUI();
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int UpdateUI();
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int EnableModeless([In, MarshalAs(UnmanagedType.Bool)] bool fEnable);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int OnDocWindowActivate([In, MarshalAs(UnmanagedType.Bool)] bool fActivate);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int OnFrameWindowActivate([In, MarshalAs(UnmanagedType.Bool)] bool fActivate);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int ResizeBorder(
        [In] COMRECT rect,
        [In, MarshalAs(UnmanagedType.Interface)] object doc,
        bool fFrameWindow);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int TranslateAccelerator(
        [In] ref MSG msg,
        [In] ref Guid group,
        [In, MarshalAs(UnmanagedType.I4)] int nCmdID);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int GetOptionKeyPath(
        [Out, MarshalAs(UnmanagedType.LPArray)] string[] pbstrKey,
        [In, MarshalAs(UnmanagedType.U4)] int dw);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int GetDropTarget(
        [In, MarshalAs(UnmanagedType.Interface)] IOleDropTarget pDropTarget,
        [MarshalAs(UnmanagedType.Interface)] out IOleDropTarget ppDropTarget);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int GetExternal([MarshalAs(UnmanagedType.IDispatch)] out object ppDispatch);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int TranslateUrl(
        [In, MarshalAs(UnmanagedType.U4)] int dwTranslate,
        [In, MarshalAs(UnmanagedType.LPWStr)] string strURLIn,
        [MarshalAs(UnmanagedType.LPWStr)] out string pstrURLOut);
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int FilterDataObject(
        IDataObject pDO,
        out IDataObject ppDORet);
    }

Implementieren Sie optional die ICustomDoc-Schnittstelle (siehe MSDN-Artikel zum ICustomDoc:

[InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
 Guid("3050F3F0-98B5-11CF-BB82-00AA00BDCE0B")]
public interface ICustomDoc
{
    void SetUIHandler(IDocHostUIHandler pUIHandler);
}

Ordnen Sie die Klasse, die IDocHostUIHandler implementiert, dem Dokument des WebOC zu. Wenn Sie die oben genannte ICustomDoc-Schnittstelle implementiert haben, wandeln Sie sie, sobald die Dokumenteigenschaft des WebOC gültig ist, in einen ICustomDoc um, und rufen Sie die SetUIHandler-Methode auf, und übergeben Sie die Klasse, die IDocHostUIHandler implementiert.

// "this" references that class that owns the WebOC control and in this case also implements the IDocHostUIHandler interface
ICustomDoc customDoc = (ICustomDoc)webBrowser.Document;
customDoc.SetUIHandler(this);

Wenn Sie die ICustomDoc-Schnittstelle NICHT implementiert haben, müssen Sie sie in ein IOleObject umwandeln und die SetClientSite Methode übergeben, die IDocHostUIHandler implementiert, sobald die Dokumenteigenschaft des WebOC gültig ist. Legen Sie das DOCHOSTUIFLAG_DPI_AWARE Flag für das DOCHOSTUIINFO-Attribut fest, das an den GetHostInfo Methodenaufruf übergeben wird:

public int GetHostInfo(DOCHOSTUIINFO info)
{
    // This is what the default site provides.
    info.dwFlags = (DOCHOSTUIFLAG)0x5a74012;
    // Add the DPI flag to the defaults
    info.dwFlags |=.DOCHOSTUIFLAG.DOCHOSTUIFLAG_DPI_AWARE;
    return S_OK;
}

Dies sollte alles sein, was Sie benötigen, um Ihr WebOC-Steuerelement zur Unterstützung von HPDI zu erhalten.

Tipps

  1. Wenn sich die Dokumenteigenschaft des WebOC-Steuerelements ändert, müssen Sie das Dokument möglicherweise erneut der IDocHostUIHandler-Klasse zuordnen.

  2. Wenn die oben beschriebene Funktion nicht funktioniert, gibt es ein bekanntes Problem mit dem WebOC, das die Änderung an der DPI-Kennzeichnung nicht aufnimmt. Die zuverlässigste Möglichkeit, dies zu beheben, besteht darin, den optischen Zoom des WebOC umzuschalten, was bedeutet, dass zwei Aufrufe mit zwei verschiedenen Werten für den Zoomprozentsatz verwendet werden. Wenn diese Problemumgehung erforderlich ist, kann es für jeden Navigationsanruf erforderlich sein.

    // browser2 is a SHDocVw.IWebBrowser2 in this case
    // EX: Call the Exec twice with DPI%-1 and then DPI% as the zoomPercent values
    IOleCommandTarget cmdTarget = browser2.Document as IOleCommandTarget;
    if (cmdTarget != null)
    {
        object commandInput = zoomPercent;
        cmdTarget.Exec(IntPtr.Zero,
                       OLECMDID_OPTICAL_ZOOM,
                       OLECMDEXECOPT_DONTPROMPTUSER,
                       ref commandInput,
                       ref commandOutput);
    }