Udostępnij przez


Rozwiązać problemy z DPI

Coraz większa liczba urządzeń jest wysyłana z ekranami o wysokiej rozdzielczości. Te ekrany zwykle mają ponad 200 pikseli na cal (ppi). Praca z aplikacją na tych komputerach wymaga skalowania zawartości w górę w celu zaspokojenia potrzeb wyświetlania zawartości na normalnym dystansie wyświetlania urządzenia. Od 2014 roku głównym celem wyświetlaczy o wysokiej gęstości są urządzenia mobilne (tablety, laptopy z klapką i telefony).

System Windows 8.1 lub nowszy zawiera kilka funkcji umożliwiających tym maszynom pracę z wyświetlaczami i środowiskami, w których maszyna jest podłączona zarówno do wyświetlaczy o wysokiej gęstości, jak i standardowej gęstości w tym samym czasie.

  • System Windows umożliwia skalowanie zawartości na urządzenie przy użyciu ustawienia "Ustaw tekst i inne elementy większe lub mniejsze" (dostępne od systemu Windows XP).

  • System Windows 8.1 lub nowszy automatycznie skaluje zawartość, aby większość aplikacji była spójna po przeniesieniu między wyświetlaczami o różnych gęstości pikseli. Gdy ekran podstawowy ma wysoką gęstość (200% skalowania), a pomocniczy ekran ma standardową gęstość (100%), system Windows automatycznie skaluje zawartość okna aplikacji w dół na ekranie pomocniczym (1 piksel wyświetlany dla każdego 4 pikseli renderowanego przez aplikację).

  • System Windows będzie domyślnie dostosowywał odpowiednie skalowanie w oparciu o gęstość pikseli i odległość oglądania dla wyświetlacza (w systemie Windows 7 i nowszych, konfigurowalny przez producenta OEM).

  • System Windows może automatycznie skalować zawartość do 250% na nowych urządzeniach, które przekraczają 280 ppi (od systemu Windows 8.1 S14).

    System Windows ma sposób radzenia sobie ze skalowaniem w górę interfejsu użytkownika, aby korzystać ze zwiększonej liczby pikseli. Aplikacja zgłasza zgodność z tym systemem, deklarując się jako "świadoma DPI systemu". Aplikacje, które tego nie robią, są automatycznie skalowane w górę przez system. Może to spowodować "rozmyte" doświadczenie użytkownika, w którym cała aplikacja jest równomiernie pikselowo rozciągnięta. Przykład:

    Problemy z dpi rozmyte

    Program Visual Studio decyduje się na uwzględnianie skalowania DPI i dlatego nie jest "zwirtualizowany".

    System Windows (i Program Visual Studio) korzystają z kilku technologii interfejsu użytkownika, które mają różne sposoby radzenia sobie z czynnikami skalowania ustawionymi przez system. Przykład:

  • WPF mierzy kontrolki w sposób niezależny od urządzenia (jednostki, a nie piksele). Interfejs użytkownika WPF automatycznie skaluje się w górę dla bieżącego dpi.

  • Wszystkie rozmiary tekstu niezależnie od struktury interfejsu użytkownika są wyrażane w punktach, dlatego są traktowane przez system jako niezależne od dpi. Tekst w systemach Win32, WinForms i WPF jest już poprawnie skalowany w górę podczas rysowania na urządzeniu wyświetlania.

  • Okna dialogowe i okna Win32/WinForms umożliwiają włączenie układu, który zmienia rozmiar tekstu (na przykład za pośrednictwem paneli siatki, przepływu i układu tabeli). Umożliwiają one uniknięcie zakodowanych w kodzie lokalizacji pikseli, które nie są skalowane, gdy rozmiary czcionek zostaną zwiększone.

  • Ikony udostępniane przez system lub zasoby na podstawie metryk systemu (na przykład SM_CXICON i SM_CXSMICON) są już skalowane w górę.

Starsze interfejsy użytkownika Win32 (GDI, GDI+) i WinForms

Chociaż WPF jest już wysoko dostosowany do DPI, większość naszego kodu opartego na Win32/GDI nie została pierwotnie napisana z myślą o świadomości DPI. System Windows oferuje interfejsy API do skalowania DPI. Poprawki problemów w Win32 powinny być używane spójnie w całym produkcie. Program Visual Studio udostępnił bibliotekę klas pomocnika, aby uniknąć duplikowania funkcji i zapewnienia spójności w całym produkcie.

Obrazy o wysokiej rozdzielczości

Ta sekcja dotyczy głównie deweloperów rozszerzających program Visual Studio 2013. W przypadku programu Visual Studio 2015 użyj usługi obrazów wbudowanej w program Visual Studio. Może się również okazać, że należy obsługiwać lub dostosowywać się do wielu wersji programu Visual Studio, dlatego korzystanie z usługi obrazów w 2015 r. nie jest opcją, ponieważ nie istnieje we wcześniejszych wersjach. Ta sekcja jest również dla Ciebie.

