DPI-problémák elhárítása

Egyre több eszköz szállít "nagy felbontású" képernyőkkel. Ezek a képernyők általában több mint 200 képpont /hüvelyk (ppi) méretűek. Az alkalmazások ezen számítógépeken való használatához a tartalmat fel kell skálázni, hogy megfeleljen a tartalom normál megtekintési távolságra való megtekintésének igényeinek. 2014-ben a nagy sűrűségű kijelzők elsődleges célja a mobil számítástechnikai eszközök (táblagépek, clamshell laptopok és telefonok).

A Windows 8.1 és újabb verziók számos funkciót tartalmaznak, amelyekkel ezek a gépek olyan kijelzőkkel és környezetekkel dolgozhatnak, ahol a gép egyszerre csatlakozik a nagy sűrűségű és a standard sűrűségű kijelzőkhöz.

  • A Windows lehetővé teszi a tartalomnak az eszközre való skálázását a "Szöveg és más elemek méretének növelése vagy kisebbvé tétele" beállítással (a Windows XP óta érhető el).

  • A Windows 8.1 és újabb verziók automatikusan skálázják a tartalmakat, hogy a legtöbb alkalmazás konzisztens legyen a különböző képpontsűrűségű kijelzők közötti áthelyezéskor. Ha az elsődleges kijelző nagy sűrűségű (200% skálázás), és a másodlagos kijelző normál sűrűségű (100%), a Windows automatikusan leskálázza az alkalmazásablak tartalmát a másodlagos kijelzőn (1 képpont az alkalmazás által megjelenített 4 képpontonként).

  • A Windows alapértelmezés szerint a képpontsűrűség és a megjelenítési távolság (Windows 7 és újabb, OEM-konfigurálható) megfelelő skálázása.

  • A Windows legfeljebb 250% képes automatikusan skálázni a tartalmat a 280 ppi-t meghaladó új eszközökön (a Windows 8.1 S14-hez hasonlóan).

    A Windows a felhasználói felület vertikális felskálázásával foglalkozik a megnövekedett képpontszám kihasználása érdekében. Egy alkalmazás akkor lép be ebbe a rendszerbe, ha "rendszer DPI tudatosnak" nyilvánítja magát. Azok az alkalmazások, amelyek ezt nem teszik meg, a rendszer által felskálázásra kerülnek. Az egész alkalmazás egyenletesen szétterjedt pixelméretű, ami "homályos" felhasználói élményt eredményezhet. Például:

    DPI-problémák Fuzzy

    A Visual Studio úgy dönt, hogy a DPI skálázható, ezért nem "virtualizált".

    A Windows (és a Visual Studio) számos felhasználói felületi technológiát használ, amelyek különböző módon kezelik a rendszer által meghatározott méretezési tényezőket. Például:

  • A WPF eszközfüggetlen módon méri a vezérlőket (egységek, nem képpontok). A WPF felhasználói felülete automatikusan felskálázódik az aktuális DPI-hez.

  • A felhasználói felületi keretrendszertől függetlenül minden szövegméret pontban van kifejezve, így a rendszer DPI-függetlenként kezeli őket. A Win32-, WinForms- és WPF-szövegek már megfelelően felskálázhatók, amikor a kijelzőeszközre kerülnek.

  • A Win32/WinForms párbeszédpanelek és ablakok lehetőséget biztosítanak olyan elrendezésekhez, amelyek szöveg alapján átméretezhetőek (például rácspanel, folyamatelem és táblázatelrendezési panelek). Ez lehetővé teszi a fixen kódolt képponthelyek elkerülését, amelyek nincsenek skálázva a betűméretek növelésekor.

  • A rendszer vagy az erőforrások által a rendszermetrikák alapján megadott ikonok (például SM_CXICON és SM_CXSMICON) már fel vannak skálázva.

Régebbi Win32 (GDI, GDI+) és WinForms-alapú felhasználói felület

Bár a WPF már eleve magas DPI-tudással rendelkezik, a Win32/GDI-alapú kód nagy része eredetileg nem a DPI-tudatosság szem előtt tartásával készült. A Windows DPI-méretezési API-kat biztosított. A Win32-problémák javításainak ezeket következetesen kell használniuk a terméken belül. A Visual Studio egy segédosztálytárat biztosított a funkciók duplikálásának elkerülése és a termék konzisztenciájának biztosítása érdekében.

Nagy felbontású képek

Ez a szakasz elsősorban a Visual Studio 2013-at kiterjesztő fejlesztők számára készült. Használja a Visual Studio 2015-höz beépített képszolgáltatást a Visual Studio-n belül. Azt is tapasztalhatja, hogy a Visual Studio számos verzióját támogatnia/meg kell céloznia, ezért a képszolgáltatás 2015-ös használata nem megoldás, mivel a korábbi verziókban nem létezik. Ez a szakasz önnek is szól.

Túl kicsi képek méretezése

A túl kicsi képek felskálázhatók és megjeleníthetők a GDI-n és a WPF-en néhány gyakori módszerrel. A felügyelt DPI-segédosztályok belső és külső Visual Studio-integrátorok számára érhetők el a méretezési ikonok, bitképek, képek és képlisták kezelésére. A Win32-alapú natív C/C++-segítők a HICON, a HBITMAP, a HIMAGELIST és a VsUI::GdiplusImage skálázásához érhetők el. A bitképek méretezéséhez általában csak egysoros módosítás szükséges a segédtárra mutató hivatkozás hozzáadása után. Például:

(WinForms) DpiHelper.LogicalToDeviceUnits(ref image);

A képlista skálázása attól függ, hogy a képlista betöltéskor befejeződött-e, vagy futásidőben van hozzáfűzve. Ha a betöltési idő alatt teljesen elkészült, hívja meg a LogicalToDeviceUnits() képlistát úgy, mint egy bitképet. Ha a kódnak be kell töltenie egy egyéni bitképet a képlista írása előtt, mindenképpen skálázza fel a képlista képméretét:

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

Natív kódban a dimenziók az alábbi módon méretezhetők a képlista létrehozásakor:

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

A kódtár függvényei lehetővé teszik az átméretezési algoritmus megadását. Képlistákba helyezendő képek méretezésekor ügyeljen arra, hogy adja meg az áttetszőséghez használt háttérszínt, vagy használja a NearestNeighbor skálázást (ami 125% és 150%esetén torzítást okoz).

Tekintse meg az MSDN dokumentációját DpiHelper .

Az alábbi táblázat példákat mutat be arra, hogyan kell méretezni a képeket a megfelelő DPI-méretezési tényezők alapján. A narancssárga színnel tagolt képek a Visual Studio 2013 ajánlott eljárását jelölik (100%-200% DPI-méretezés):

DPI-problémák skálázása

Elrendezési problémák

A gyakori elrendezési problémák elsősorban úgy kerülhetők el, hogy a felhasználói felületen lévő pontokat skálázva és egymáshoz viszonyítva tartják, nem pedig abszolút helyek használatával (pontosabban képpontegységekben). Például:

  • Az elrendezési/szövegpozícióknak igazodnia kell a felskálázott képekhez.

  • A rácsok oszlopainak szélességét módosítani kell a nagyított szöveghez igazodva.

  • A nehezen kódolt méreteket vagy az elemek közötti térközt is fel kell skálázni. A csak szövegméreteken alapuló méretek általában finomak, mert a betűtípusok automatikusan felskálázódnak.

    Az DpiHelper osztályban érhetők el olyan segédfüggvények, amelyek lehetővé teszik az X és Y tengelyek skálázását.

  • LogicalToDeviceUnitsX/LogicalToDeviceUnitsY (a függvények lehetővé teszik a skálázást az X/Y tengelyen)

  • int space = DpiHelper.LogicalToDeviceUnitsX(10);

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

    Vannak LogicalToDeviceUnits túlterhelések, amelyek lehetővé teszik objektumok, mint a Rect, Point és Size, skálázását.

A DPIHelper könyvtár/osztály használata képek és elrendezések skálázásához

A Visual Studio DPI segédkönyvtár natív és felügyelt formában érhető el, és más alkalmazások is használhatják a Visual Studio rendszerhéján kívül.

A kódtár használatához nyissa meg a Visual Studio VSSDK bővíthetőségi mintáit , és klónozza a High-DPI_Images_Icons mintát.

A forrásfájlokban adja meg a VsUIDpiHelper.h fájlt, és hívja meg az osztály statikus függvényét VsUI::DpiHelper :

#include "VsUIDpiHelper.h"

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

Megjegyzés:

Ne használja a segédfüggvényeket modulszintű vagy osztályszintű statikus változókban. A kódtár statikus elemet is használ a szálszinkronizáláshoz, és előfordulhat, hogy sorrend-inicializálási problémákba ütközik. Alakítsa át ezeket a statikus elemeket nem statikus tagváltozókká, vagy csomagolja őket egy függvénybe (így az első hozzáféréskor létrejönnek).

A DPI-segédfüggvények elérése a Visual Studio-környezetben futtatandó felügyelt kódból:

  • A fogyasztó projektnek a Shell MPF legújabb verziójára kell hivatkoznia. Például:

    <Reference Include="Microsoft.VisualStudio.Shell.14.0.dll" />
    
  • Győződjön meg arról, hogy a projekt a System.Windows.Formsra, a PresentationCore-ra és a PresentationUI-ra mutató hivatkozásokkal rendelkezik.

  • A kódban használja a Microsoft.VisualStudio.PlatformUI névteret, és hívja meg a DpiHelper osztály statikus függvényeit. A támogatott típusok (pontok, méretek, téglalapok stb.) esetében vannak olyan bővítményfüggvények, amelyek új skálázott objektumokat adnak vissza. Például:

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

A WPF-rendszerképek homályosságának kezelése nagyítható felhasználói felületen

A WPF-ben a bitképeket a WPF automatikusan átméretezi az aktuális DPI-nagyítási szinthez egy kiváló minőségű bicubic algoritmussal (alapértelmezett), amely jól működik képekhez vagy nagy képernyőképekhez, de nem megfelelő a menüelemek ikonjaihoz, mert érzékelt homályosságot mutat.

Ajánlások:

  • Emblémaképek és bannerek esetében az alapértelmezett BitmapScalingMode átméretező mód használható.

  • Menüelemekhez és ikonográfiai képekhez akkor BitmapScalingMode kell használni, ha nem okoz más torzítási összetevőket a homályosság megszüntetéséhez (200% és 300%).

  • Nagy nagyítási szintekhez, amelyek nem 100%-os többszörösei (például 250% vagy 350%), az ikonográfiai képek bicubic használatával történő skálázása homályos és kimosott felhasználói felületet eredményez. Jobb eredményt akkor kapunk, ha először 100% (például 200% vagy 300%) legnagyobb többszörösére skálázjuk a képet a NearestNeighborral, majd onnan skálázjuk a bikubicot. További információkért lásd a speciális esetet: WPF-rendszerképek előskálázása nagy DPI-szintekhez.

    A Microsoft.VisualStudio.PlatformUI névtér DpiHelper osztálya egy kötéshez használható tagot BitmapScalingMode biztosít. Lehetővé teszi, hogy a Visual Studio rendszerhéj a DPI skálázási tényezőtől függően egységesen vezérelje a bitkép skálázási módját a terméken belül.

    Ha xAML-ben szeretné használni, adja hozzá a következőt:

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

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

A Visual Studio grafikus felülete már beállítja ezt a tulajdonságot a legfelső szintű ablakokra és párbeszédpanelekre. A Visual Studióban futó WPF-alapú felhasználói felület már örökli azt. Ha a beállítás nem propagálható az adott felhasználói felületen, akkor az XAML/WPF felhasználói felület gyökérelemén állítható be. Ilyenek azok a helyek, ahol ez történik: előugró ablakok, a Win32-szülőkkel rendelkező elemek, valamint a külön folyamatban futó tervezőablakok, például a Blend.

Egyes felhasználói felületek a rendszer által beállított DPI nagyítási szinttől függetlenül méretezhetők, például a Visual Studio szövegszerkesztőjétől és a WPF-alapú tervezőktől (WPF Desktop és Windows Áruház). Ezekben az esetekben a DpiHelper.BitmapScalingMode nem használható. A hiba a szerkesztőben való megoldásához az IDE csapata létrehozott egy egyéni tulajdonságot RenderOptions.BitmapScalingMode néven. Állítsa be ezt a tulajdonságértéket HighQuality vagy NearestNeighbor értékre a rendszer és a felhasználói felület együttes nagyítási szintjétől függően.

Speciális eset: WPF-rendszerképek előskálázása nagy DPI-szintekhez

Nagyon nagy nagyítási szintek esetén, amelyek nem többszörösei a 100% (például 250%, 350%stb.), az ikonográfiai képek bicubic skálázása homályos, kimosott felhasználói felületet eredményez. Ezeknek a képeknek a benyomása a ropogós szöveg mellett majdnem olyan, mint egy optikai illúzió. Úgy tűnik, hogy a képek közelebb kerülnek a szemhez, és a szöveghez képest homályosak vagy elmosódottak. A méretezési eredmény ezen a nagyított méreten javítható, ha először 100% (például 200% vagy 300%) legnagyobb többszörösére skálázza a képet a NearestNeighborral, majd a többihez bicubic-sel skáláz (további 50%).

** Az alábbi példa az eredmények különbségeit szemlélteti, ahol az első kép skálázása a továbbfejlesztett kétszeres skálázási algoritmussal történik 100%->200%->250%, a második pedig csak bicubikus módszerrel 100%->250%.

