scroll an element into view

Hi experts,

I have a CHtmlView window which displays an HTML page.   I need to ensure that an element is in view.  If it is already in view, I don't want the display to jump around.  If it is not in view, it should be scrolled into view.

The last requirement is easy with IHTMLELEMENT's ScrollIntoView function.  However, I can't use this all the time because it looks jumpy.  I only want to use it when I really need to.  

I can already get element coordinates, that's no problem.  But, my question is, how can I tell what portion of the HTML page is being shown in the view?  I've tried getting ScrollInfo and ScrollBarInfo etc, all with no luck.

Thanks
Marisa
marisademeglioAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AndyAinscowFreelance programmer / ConsultantCommented:
Assuming you are talking about when the page is first displayed.
You can use
CRect rc;
pWnd->GetClientRect(&rc);  //pWnd is a pointer to the window that displays the HTML page

now rc.Height() will give you the display height (rc.Width() the display width).  As you say you have the co-ordinates of the control then you can check simply if the control is in the area being displayed and scroll if it is not visible.
0
AndyAinscowFreelance programmer / ConsultantCommented:
If you are not talking about first display - control must ALWAYS be visible then it might be better to modify the co-ordinates of the control rather than scrolling.
0
marisademeglioAuthor Commented:
I need to do this continuously since my program gives sequential highlighting of HTML text elements.  Basically if I call element->ScrollIntoView every time, the IE control positions the element at the top of its view, which looks jumpy and users hate it.  If the element is already visible, there's no reason to explicitly scroll to it.  This is what I need to calculate.

I don't quite get what you mean by modifying the coordinates of the control.  The IE control?

0
Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

AndyAinscowFreelance programmer / ConsultantCommented:
Modifyig the co-ordinates of the control.
Can you manually reposition it (like MoveWindow) ?



<I've tried getting ScrollInfo and ScrollBarInfo etc, all with no luck.>

maybe post some code how you have tried that.
0
marisademeglioAuthor Commented:
The whole function is here:
http://svn.sourceforge.net/viewcvs.cgi/amis/trunk/amis/AmisGuiMFC/Brain/TextRenderBrain.cpp?annotate=1551
starting at line 595

Of course I'd given up on scroll bar stuff so I deleted it from the code, but it had looked something like this (for example, to get page info):

SCROLLINFO si;
ZeroMemory(&si, sizeof(si));
si.cbSize = sizeof(si);
si.fMask = SIF_PAGE;

wndHtmlView->GetScrollInfo(SB_VERT, &si);

...resulting in no values in "si".  There was a scrollbar, it was vertical, and it was enabled.  I don't know what the problem was.  It could be that I was querying the wrong window (the HTML view) for its scroll bar.  I tried wndHtmlView->GetParentFrame()->GetScrollInfo(...) with the same results.
0
AndyAinscowFreelance programmer / ConsultantCommented:
I think you want SIF_POS not SIF_PAGE
0
AndyAinscowFreelance programmer / ConsultantCommented:
Just stick a button/menu and call a piece of code to test the GetScrollInfo.  It should only take a minute to put into place.
0
marisademeglioAuthor Commented:
http://svn.sourceforge.net/viewcvs.cgi/amis/trunk/amis/AmisGuiMFC/Brain/TextRenderBrain.cpp?view=annotate

Line 603.

I traced through and GetScrollInfo is called.  Its values are a bunch of zeros, like I saw before.
0
AndyAinscowFreelance programmer / ConsultantCommented:
I'm out of ideas.
0
mahesh1402IT ProfessionalCommented:
marisademeglio,
Have you tried to call individual functions to retrieve scrollbar info like GetScrollPos() / GetScrollRange() ?

Also as per documentation :
If the function retrieved any values, the return value is nonzero.
If the function does not retrieve any values, the return value is zero. To get extended error information, call GetLastError.
Have you checked that with GetLastError() ?

-MAHESH
0
AndyAinscowFreelance programmer / ConsultantCommented:
I have had a further thought.
Does the HTMLView have a control embedded in it and this has the scrollbar, not the view.
0
AndyAinscowFreelance programmer / ConsultantCommented:
There is an m_wndBrowser inside the view

try this

SCROLLINFO si;
ZeroMemory(&si, sizeof(si));
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;

wndHtmlView->m_wndBrowser.GetScrollInfo(SB_VERT, &si);
0
marisademeglioAuthor Commented:
I tried:

wndHtmlView->m_wndBrowser.GetScrollInfo(SB_VERT, &si);

with no better results.

I also tried calling GetLastError after the above line, as well as the first version of it (w/o using m_wndBrowser), and both times got 1447, whatever that means -- I'll look into it but can't right now.
0
mahesh1402IT ProfessionalCommented:
Well 1447 = the window does not have scroll bars !!!

