Solved

scroll an element into view

Posted on 2006-06-14
28
1,418 Views
Last Modified: 2013-11-20
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
0
Comment
Question by:marisademeglio
  • 11
  • 6
  • 5
  • +1
28 Comments
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 16909258
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
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 16909260
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
 

Author Comment

by:marisademeglio
ID: 16911198
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
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 16911378
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
 

Author Comment

by:marisademeglio
ID: 16911511
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
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 16911622
I think you want SIF_POS not SIF_PAGE
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 16911635
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
 

Author Comment

by:marisademeglio
ID: 16911772
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
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 16911916
I'm out of ideas.
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16917989
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
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 16918054
I have had a further thought.
Does the HTMLView have a control embedded in it and this has the scrollbar, not the view.
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 44

Expert Comment

by:AndyAinscow
ID: 16918066
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
 

Author Comment

by:marisademeglio
ID: 16919756
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
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16921322
Well 1447 = the window does not have scroll bars !!!

-MAHESH
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 16922058
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
 
LVL 22

Accepted Solution

by:
mahesh1402 earned 500 total points
ID: 16934498
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
 

Author Comment

by:marisademeglio
ID: 16951127
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
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 17350770
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
 
LVL 22

Expert Comment

by:mahesh1402
ID: 17351060
>>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
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 17354805
>>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
 

Expert Comment

by:CetusMOD
ID: 17371223
PAQed with points refunded (500)

CetusMOD
Community Support Moderator
0
 

Author Comment

by:marisademeglio
ID: 17426028
Hi experts,

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

Thanks
Marisa
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 17435260
Thank You, DanRollins :)
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Generic progress indicator 6 110
ShiftLeft challenge 21 66
Annoying "thing" blocks my view 4 51
SQUD PROXY SERVER, UNIX, SLL/HTTPS 5 50
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video discusses moving either the default database or any database to a new volume.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now