Aracılığıyla paylaş


DPI sorunlarını giderme

Artan sayıda cihaz "yüksek çözünürlüklü" ekranlarla gönderiliyor. Bu ekranlar genellikle inç başına 200 pikselden (ppi) fazladır. Bu bilgisayarlardaki bir uygulamayla çalışmak, içeriğin cihaz için normal görüntüleme uzaklığında görüntüleme gereksinimlerini karşılamak için içeriğin ölçeğinin büyütülmesi gerekir. 2014 itibarıyla, yüksek yoğunluklu ekranlar için birincil hedef mobil bilgi işlem cihazlarıdır (tabletler, clamshell dizüstü bilgisayarlar ve telefonlar).

Windows 8.1 ve üzeri, bu makinelerin hem yüksek yoğunluklu hem de standart yoğunluklu ekranlara aynı anda bağlı olduğu ekranlar ve ortamlarla çalışmasını sağlayan çeşitli özellikler içerir.

  • Windows, "Metni ve diğer öğeleri daha büyük veya daha küçük yap" ayarını (Windows XP'den itibaren kullanılabilir) kullanarak içeriği cihaza ölçeklendirmenize olanak sağlayabilir.

  • Windows 8.1 ve üzeri, farklı piksel yoğunluklarının ekranları arasında taşındığında çoğu uygulamanın tutarlı olması için içeriği otomatik olarak ölçeklendirir. Birincil ekran yüksek yoğunluklu (%200 ölçeklendirme) ve ikincil ekran standart yoğunluk (%100) olduğunda, Windows uygulama penceresinin içeriğini ikincil ekranda (uygulama tarafından işlenen her 4 piksel için 1 piksel) otomatik olarak ölçeklendirir.

  • Windows, ekran için piksel yoğunluğu ve görüntüleme uzaklığı için varsayılan olarak doğru ölçeklendirmeyi kullanır (Windows 7 ve üzeri, OEM tarafından yapılandırılabilir).

  • Windows, 280 ppi'yi (Windows 8.1 S14 itibarıyla) aşan yeni cihazlarda içeriği otomatik olarak %250'ye kadar ölçeklendirebilir.

    Windows' un artan piksel sayılarından yararlanmak için kullanıcı arabirimini ölçeklendirmeyle ilgilenmenin bir yolu vardır. Bir uygulama kendisini "sistem DPI'sını algılayan" olarak bildirerek bu sisteme katılmayı kabul eder. Bunu yapmayan uygulamaların ölçeği sistem tarafından artırılır. Bu, uygulamanın tamamının düzgün şekilde piksel esnetildiği "belirsiz" bir kullanıcı deneyimine neden olabilir. Örneğin:

    DPI Issues Fuzzy

    Visual Studio, DPI ölçeklendirmeye duyarlı olmayı tercih eder ve bu nedenle "sanallaştırılmış" değildir.

    Windows (ve Visual Studio), sistem tarafından ayarlanan ölçeklendirme faktörleriyle başa çıkmanın farklı yolları olan çeşitli kullanıcı arabirimi teknolojilerinden yararlanıyor. Örneğin:

  • WPF denetimleri cihazdan bağımsız bir şekilde ölçer (piksel değil birimler). WPF kullanıcı arabirimi geçerli DPI için otomatik olarak ölçeklendirilir.

  • UI çerçevesi ne olursa olsun tüm metin boyutları nokta cinsinden ifade edilir ve bu nedenle sistem tarafından DPI'lerden bağımsız olarak kabul edilir. Win32, WinForms ve WPF'deki metinler görüntü cihazına çizildiğinde zaten doğru şekilde ölçeklendirilir.

  • Win32/WinForms iletişim kutuları ve pencereleri metinle yeniden boyutlandıran düzeni etkinleştirmek için araçlara sahiptir (örneğin, kılavuz, akış ve tablo düzeni panelleri aracılığıyla). Bunlar, yazı tipi boyutları artırıldığında ölçeklendirilmeyen sabit kodlanmış piksel konumlarından kaçınmaya olanak tanır.

  • Sistem ölçümlerine (örneğin, SM_CXICON ve SM_CXSMICON) göre sistem veya kaynaklar tarafından sağlanan simgeler zaten ölçeklendirildi.

Eski Win32 (GDI, GDI+) ve WinForms tabanlı kullanıcı arabirimi

WPF zaten yüksek DPI duyarlı olsa da, Win32/GDI tabanlı kodumuzun çoğu başlangıçta DPI farkındalığı göz önünde bulundurularak yazılmamıştı. Windows DPI ölçeklendirme API'leri sağlamıştır. Win32 sorunlarının düzeltmeleri bunları ürün genelinde tutarlı bir şekilde kullanmalıdır. Visual Studio, işlevselliği yinelemekten ve ürün genelinde tutarlılık sağlamaktan kaçınmak için bir yardımcı sınıf kitaplığı sağlamıştır.

Yüksek çözünürlüklü görüntüler

Bu bölüm öncelikli olarak Visual Studio 2013'i genişleten geliştiricilere yöneliktir. Visual Studio 2015 için Visual Studio'da yerleşik olarak bulunan görüntü hizmetini kullanın. Ayrıca Visual Studio'nun birçok sürümünü desteklemeniz/hedeflemeniz gerektiğini ve bu nedenle önceki sürümlerde mevcut olmadığından 2015'te görüntü hizmetini kullanmanın bir seçenek olmadığını fark edebilirsiniz. Bu bölüm aynı zamanda size de yöneliktir.

Çok küçük görüntülerin ölçeğini artırma

Çok küçük olan görüntülerin ölçeği artırılabilir ve bazı yaygın yöntemler kullanılarak GDI ve WPF üzerinde işlenebilir. Yönetilen DPI yardımcı sınıfları, ölçeklendirme simgelerini, bit eşlemleri, imagestrips ve görüntü listelerini ele almak için iç ve dış Visual Studio tümleştiricileri tarafından kullanılabilir. WIN32 tabanlı yerel C/C++yardımcıları HICON, HBITMAP, HIMAGELIST ve VsUI::GdiplusImage'ı ölçeklendirmek için kullanılabilir. Bit eşlem ölçeklendirmesi genellikle yalnızca yardımcı kitaplığa başvuru ekledikten sonra tek satırlık bir değişiklik gerektirir. Örneğin:

(WinForms) DpiHelper.LogicalToDeviceUnits(ref image);

Görüntü listesini ölçeklendirme, görüntü listesinin yükleme zamanında tamamlanıp tamamlanmadığına veya çalışma zamanında eklenip eklenmediğine bağlıdır. Yükleme zamanında tamamlanırsa, bit eşlem gibi görüntü listesiyle çağrısı LogicalToDeviceUnits() yapın. Görüntü listesini oluşturmadan önce kodun tek bir bit eşlem yüklemesi gerektiğinde, görüntü listesinin görüntü boyutunu ölçeklendirmeyi unutmayın:

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

Yerel kodda, görüntü listesi oluşturulurken boyutlar aşağıdaki gibi ölçeklendirilebilir:

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

Kitaplıktaki işlevler, yeniden boyutlandırma algoritmasını belirtmeye olanak sağlar. Görüntü listelerine yerleştirilecek görüntüleri ölçeklendirirken, saydamlık için kullanılan arka plan rengini belirttiğinizden emin olun veya NearestNeighbor ölçeklendirmesini (%125 ve %150'de bozulmalara neden olacak) kullanın.

MSDN belgelerine DpiHelper bakın.

Aşağıdaki tabloda, görüntülerin ilgili DPI ölçeklendirme faktörlerine göre nasıl ölçeklendirilmesi gerektiğine ilişkin örnekler gösterilmektedir. Turuncu renkle özetlenen görüntüler, Visual Studio 2013 (%100-%200 DPI ölçeklendirme) itibarıyla en iyi uygulamamızı gösterir:

DPI Issues Scaling

Düzen sorunları

Yaygın düzen sorunları öncelikli olarak, mutlak konumlar (özellikle piksel birimlerinde) kullanmak yerine kullanıcı arabirimindeki noktaların ölçeklendirilip birbirine göre ölçeklendirilmesiyle önlenebilir. Örneğin:

  • Düzen/metin konumlarının ölçeklendirilmiş görüntüleri hesaba eklemek için ayarlanması gerekir.

  • Kılavuzlardaki sütunların ölçeklendirilmiş metin için ayarlanmış genişlikleri olması gerekir.

  • Sabit kodlanmış boyutların veya öğeler arasındaki boşluğun da ölçeğinin genişletilmesi gerekir. Yazı tiplerinin ölçeği otomatik olarak artırıldığından, yalnızca metin boyutlarını temel alan boyutlar genellikle uygundur.

    X ve Y ekseninde DpiHelper ölçeklendirmeye izin vermek için yardımcı işlevler sınıfında kullanılabilir:

  • LogicalToDeviceUnitsX/LogicalToDeviceUnitsY (işlevler X/Y ekseninde ölçeklendirmeye izin verir)

  • int space = DpiHelper.LogicalToDeviceUnitsX (10);

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

    Rect, Point ve Size gibi nesnelerin ölçeklendirilebilmesi için LogicalToDeviceUnits aşırı yüklemeleri vardır.

Görüntüleri ve düzeni ölçeklendirmek için DPIHelper kitaplığını/sınıfını kullanma

Visual Studio DPI yardımcı kitaplığı yerel ve yönetilen formlarda kullanılabilir ve diğer uygulamalar tarafından Visual Studio kabuğunun dışında kullanılabilir.

Kitaplığı kullanmak için Visual Studio VSSDK genişletilebilirlik örneklerine gidin ve High-DPI_Images_Icons örneğini kopyalayın.

Kaynak dosyalara VsUIDpiHelper.h dosyasını ekleyin ve sınıfın statik işlevlerini çağırınVsUI::DpiHelper:

#include "VsUIDpiHelper.h"

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

Dekont

Yardımcı işlevleri modül düzeyinde veya sınıf düzeyinde statik değişkenlerde kullanmayın. Kitaplık ayrıca iş parçacığı eşitlemesi için statikler kullanır ve sipariş başlatma sorunlarıyla karşılaşabilirsiniz. Bu statikleri statik olmayan üye değişkenlerine dönüştürün veya bir işleve sarmalayarak (ilk erişimde oluşturmalarını sağlayın).

Visual Studio ortamında çalıştırılacak yönetilen koddan DPI yardımcı işlevlerine erişmek için:

  • Tüketen proje, Shell MPF'nin en son sürümüne başvurmalıdır. Örneğin:

    <Reference Include="Microsoft.VisualStudio.Shell.14.0.dll" />
    
  • Projenin System.Windows.Forms, PresentationCore ve PresentationUI başvurularına sahip olduğundan emin olun.

  • Kodda Microsoft.VisualStudio.PlatformUI ad alanını kullanın ve DpiHelper sınıfının statik işlevlerini çağırın. Desteklenen türler (noktalar, boyutlar, dikdörtgenler vb.) için yeni ölçeklendirilmiş nesneler döndüren uzantı işlevleri sağlanır. Örneğin:

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

Yakınlaştırılabilir kullanıcı arabiriminde WPF görüntüsü bulanıklığıyla ilgilenme

WPF'de bit eşlemler, yüksek kaliteli bikübik algoritma (varsayılan) kullanılarak geçerli DPI yakınlaştırma düzeyi için WPF tarafından otomatik olarak yeniden boyutlandırılır. Bu algoritma resimler veya büyük ekran görüntüleri için iyi sonuç verir, ancak algılanan bulanıklık oluşturduğundan menü öğesi simgeleri için uygun değildir.

Öneriler:

  • Logo resmi ve başlık resmi için varsayılan BitmapScalingMode yeniden boyutlandırma modu kullanılabilir.

  • Menü öğeleri ve ikonografi görüntüleri için, BitmapScalingMode diğer bozulma yapıtlarının bulanıklığı ortadan kaldırmasına neden olmadığında kullanılmalıdır (%200 ve %300).

  • %100'ün katları olmayan büyük yakınlaştırma düzeyleri için (örneğin, %250 veya %350), kaynakçalı ikonografi görüntülerini ölçeklendirmek bulanık, yıkanmış kullanıcı arabiriminde sonuçlanır. Önce NearestNeighbor ile görüntüyü %100'ün en büyük katına (örneğin, %200 veya %300) ölçeklendirerek ve oradan bikübik ile ölçeklendirme yaparak daha iyi bir sonuç elde edilir. Daha fazla bilgi için bkz. Özel durum: büyük DPI düzeyleri için WPF görüntülerini önceden hesaplama.

    Microsoft.VisualStudio.PlatformUI ad alanı içindeki DpiHelper sınıfı, bağlama için kullanılabilecek bir üye BitmapScalingMode sağlar. Visual Studio kabuğunun DPI ölçeklendirme faktörüne bağlı olarak ürün genelinde bit eşlem ölçeklendirme modunu tekdüzen denetlemesine olanak sağlar.

    XAML'de kullanmak için şunları ekleyin:

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

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

Visual Studio kabuğu bu özelliği zaten üst düzey pencerelerde ve iletişim kutularına ayarlar. Visual Studio'da çalıştırılan WPF tabanlı kullanıcı arabirimi bunu zaten devralır. Ayar belirli kullanıcı arabirimi parçalarınıza yayılmazsa, XAML/WPF kullanıcı arabiriminin kök öğesinde ayarlanabilir. Bunun gerçekleştiği yerler arasında açılır pencereler, Win32 üst öğelerine sahip öğeler ve Blend gibi işlem dışı olan tasarımcı pencereleri bulunur.

Bazı kullanıcı arabirimi, Visual Studio metin düzenleyicisi ve WPF tabanlı tasarımcılar (WPF Masaüstü ve Windows Mağazası) gibi sistem tarafından ayarlanan DPI yakınlaştırma düzeyinden bağımsız olarak ölçeklendirilebilir. Bu gibi durumlarda DpiHelper.BitmapScalingMode kullanılmamalıdır. Düzenleyicide bu sorunu düzeltmek için IDE ekibi RenderOptions.BitmapScalingMode adlı özel bir özellik oluşturdu. Sistemin birleşik yakınlaştırma düzeyine ve kullanıcı arabiriminize bağlı olarak bu özellik değerini HighQuality veya NearestNeighbor olarak ayarlayın.

Özel durum: Büyük DPI düzeyleri için WPF görüntülerini önceden hesaplama

%100'ün katları olmayan çok büyük yakınlaştırma düzeyleri (örneğin, %250, %350 vb.) için, kaynakçalı ikonografi görüntülerini ölçeklendirmek belirsiz, yıkanmış kullanıcı arabirimiyle sonuçlanır. Bu görüntülerin canlı metinle birlikte izlenimi neredeyse optik bir yanılsama gibidir. Resimler metne göre göze daha yakın ve odak dışında görünüyor. Bu büyütülmüş boyuttaki ölçeklendirme sonucu, önce NearestNeighbor ile görüntüyü %100'ün en büyük katına (örneğin, %200 veya %300) ölçeklendirerek ve geri kalanına iki yönlü ölçeklendirerek (%50 daha fazla) geliştirilebilir.

Aşağıda, ilk görüntünün %100-%200->%250 geliştirilmiş çift ölçeklendirme algoritmasıyla ölçeklendirildiği ve ikinci görüntünün yalnızca %100->>%250 arası bikübik olduğu sonuçlardaki farklılıklara bir örnek verilmiştir.

DPI Issues Double Scaling Example

Kullanıcı arabiriminin bu çift ölçeklendirmeyi kullanmasını sağlamak için, her Image öğesini görüntülemek için XAML işaretlemenin değiştirilmesi gerekir. Aşağıdaki örneklerde, DpiHelper kitaplığı ve Shell.12/14 kullanılarak Visual Studio'da WPF'de çift ölçeklendirmenin nasıl kullanılacağı gösterilmektedir.

1. Adım: NearestNeighbor kullanarak görüntüyü %200, %300 vb. olarak önceden ölçeklendirin.

Bağlamaya uygulanan bir dönüştürücü kullanarak veya XAML işaretleme uzantısıyla görüntüyü önceden ölçekleme. Örneğin:

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

Görüntünün de temalı olması gerekiyorsa (tümü olmasa da), işaretleme önce görüntünün temalısını ve ardından önceden ölçeklendirmeyi gerçekleştiren farklı bir dönüştürücü kullanabilir. İşaretlemesi, istenen dönüştürme çıkışına bağlı olarak veya DpiPrescaleThemedImageSourceConverterkullanabilirDpiPrescaleThemedImageConverter.

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

2. Adım: Geçerli DPI için son boyutun doğru olduğundan emin olun.

WPF, UIElement üzerinde ayarlanan BitmapScalingMode özelliğini kullanarak geçerli DPI'nin kullanıcı arabirimini ölçeklendireceği için, kaynağı olarak önceden ölçeklendirilmiş bir görüntü kullanan bir Görüntü denetimi olması gerekenden iki veya üç kat daha büyük görünür. Bu etkiye karşı koymanın birkaç yolu şunlardır:

  • Özgün görüntünün boyutunu %100 olarak biliyorsanız, Görüntü denetiminin tam boyutunu belirtebilirsiniz. Bu boyutlar, ölçeklendirme uygulanmadan önce kullanıcı arabiriminin boyutunu yansıtır.

    <Image Source="{Binding Path=SelectedImage, Converter={StaticResource DpiPrescaleImageSourceConverter}}" Width="16" Height="16" />
    
  • Özgün görüntünün boyutu bilinmiyorsa, son Image nesnesinin ölçeğini küçültmek için bir LayoutTransform kullanılabilir. Örneğin:

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

WebOC'ye HDPI desteğini etkinleştirme

Varsayılan olarak, WebOC denetimleri (WPF'deki WebBrowser denetimi veya IWebBrowser2 arabirimi gibi) HDPI algılama ve desteğini etkinleştirmez. Sonuç, yüksek çözünürlüklü bir ekranda çok küçük olan görüntüleme içeriğine sahip ekli bir denetim olacaktır. Aşağıda, belirli bir web WebOC örneğinde yüksek DPI desteğinin nasıl etkinleştirileceği açıklanmaktadır.

IDocHostUIHandler arabirimini uygulayın (IDocHostUIHandler'da MSDN makalesine bakın:

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

İsteğe bağlı olarak, ICustomDoc arabirimini uygulayın (ICustomDoc'ta MSDN makalesine bakın:

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

IDocHostUIHandler uygulayan sınıfı WebOC'nin belgesiyle ilişkilendirin. Yukarıdaki ICustomDoc arabirimini uyguladıysanız, WebOC'nin belge özelliği geçerli olur olmaz bunu bir ICustomDoc'a yayınlayın ve IDocHostUIHandler uygulayan sınıfı geçirerek SetUIHandler yöntemini çağırın.

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

ICustomDoc arabirimini uygulamadıysanız, WebOC'nin belge özelliği geçerli olur olmaz bunu bir IOleObject'e atamanız ve IDocHostUIHandler uygulayan sınıfı geçirerek yöntemini çağırmanız SetClientSite gerekir. Yöntem çağrısına geçirilen DOCHOSTUIINFO üzerinde DOCHOSTUIFLAG_DPI_AWARE bayrağını GetHostInfo ayarlayın:

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

HPDI'yi desteklemek için WebOC denetiminizi almak için ihtiyacınız olan tek şey bu olmalıdır.

İpuçları

  1. WebOC denetimindeki belge özelliği değişirse, belgeyi IDocHostUIHandler sınıfıyla yeniden ilişkilendirmeniz gerekebilir.

  2. Yukarıdakiler işe yaramazsa, WebOC'nin DPI bayrağındaki değişikliği almamasıyla ilgili bilinen bir sorun vardır. Bunu düzeltmenin en güvenilir yolu, WebOC'nin optik yakınlaştırmasını değiştirmektir; yani yakınlaştırma yüzdesi için iki farklı değere sahip iki çağrı. Ayrıca, bu geçici çözüm gerekliyse, her gezinme çağrısında bunu gerçekleştirmek gerekebilir.

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