-MAHESH
0
AndyAinscowFreelance programmer / ConsultantCommented:
Using spy++ I find the 'view' seems to be a further child of this m_wndBrowser.  Exactly how to *guarantee* one gets this child I don't know at present.
0
mahesh1402IT ProfessionalCommented:
You may use IHTMLElement2::get_scrollTop() and IHTMLElement2::get_scrollHeight() to obtain scroll info in this case.

Refer this article at codeproject 'Programmatically scrolling WebBrowser control from Visual C/C++'
http://www.codeproject.com/miscctrl/scrollbrowser.asp <== Here its given that browser window does not accept Windows scroll messages. Calling the MFC GetScrollInfo APIs does not do anything. But there is a way to use IHTMLElement2 interface. Refer src code how to obtain IHTMLElement2 interface.

Scroll down and refer following comment at end of the article : 'How to get scroll bar position?'
http://www.codeproject.com/miscctrl/scrollbrowser.asp?df=100&forumid=2537&exp=0&select=780783#xx780783xx <--

You can write the code below to get the scroll bar position....

HRESULT hr;

// get the document dispatch from browser
IDispatch *pDisp = GetHtmlDocument();
ASSERT( pDisp ); //if NULL, we failed

IHTMLDocument2 *pDocument = NULL;
hr = pDisp->QueryInterface( IID_IHTMLDocument2, (void**)&pDocument );
ASSERT( SUCCEEDED( hr ) );
ASSERT( pDocument );

IHTMLElement *pBody = NULL;
hr = pDocument->get_body( &pBody );
ASSERT( SUCCEEDED( hr ) );
ASSERT( pBody );

// from body we can get element2 interface,
// which allows us to do scrolling
IHTMLTextContainer *pContainer = NULL;
hr = pBody->QueryInterface(IID_IHTMLTextContainer,(void**)&pContainer);
ASSERT(SUCCEEDED(hr));
ASSERT( pContainer );

CPoint ScrollPos;
pContainer->get_scrollTop(&ScrollPos.x);
pContainer->get_scrollLeft(&ScrollPos.y);

CString str;
str.Format("Top: %ld, Left: %ld", ScrollPos.x, ScrollPos.y);
AfxMessageBox(str);

pDisp->Release();


-MAHESH


0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
marisademeglioAuthor Commented:
Hi,

Thanks for the suggestion.

I tried it and it returns 0, 0 for the XY coords of the scroll bar, no matter of its actual position.

My code is here:
http://svn.sourceforge.net/viewcvs.cgi/amis/trunk/amis/AmisGuiMFC/Brain/TextRenderBrain.cpp?view=markup

The function is called "isElementInView(..)"

Marisa
0
AndyAinscowFreelance programmer / ConsultantCommented:
Final comment by questioner -
Hi,

Thanks for the suggestion.

I tried it and it returns 0, 0 for the XY coords of the scroll bar, no matter of its actual position.



That implies method suggested by mahesh1402 is NOT working.
0
mahesh1402IT ProfessionalCommented:
>>That implies method suggested by mahesh1402 is NOT working.

may be Dan missed last comment....anyways....

BUT.....METHOD SUGGESTED ABOVE IS 100% WORKABLE FOR CHtmlView scrollbars.....you can just create html view put above code on view function, execute ...manually scroll scrollbars and test positions.....

Otherwise simply you can test that following way just to ensure its working  :

-Donwnload sample Src files from : http://www.codeproject.com/miscctrl/chtmlview_search.asp
-Open Src file CHtmlView_SearchView.CPP
-Edit any function e.g. CCHtmlView_SearchView::FindText() and copy paste above code at end of function
-Compile & Excute Project, Set Scroll bars manually to some position, click on Search type something press ENTER

-----You will get MessageBox with proper scrollbar positions !

When I had look at author's srcfile It wasnot clear to me how instance initialize in GetDoc() function from other src files as its huge project on sourceforge.

Anyways Just put this to clear above code work to locate CHtmlView scrollbar positions and it works for other too as per comments at last of this article : http://www.codeproject.com/miscctrl/scrollbrowser.asp

-MAHESH
0
AndyAinscowFreelance programmer / ConsultantCommented:
>>I very rarely recommend a "override" when the Asker has said that he could not get the solution to work, but I feel that this is a valid exception to that general rule.


From our position we can only guess and assume - the questioner is the only one that knows for sure.  If he says it does not work then we should believe him.  (The questioner posted a question and offered points for a solution, did he get one?  Should this 'general rule' actually have an exception?  I'll leave it up to the moderators.  Maybe AnnieMod ought to be questioned for clarification on EE standing on matters like this.).
0
CetusMODCommented:
PAQed with points refunded (500)

CetusMOD
Community Support Moderator
0
marisademeglioAuthor Commented:
Hi experts,

I got Mahesh's solution to work.  Sorry to leave you hanging; been busy.

Thanks
Marisa
0
mahesh1402IT ProfessionalCommented:
Thank You, DanRollins :)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.