Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Size of a CDHTMLDialog?

Size of a CDHTMLDialog?

Scheduled Pinned Locked Moved C / C++ / MFC
question
7 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Robert Mooney
    wrote on last edited by
    #1

    Is there a way to determine the size of the rendered content of a CDHtmlDialog? - Rob

    P M 2 Replies Last reply
    0
    • R Robert Mooney

      Is there a way to determine the size of the rendered content of a CDHtmlDialog? - Rob

      P Offline
      P Offline
      Peter Molnar
      wrote on last edited by
      #2

      1.Get IHTMLDocument2 interface with GetDHtmlDocument 2.Get entire body tag with spDoc->get_body 3.Call spBodyElement->offsetHeight and spBodyElement->offsetWidth to determine the body element's size (i.e. that of the full HTML page) 4.Resize your dialog with CWnd::MoveWindow accordingly Problem of above approach: you first show, measure and then resize your HTML, which entails some flickering. To avoid it, first of all parse your HTML from file or resource without displaying it as described in http://www.codeproject.com/internet/parse_html.asp (equivalent to 1./) then do steps 2./ 3./ and 4./ in "silent" mode. Peter Molnar

      R 1 Reply Last reply
      0
      • P Peter Molnar

        1.Get IHTMLDocument2 interface with GetDHtmlDocument 2.Get entire body tag with spDoc->get_body 3.Call spBodyElement->offsetHeight and spBodyElement->offsetWidth to determine the body element's size (i.e. that of the full HTML page) 4.Resize your dialog with CWnd::MoveWindow accordingly Problem of above approach: you first show, measure and then resize your HTML, which entails some flickering. To avoid it, first of all parse your HTML from file or resource without displaying it as described in http://www.codeproject.com/internet/parse_html.asp (equivalent to 1./) then do steps 2./ 3./ and 4./ in "silent" mode. Peter Molnar

        R Offline
        R Offline
        Robert Mooney
        wrote on last edited by
        #3

        Hrm. That seems to return the size of the client area, not the size required to display the document. I have the following in my class derived from CDHtmlDialog, in an overridden ShowContextMenu() handler. LONG nHeight, nWidth; IHTMLDocument2 *pDocument; IHTMLElement *pElement; GetDHtmlDocument(&pDocument); pDocument->get_body(&pElement); pElement->get_offsetHeight(&nHeight); pElement->get_offsetWidth(&nWidth); TRACE("Document width = %d\n", nWidth); TRACE("Document height = %d\n", nHeight); pElement->Release(); pDocument->Release(); CRect rect; GetClientRect(&rect); TRACE("Client width = %d\n", rect.Width()); TRACE("Client height = %d\n", rect.Height()); ASSERT(nWidth == rect.Width()); ASSERT(nHeight == rect.Height()); The width and height are always equal to the respective attributes of the client rectangle. Using the technique from http://www.codeproject.com/internet/parse_html.asp, the document width and height are always 0. Am I missing something?

        P 1 Reply Last reply
        0
        • R Robert Mooney

          Hrm. That seems to return the size of the client area, not the size required to display the document. I have the following in my class derived from CDHtmlDialog, in an overridden ShowContextMenu() handler. LONG nHeight, nWidth; IHTMLDocument2 *pDocument; IHTMLElement *pElement; GetDHtmlDocument(&pDocument); pDocument->get_body(&pElement); pElement->get_offsetHeight(&nHeight); pElement->get_offsetWidth(&nWidth); TRACE("Document width = %d\n", nWidth); TRACE("Document height = %d\n", nHeight); pElement->Release(); pDocument->Release(); CRect rect; GetClientRect(&rect); TRACE("Client width = %d\n", rect.Width()); TRACE("Client height = %d\n", rect.Height()); ASSERT(nWidth == rect.Width()); ASSERT(nHeight == rect.Height()); The width and height are always equal to the respective attributes of the client rectangle. Using the technique from http://www.codeproject.com/internet/parse_html.asp, the document width and height are always 0. Am I missing something?

          P Offline
          P Offline
          Peter Molnar
          wrote on last edited by
          #4

          Sorry, I was wrong when I suggested that you should get the entire body, because its sizes really equal to the entire body, consequently you cannot get anything else but the size of your entire DHTML client area in this way. So, my new suggestion is that you take a pointer to that element only, the size of which you wanna get. If you are interested in several elements at a time like <a>,<img> <table>etc. then put them all into one single <div> element, and deal with this container of elements. In order to get a pointer to an element you can either 1.loop through all elements by checking for some property, like id, name, tagname etc., using IHTMLDocument2::get_all, and IHTMLElementCollection::item,(>=IE4), or 2.use IHTMLDocument3::getElementById, getElementsByName or getElementsByTagName (>=IE5) The simplest thing is to give your element in question (or container element) an id attribute, e.g. <div id="YourDivID">...</div>, so that you can find it. Remark to your code: consider using smart pointers, which makes your task significantly easier by eliminating QueryInterfacing and releasing pointers.

          CComPtr<IHTMLDocument2> spDoc;
          //or
          MSHTML::IHTMLDocument2Ptr spDoc;

          Your code:

          MSHTML::IHTMLElementPtr spElem;
          MSHTML::IHTMLDocument3Ptr spDoc3(spDoc);
          spDoc3->getElementByID(CComBSTR("YourDivID"),&spElem);
          spElem->get_offsetHeight(&nHeight);
          spElem->get_offsetWidth(&nWidth);

          Peter Molnar

          R 1 Reply Last reply
          0
          • P Peter Molnar

            Sorry, I was wrong when I suggested that you should get the entire body, because its sizes really equal to the entire body, consequently you cannot get anything else but the size of your entire DHTML client area in this way. So, my new suggestion is that you take a pointer to that element only, the size of which you wanna get. If you are interested in several elements at a time like <a>,<img> <table>etc. then put them all into one single <div> element, and deal with this container of elements. In order to get a pointer to an element you can either 1.loop through all elements by checking for some property, like id, name, tagname etc., using IHTMLDocument2::get_all, and IHTMLElementCollection::item,(>=IE4), or 2.use IHTMLDocument3::getElementById, getElementsByName or getElementsByTagName (>=IE5) The simplest thing is to give your element in question (or container element) an id attribute, e.g. <div id="YourDivID">...</div>, so that you can find it. Remark to your code: consider using smart pointers, which makes your task significantly easier by eliminating QueryInterfacing and releasing pointers.

            CComPtr<IHTMLDocument2> spDoc;
            //or
            MSHTML::IHTMLDocument2Ptr spDoc;

            Your code:

            MSHTML::IHTMLElementPtr spElem;
            MSHTML::IHTMLDocument3Ptr spDoc3(spDoc);
            spDoc3->getElementByID(CComBSTR("YourDivID"),&spElem);
            spElem->get_offsetHeight(&nHeight);
            spElem->get_offsetWidth(&nWidth);

            Peter Molnar

            R Offline
            R Offline
            Robert Mooney
            wrote on last edited by
            #5

            That seems to work after the content is displayed (i.e. OnDocumentComplete()), but using the offscreen rendering technique, the width and height still return 0. :sigh: I am still interested to know how to determine the width and height of an offscreen HTML document, if you have any suggestions. However, thank you for answering my original question!

            P 1 Reply Last reply
            0
            • R Robert Mooney

              That seems to work after the content is displayed (i.e. OnDocumentComplete()), but using the offscreen rendering technique, the width and height still return 0. :sigh: I am still interested to know how to determine the width and height of an offscreen HTML document, if you have any suggestions. However, thank you for answering my original question!

              P Offline
              P Offline
              Peter Molnar
              wrote on last edited by
              #6

              I am glad the second suggestion worked! As for the the offscreen method, 2 thoughts: 1.According to your experience, a not shown HTML window has no sizes. This might be surprising at first sight but it is quite obvious at the second: how a text is rendered in a HTML container window, depends on the current window's width and height, unless you specified some style either for the whole doc or just for the given element. If the window has no size, no rendering is possible.

              MSHTML::IHTMLStylePtr spStyle;
              spElem->get_style(&spStyle);
              spStyle->get_width(...);
              spStyle->get_height(...);

              This actually gets the stylesheet's current width and height data as seen from the element, but there is not much chance that it will show any realistic sizes if you didn't specify any such style beforehand. 2.Create an invisible child window on your DHTML dialog from activeX, and do on it whatever you wanted to in an "invisible" manner. Such a window should have a width and a height, as result of which a text is supposed to be rendered. Peter Molnar

              1 Reply Last reply
              0
              • R Robert Mooney

                Is there a way to determine the size of the rendered content of a CDHtmlDialog? - Rob

                M Offline
                M Offline
                Maciej Jaros
                wrote on last edited by
                #7

                Here is a working code that resizes dialog window to the size of the body. Note that you should set body margin to 0 (e.g. with CSS). Note that if you would want to also set width then you would have to set it first and recalculate and set height afterwards.

                // Called by the framework to notify an application when a document has achieved the READYSTATE_COMPLETE state.
                void CYourDialogClassDlg::OnDocumentComplete(LPDISPATCH pDisp, LPCTSTR szUrl)
                {
                CDHtmlDialog::OnDocumentComplete(pDisp, szUrl);

                // get document height (note - you need to set body margin to 0!)
                LONG nHeight;
                IHTMLDocument2 \*pDocument;
                IHTMLElement \*pElement;
                GetDHtmlDocument(&pDocument);
                pDocument->get\_body(&pElement);
                pElement->get\_offsetHeight(&nHeight);
                
                // get client to real window height difference
                LONG nHeightDiff;
                CRect rectClient;
                GetClientRect(&rectClient);
                CRect rectWindow;
                GetWindowRect(&rectWindow);
                nHeightDiff = rectWindow.Height() - rectClient.Height();
                
                // set height to fit body
                SetWindowPos(NULL, 0, 0, rectWindow.Width(), nHeight+nHeightDiff, SWP\_NOMOVE | SWP\_NOZORDER);
                

                }

                Of course you'll also need declaration in your h:

                virtual void OnDocumentComplete(LPDISPATCH pDisp, LPCTSTR szUrl);

                Nux

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups