none
The web browser control and IHTMLStyle::put_element RRS feed

  • Question

  • We have been using IHTMLStyle::put_height to set a max height for an element we use in a dialog that has the WebBrowser control in it. This has always worked for us. If the height of the element is larger than the value we send to put_height, the WBC shows a scroll bar. If our dialog is sized, the scroll bar disappears and reappears right on cue.

    But customers with a 4k monitor have issues. So I acquired a desktop topology that includes a 4K monitor as my main monitor.

    Like customers, I scale it to 200%. When we make the call to put_height, the height we set doesn't work properly (but get_height does return the same value). We never see scroll bars no matter how small we resize the dialog (and the WBC it contains). When OnSize is called with the client sizes, neither SpyXX nor paint agree with the client size of the dialog nor of the WBC size we change in OnSize. I tried a number of things like passing in "Npx" (N is the height) and other units to no avail. I tried other APIs that set the size with no luck.

    Finally today I had an ideal. Before setting the height (the "cy" in OnSize) of the element, I scale it by 1/DPI setting. So if the setting is 200%, I send in cy/2. This fixes the issue with put_height I get the same "result", meaning behavior, when my 4k monitor is set to 100% or 200% (or whatever).

    I never found any documentation that indicated this is what I should do. I decided to do the scaling since I know the WBC returns 200 (in my 200% dpi case) for an OLECMDID_OPTICAL_ZOOM call I made.

    For our app, I set the DPI awareness to per monitor (but not "V2" as bad things happen all over the place). I see the same issue if I set it to high DPI aware (system aware).

    So, is this expected? Should I actually be calling to get OLECMDID_OPTICAL_ZOOM and scaling by it before calling IHTMLStyle::put_height? Something different than either approach?


    R.D. Holland

    Tuesday, July 23, 2019 6:06 PM

All replies

  • Hi RD Holland,

    Are you using ExecWB while using OLECMDID_OPTICAL_ZOOM?

    This is the sample code.

    Public Class Form1
    Private Enum Exec
      OLECMDID_OPTICAL_ZOOM = 63
    End Enum
    Private Enum ExecOpt
      OLECMDEXECOPT_DODEFAULT = 0
      OLECMDEXECOPT_PROMPTUSER = 1
      OLECMDEXECOPT_DONTPROMPTUSER = 2
      OLECMDEXECOPT_SHOWHELP = 3
    End Enum
    Private Sub Button1_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles Button1.Click
      Try
        Dim Res As Object = Nothing
        Dim MyWeb As Object
        MyWeb = Me.WebBrowser1.ActiveXInstance
        MyWeb.ExecWB(Exec.OLECMDID_OPTICAL_ZOOM, _
              ExecOpt.OLECMDEXECOPT_DONTPROMPTUSER, 50, IntPtr.Zero)
      Catch ex As Exception
        MsgBox("Error:" & ex.Message)
      End Try
     End Sub
    End Class

    Reference:

    Using ExecWB with the native .NET 2.0 WebBrowser control

    Let me know, if I misunderstand anything from your above description. I will try to correct myself.

    Regards

    Deepak


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, July 24, 2019 6:08 AM
    Moderator
  • Hi Deepak,

    No I am not. My code is c++ and I use IOleCommandTarget::Exec to get and set the zoom factor. But, it is the same interface .NET uses if the WBC is still the basis for .NET's version of the control. I don't really have to set the zoom factor as after creating the control its zoom factor is already the same as my main monitor's DPI scale.

    Apparently when calling put_height, the input is assumed to be unscaled and the control scales it.


    R.D. Holland

    Wednesday, July 24, 2019 12:39 PM
  • Hi RD Holland,

    If you try to post any sample code than we can try to test the issue on our side to see the result.

    It can help us to understand the issue in better way and than we can try to provide any suggestion for the issue.

    Thanks for your understanding.

    Regards

    Deepak


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, July 25, 2019 6:39 AM
    Moderator
  • Pretty simple really. When OnSize is called we set the height of an element in our web page that is dynamically populated with data. We have a max height of the dialog that contains the WBC. GUserText is our version of a string class. TIP is just a smart pointer. You can replace it with standard interface pointers and then call Release directly or use the MS definition of the equivalent smart pointers.

    HRESULT JWebBrowserCtrl::SetElementMaxHeight(GUserText gutElmID, long nHeight)
    {
        HRESULT hr = NOERROR;
        TIP<IHTMLElement*> tipHtmlElement;
        TIP<IHTMLWindow2*> tipIHTMLWindow2;
        TIP<IHTMLStyle*> tipIHTMLStyle;

        CWebBrowser2* pWebBrowser = NULL;

        if(!m_pWebBrowser2 || !(m_pWebBrowser2->GetSafeHwnd()))
            hr_exit(E_FAIL);

        pWebBrowser = (CWebBrowser2*)m_pWebBrowser2;
        if(!pWebBrowser)
        {
            hr = E_FAIL;
            goto wrapup;
        }

        hr = FindElement(gutElmID, IID_IHTMLElement, (LPVOID*)&tipHtmlElement, &tipIHTMLWindow2);
        if(tipHtmlElement==NULL)
        {
           goto wrapup;
        }

        hr = tipHtmlElement->get_style(&tipIHTMLStyle);
        hr_test;

        hr = tipIHTMLStyle->put_height(_variant_t(nHeight));
        hr_test;

    wrapup:
        return hr;
    }

    Here is code grabbed from OnSize. SE_DPI just applies the device DPI factor. I fixed the issue with the height by dividing by the device DPI value before setting the element height. That fixed the issue we had where the element was too big. I just didn't expect that that would be needed. But, perhaps it is what one has to do when working on a scaled desktop.

                int nMaxHeight = cy - SE_DPI(30) - SE_DPI(40);

                // But this one was just right.
                nMaxHeight = (double)nMaxHeight/SE_DPI(1);

                pWebBrowserCtrl->SetElementMaxHeight(GUserText(L"CMD_FINDER_RESULT"), nMaxHeight);


    R.D. Holland


    • Edited by RD Holland Thursday, July 25, 2019 1:30 PM
    Thursday, July 25, 2019 1:21 PM
  • Hi RD Holland,

    You can try to set AutoScaleMode property of your form to Dpi.

    You can also try to refer links below may give some additional information that can be helpful to you.

    References:

    WPF Web Browser Control and DPI Scaling

    WebBrowser control High DPI support

    Regards

    Deepak


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, July 30, 2019 9:19 AM
    Moderator
  • Hi Deepak,

    I'm working in a non .NET app. I set the emulation mode for the WBC and the app is per monitor DPI aware. I looked at your links. As it stands, I don't even have issues with shortcut menus (believe someone in the links mentioned that).

    As of now, I stand by what I found. The WBC honors the DPI scaling (verified via the call to get the optical zoom factor) and when calling put_height, I have to send in non-scaled values as the WBC will scale the input height when it renders. I didn't expect that so I posted about it. By doing that, the results we want are the same whether the monitor is scaled or not.

    It just "feels" odd that I have to use the cy (client height for WM_SIZE) of our dialog in which the WBC is embedded and call MoveWindow on the WBC using that value, and then to set the max height of an element, I have to unscale the height I want. But, hey, it works. For now.


    R.D. Holland

    Wednesday, July 31, 2019 1:44 PM