Powiększanie obrazów, które są zbyt małe

Obrazy, które są zbyt małe, można skalować w górę i renderować na GDI i WPF przy użyciu niektórych typowych metod. Zarządzane klasy pomocnika DPI są dostępne dla wewnętrznych i zewnętrznych integratorów programu Visual Studio do obsługi ikon skalowania, map bitowych, elementów imagestrip i list obrazów. Natywne pomocniki języka C/C++oparte na win32 są dostępne do skalowania HICON, HBITMAP, HIMAGELIST i VsUI::GdiplusImage. Skalowanie bitmapy zwykle wymaga tylko zmiany jednolinijkowej po włączeniu odwołania do biblioteki pomocniczej. Przykład:

(WinForms) DpiHelper.LogicalToDeviceUnits(ref image);

Skalowanie listy obrazów zależy od tego, czy lista obrazów jest ukończona w czasie ładowania, czy jest dołączana w czasie wykonywania. Jeśli zakończono podczas ładowania, wywołaj LogicalToDeviceUnits() z listą obrazów, tak jak mapę bitową. Gdy kod musi załadować pojedynczą mapę bitową przed utworzeniem listy obrazów, pamiętaj o skalowaniu rozmiaru obrazu listy obrazów:

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

W kodzie natywnym wymiary można skalować podczas tworzenia listy obrazów w następujący sposób:

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

Funkcje w bibliotece umożliwiają określanie algorytmu zmiany rozmiaru. Podczas skalowania obrazów do umieszczenia na listach obrazów, należy określić kolor tła wykorzystywany do przezroczystości albo użyć skalowania NearestNeighbor (co spowoduje zniekształcenia przy współczynnikach 125% i 150%).

Zapoznaj się z dokumentacją w witrynie DpiHelper MSDN.

W poniższej tabeli przedstawiono przykłady skalowania obrazów przy odpowiednich współczynnikach skalowania DPI. Obrazy przedstawione w kolorze pomarańczowym oznaczają najlepsze rozwiązanie dla programu Visual Studio 2013 (100%-200% skalowania DPI):

Problemy z ustawieniami DPI

Problemy z układem

Typowe problemy z układem można uniknąć przede wszystkim przez utrzymywanie punktów w interfejsie użytkownika skalowanych i względem siebie, a nie przy użyciu lokalizacji bezwzględnych (w szczególności w jednostkach pikseli). Przykład:

  • Pozycje układu/tekstu muszą być dostosowywane do uwzględnienia obrazów powiększonych.

  • Kolumny w siatkach muszą mieć szerokości dostosowane do tekstu skalowanego w górę.

  • Zakodowane rozmiary lub spacje między elementami również muszą zostać przeskalowane w górę. Rozmiary oparte tylko na wymiarach tekstu są zwykle poprawne, ponieważ czcionki są automatycznie skalowane w górę.

    Funkcje pomocnika są dostępne w DpiHelper klasie, aby umożliwić skalowanie na osi X i Y:

  • LogicalToDeviceUnitsX/LogicalToDeviceUnitsY (funkcje umożliwiają skalowanie na osi X/Y)

  • int space = DpiHelper.LogicalToDeviceUnitsX (10);

  • int height = VsUI::DpiHelper::LogicalToDeviceUnitsY(5);

    Istnieją przeciążenia funkcji LogicalToDeviceUnits, które pozwalają na skalowanie obiektów, takich jak Rect, Point i Size.

Skalowanie obrazów i układu za pomocą biblioteki DPIHelper/klasy

Biblioteka pomocnicza DPI programu Visual Studio jest dostępna w formach natywnych i zarządzanych i może być używana oprócz powłoki programu Visual Studio przez inne aplikacje.

Aby użyć biblioteki, przejdź do przykładów rozszerzalności zestawu VSSDK programu Visual Studio i sklonuj przykład High-DPI_Images_Icons.

W plikach źródłowych uwzględnij VsUIDpiHelper.h i wywołaj statyczne funkcje klasy VsUI::DpiHelper.

#include "VsUIDpiHelper.h"

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

Uwaga / Notatka

Nie używaj funkcji pomocnika w zmiennych statycznych na poziomie modułu ani na poziomie klasy. Biblioteka używa również statycznych danych do synchronizacji wątków i może wystąpić problemy z inicjowaniem kolejności. Przekonwertuj te zmienne statyczne na niestatyczne zmienne członkowskie lub zawij je w funkcję, aby były tworzone przy pierwszym dostępie.