DPI-problémák – Dupla skálázás – példa

Ahhoz, hogy a felhasználói felület használhassa ezt a kettős méretezést, módosítani kell az egyes képelemek megjelenítéséhez szükséges XAML-jelöléseket. Az alábbi példák bemutatják, hogyan használható a dupla skálázás a WPF-ben a Visual Studióban a DpiHelper könyvtár és a Shell.12/14 használatával.

1. lépés: A kép előskálázása 200%, 300%, és így tovább a NearestNeighbor használatával.

A kép előzetes méretezése történhet kötésen alkalmazott konverterrel vagy XAML jelölő bővítménnyel. Például:

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

Ha a képet is témázni kell (a legtöbb esetben így van), a jelölőnyelv használhat egy másik átalakítót, amely először elvégzi a kép témázását, majd az előszerkesztést a méretek előzetes beállításával. A jelölés a kívánt konverziós kimenettől függően használhatja vagy a DpiPrescaleThemedImageConverter vagy a DpiPrescaleThemedImageSourceConverter tag-et.

<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. lépés: Győződjön meg arról, hogy a végső méret helyes az aktuális DPI-hez.

Mivel a WPF az aktuális DPI-nek megfelelően skálázza a felhasználói felületet a UIElement-en beállított BitmapScalingMode tulajdonsággal, egy olyan Image vezérlő, amely előre skálázott képet használ forrásként, a kelleténél kétszer vagy háromszor nagyobbnak fog tűnni. Az alábbiakban néhány módszert kínálunk ennek a hatásnak a elhárítására:

  • Ha ismeri az eredeti kép 100%-os méretét, megadhatja a képvezérlő pontos méretét. Ezek a méretek a skálázás alkalmazása előtt tükrözik a felhasználói felület méretét.

    <Image Source="{Binding Path=SelectedImage, Converter={StaticResource DpiPrescaleImageSourceConverter}}" Width="16" Height="16" />
    
  • Ha az eredeti kép mérete nem ismert, az LayoutTransform segítségével leskálázható a végső képobjektum. Például:

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

A HDPI támogatásának engedélyezése a WebOC-hez

A WebOC-vezérlők (például a WPF WebBrowser vezérlője vagy az IWebBrowser2 felület) alapértelmezés szerint nem engedélyezik a HDPI észlelését és támogatását. Az eredmény egy beágyazott vezérlő lesz, amelynek megjelenítési tartalma túl kicsi a nagy felbontású kijelzőn. Az alábbiakban bemutatjuk, hogyan engedélyezhet magas DPI-támogatást egy adott webOC-példányban.

Implementálja az IDocHostUIHandler felületet (lásd az MSDN-cikket az IDocHostUIHandlerről:

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

Igény szerint implementálhatja az ICustomDoc felületet (lásd az MSDN-cikket az ICustomDoc-ról:

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

Társítsa az IDocHostUIHandlert megvalósító osztályt a WebOC dokumentumához. Ha az ICustomDoc felületet implementálta a fentiek szerint, akkor amint a WebOC dokumentum tulajdonsága érvényes lesz, ezt alakítsa át ICustomDoc-ká, majd hívja meg a SetUIHandler metódust, az IDocHostUIHandlert implementáló osztályt továbbítva argumentumként.

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

Ha NEM implementálta az ICustomDoc felületet, akkor amint a WebOC dokumentum tulajdonsága érvényes, le kell képeznie egy IOleObject-re, és meg kell hívnia a SetClientSite metódust, az IDocHostUIHandler-t implementáló osztályt megadva. Állítsa be a DOCHOSTUIINFO-ban a metódushívás során átadott DOCHOSTUIFLAG_DPI_AWARE jelzőt.

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

Csak ennyire van szüksége, hogy a WebOC vezérlő támogassa a HPDI-t.

Tippek

  1. Ha a WebOC-vezérlő dokumentumtulajdonságai módosulnak, előfordulhat, hogy újra kell társítania a dokumentumot az IDocHostUIHandler osztálysal.

  2. Ha a fentiek nem működnek, ismert probléma merül fel azzal kapcsolatban, hogy a WebOC nem veszi fel a DPI-jelző módosítását. Ennek a megoldásnak a legmegbízhatóbb módja a WebOC optikai nagyításának kapcsolása, vagyis két hívást kell kezdeményezni két különböző nagyítási százalékértékkel. Emellett, ha ez a kerülő megoldás szükséges, szükség lehet rá minden navigálási híváson.

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