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ğunlukta (100%) olduğunda, Windows uygulama penceresinin içeriğini ikincil ekranda otomatik olarak ölçeklendirir (uygulama tarafından işlenen her 4 piksel için 1 piksel görüntülenir).

  • 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% 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 tekdüze bir şekilde piksel esnetilmesi nedeniyle "bulanık" bir kullanıcı deneyimine neden olabilir. Örneğin:

    DPI Sorunları Belirsiz

    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çümleri (örneğin, SM_CXICON ve SM_CXSMICON) baz alındığında, sistem veya kaynaklar tarafından sağlanan simgeler şimdiden yükseltilmiş durumdadır.

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. Bitmap ölçeklendirmesi genellikle yardımcı kitaplığa referans eklendikten hemen sonra tek bir satırda değişiklik yapılması yeterlidir. Ö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çeklendirmesi) itibarıyla en iyi uygulamamızı gösterir:

DPI Sorunlarını Ölçeklendirme

Düzen sorunları

Yaygın düzen sorunları, piksel birimlerinde sabit konumlar kullanmak yerine, UI'daki noktaların 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.

  • Izgaralardaki sütunların, ölçeklendirilmiş metin için ayarlanan genişliklere sahip 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::DpiHelper::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ın VsUI::DpiHelper :

#include "VsUIDpiHelper.h"

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

Uyarı

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 statik değişkenler kullanır ve başlatma sırası sorunlarıyla karşılaşabilirsiniz. Bu statik değişkenleri statik olmayan üye değişkenlerine dönüştürün veya bir işlev içine alarak ilk erişimde oluşturulmaları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" />
    
  • System.Windows.Forms, PresentationCore ve PresentationUI başvurularının projede 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ü bulanıklığını giderme

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 resimleri için, diğer bozulma artefaktlarına neden olmadığında BitmapScalingMode bulanıklığı gidermek amacıyla kullanılmalıdır (200% ve 300%).

  • 100%'ün katları olmayan (örneğin, 250% veya 350%) büyük yakınlaştırma düzeyleri için, ikonografi görüntülerinin bikübik ile ölçeklenmesi sonucu bulanık ve solgun bir kullanıcı arabirimi oluşur. Önce NearestNeighbor ile görüntüyü 100% en büyük katına (örneğin, 200% veya 300%) ölçeklendirerek ve oradan bikübik ile ölçeklendirerek 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. DPI ölçeklendirme faktörüne bağlı olarak Visual Studio kabuğunun, ürün genelinde bit eşlem ölçeklendirme modunu tutarlı bir şekilde 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 kabuk bu özelliği zaten üst düzey pencerelerde ve iletişim kutularında 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 harici işlem modunda çalışan tasarım uygulaması 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, bicubic ile ikon görüntülerini ölçeklendirmek bulanık ve soluk bir 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, öncelikle NearestNeighbor yöntemiyle görüntüyü %100'ün en büyük katı olan (örneğin, %200 veya %300) bir orana ölçeklendirip, geriye kalan için bikübik yöntemini kullanarak (ek %50) 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 bikübik 100%> ->250%ile ölçeklendirildiği sonuçlardaki farklılıklara bir örnek verilmiştir.

DPI Sorunları Çift Ölçeklendirme Örneği

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ü önceden %200, %300, vb. boyutlara ayarlayın.

Görüntüyü, bir bağlamada uygulanan dönüştürücü veya bir XAML işaretleme uzantısı kullanarak ön ölçekleyin. Ö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 (ki çoğu böyle olmalıdır), işaretleme, öncelikle görüntünün temalandırılmasını ve ardından ölçeklendirilmesini gerçekleştiren farklı bir dönüştürücü kullanabilir. İşaretlemeler, istenen çıktıya bağlı olarak DpiPrescaleThemedImageConverter veya DpiPrescaleThemedImageSourceConverter kullanabilir.

<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, onu bir IOleObject'e dönüştürmeli ve IDocHostUIHandler'ı uygulayan sınıfı geçirerek SetClientSite yöntemini çağırmalısınız. DOCHOSTUIINFO nesnesine DOCHOSTUIFLAG_DPI_AWARE bayrağını ayarlayarak GetHostInfo yöntem çağrısına geçirin.

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ğında yapılan 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);
    }