Aby uzyskać dostęp do funkcji pomocnika DPI z poziomu kodu zarządzanego, który będzie uruchamiany w środowisku programu Visual Studio:

  • Projekt zużywany musi odwoływać się do najnowszej wersji programu Shell MPF. Przykład:

    <Reference Include="Microsoft.VisualStudio.Shell.14.0.dll" />
    
  • Upewnij się, że projekt zawiera odwołania do elementu System.Windows.Forms, PresentationCore i PresentationUI.

  • W kodzie użyj przestrzeni nazw Microsoft.VisualStudio.PlatformUI i wywołaj funkcje statyczne klasy DpiHelper. W przypadku obsługiwanych typów (punktów, rozmiarów, prostokątów itd.) dostępne są funkcje rozszerzenia, które zwracają nowe skalowane obiekty. Przykład:

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

Rozwiązywanie problemu rozmycia obrazu w WPF w powiększalnym interfejsie użytkownika

W WPF mapy bitowe są automatycznie zmieniane na aktualny poziom powiększenia DPI za pomocą wysokiej jakości algorytmu bicubic (wartość domyślna), co działa dobrze w przypadku zdjęć lub dużych zrzutów ekranu, ale nie nadaje się do ikon pozycji menu, ponieważ wprowadza postrzeganą nieostrość.

Rekomendacje:

  • W przypadku obrazu logo i grafiki banerów można użyć domyślnego BitmapScalingMode trybu zmiany rozmiaru.

  • W przypadku elementów menu i obrazów ikonografii, BitmapScalingMode powinno być używane, gdy nie powoduje zniekształcenia artefaktów w celu wyeliminowania rozmycia (przy 200% i 300%).

  • W przypadku dużych poziomów powiększenia niebędących wielokrotnością 100% (na przykład 250% lub 350%), skaluje się obrazy ikonografii metodą bikubikową, co skutkuje rozmytym, wypłowiałym interfejsem użytkownika. Lepszy wynik uzyskuje się, najpierw skalując obraz metodą Nearest Neighbor do największej wielokrotności 100% (na przykład 200% lub 300%), a następnie skalując metodą bicubic. Zobacz Specjalny przypadek: wstępne skalowanie obrazów WPF na potrzeby dużych poziomów DPI, aby uzyskać więcej informacji.

    Klasa DpiHelper w przestrzeni nazw Microsoft.VisualStudio.PlatformUI udostępnia element członkowski BitmapScalingMode , którego można użyć do powiązania. Dzięki niej powłoka programu Visual Studio będzie kontrolować tryb skalowania map bitowych w całym produkcie w jednolity sposób, w zależności od współczynnika skalowania DPI.

    Aby użyć go w języku XAML, dodaj:

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

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

Powłoka Visual Studio już ustawia tę właściwość w oknach najwyższego poziomu i oknach dialogowych. Interfejs użytkownika oparty na WPF działający w programie Visual Studio będzie go już dziedziczyć. Jeśli ustawienie nie jest propagowane do określonych fragmentów interfejsu użytkownika, można go ustawić na głównym elemenie interfejsu użytkownika XAML/WPF. Miejsca, w których tak się dzieje, obejmują wyskakujące okienka, elementy z nadrzędnymi elementami Win32 oraz okna projektanta, które działają poza procesem, takie jak Blend.

Niektóre interfejsy użytkownika mogą być skalowane niezależnie od ustawionego przez system poziomu skalowania DPI, takiego jak edytor tekstu programu Visual Studio i projektanci oparci na WPF (WPF Desktop i Windows Store). W takich przypadkach nie należy używać elementu DpiHelper.BitmapScalingMode. Aby rozwiązać ten problem w edytorze, zespół IDE utworzył właściwość niestandardową o nazwie RenderOptions.BitmapScalingMode. Ustaw wartość tej właściwości na "HighQuality" lub "NearestNeighbor", w zależności od połączonego poziomu powiększenia systemu oraz interfejsu użytkownika.

Przypadek specjalny: preskalowanie obrazów WPF na dużych poziomach DPI

W przypadku bardzo dużych poziomów powiększenia, które nie są wielokrotnościami 100% (na przykład 250%, 350%, itd.), skalowanie obrazów ikonografii przy użyciu metody bikubicznej skutkuje rozmytym i wypranym interfejsem użytkownika. Wrażenie tych obrazów obok ostrego tekstu jest prawie jak w przypadku iluzji optycznej. Obrazy wydają się być bliżej oka i są nieostre w odniesieniu do tekstu. Wynik skalowania w tym powiększonym rozmiarze można poprawić, najpierw skalując obraz metodą Nearest Neighbor do największej wielokrotności 100 % (na przykład 200 % lub 300 %), a następnie stosując metodę Bicubic na pozostałą wartość (dodatkowe 50 %).

Poniżej przedstawiono przykład różnic w wynikach, w których pierwszy obraz jest skalowany przy użyciu ulepszonego algorytmu podwójnego skalowania 100%->200%->250%, a drugi tylko z bicubic 100%->250%.

Problemy z podwójnym skalowaniem DPI — przykład

Aby umożliwić interfejsowi użytkownika korzystanie z tego podwójnego skalowania, należy zmodyfikować znaczniki XAML do wyświetlania każdego elementu Obrazu. W poniższych przykładach pokazano, jak używać podwójnego skalowania w WPF w programie Visual Studio przy użyciu biblioteki DpiHelper i shell.12/14.

Krok 1. Wstępne skalowanie obrazu do 200%, 300%itd. przy użyciu metody NearestNeighbor.

Wstępne skalowanie obrazu przy użyciu konwertera zastosowanego do powiązania lub rozszerzenia znaczników XAML. Przykład:

<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" />

Jeśli obraz również musi być stylizowany (większość, jeśli nie wszystkie, powinna), znaczniki mogą użyć innego konwertera, który najpierw stylizuje obraz, a następnie dokonuje przeskalowania. Znaczniki mogą używać wartości DpiPrescaleThemedImageConverter lub DpiPrescaleThemedImageSourceConverter, w zależności od żądanych danych wyjściowych konwersji.

<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>

Krok 2. Upewnij się, że ostateczny rozmiar jest poprawny dla bieżącego dpi.

Ponieważ WPF będzie skalować interfejs użytkownika dla bieżącego DPI, używając właściwości BitmapScalingMode ustawionej na UIElement, kontrolka Obraz wykorzystująca wstępnie skalowany obraz jako swoje źródło będzie wyglądać na dwa lub trzy razy większą niż powinna. Poniżej przedstawiono kilka sposobów przeciwdziałania temu efektowi:

  • Jeśli znasz wymiar oryginalnego obrazu na 100%, możesz określić dokładny rozmiar kontrolki Obraz. Te rozmiary odzwierciedlają rozmiar interfejsu użytkownika przed zastosowaniem skalowania.

    <Image Source="{Binding Path=SelectedImage, Converter={StaticResource DpiPrescaleImageSourceConverter}}" Width="16" Height="16" />
    
  • Jeśli rozmiar oryginalnego obrazu nie jest znany, można użyć elementu LayoutTransform do skalowania w dół końcowego obiektu Obrazu. Przykład:

    <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>
    

Włączanie obsługi interfejsu HDPI w usłudze WebOC

Domyślnie kontrolki WebOC (takie jak kontrolka WebBrowser w WPF lub interfejsie IWebBrowser2) nie obsługują wykrywania i obsługi interfejsu HDPI. Wynikiem będzie kontrolka osadzona z wyświetlaną zawartością, która jest zbyt mała na wyświetlaczu o wysokiej rozdzielczości. Poniżej opisano sposób włączania obsługi wysokiej rozdzielczości DPI w określonym wystąpieniu komponentu WebOC.

Zaimplementuj interfejs IDocHostUIHandler (zobacz artykuł MSDN na temat 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);
    }

Opcjonalnie zaimplementuj interfejs ICustomDoc (zobacz artykuł MSDN dotyczący ICustomDoc:

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

Skojarz klasę, która implementuje program IDocHostUIHandler z dokumentem protokołu WebOC. Jeśli zaimplementowano powyższy interfejs ICustomDoc, gdy tylko właściwość dokumentu składnika WebOC jest prawidłowa, rzutuj ją na obiekt ICustomDoc i wywołaj metodę SetUIHandler, przekazując klasę implementjącą program IDocHostUIHandler.

// "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);

Jeśli interfejs ICustomDoc nie został zaimplementowany, to gdy tylko właściwość dokumentu składnika WebOC będzie prawidłowa, musisz go rzutować jako IOleObject i wywołać metodę SetClientSite, przekazując klasę implementującą IDocHostUIHandler. Ustaw flagę DOCHOSTUIFLAG_DPI_AWARE na doCHOSTUIINFO przekazaną do wywołania GetHostInfo metody:

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;
}

Powinno to być wszystko, czego potrzebujesz, aby Twoja kontrolka WebOC obsługiwała HPDI.

Wskazówki

  1. Jeśli właściwość dokumentu w kontrolce WebOC ulegnie zmianie, może być konieczne ponowne skojarzenie dokumentu z klasą IDocHostUIHandler.

  2. Jeśli powyższe nie działa, istnieje znany problem z tym, że WebOC nie rozpoznaje zmiany ustawienia flagi DPI. Najbardziej niezawodnym sposobem naprawienia tego jest przełączanie optycznego powiększenia WebOC, co oznacza wykonanie dwóch wywołań z różnymi wartościami procentowymi powiększenia. Ponadto, jeśli to obejście jest wymagane, może być konieczne wykonanie go przy każdym wywołaniu funkcji nawigacji.

    // 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);
    }