[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

How to synchronize Scrollbars in more then one child windows in MFC  MDI applications?

Posted on 2004-09-20
20
Medium Priority
?
1,106 Views
Last Modified: 2012-05-05
Hai Friends,
       hope everybody are enjoying the life.

Friends, I got a problem, please help me out.

 I'm coding in VC++, and using MDI application.
Problem is,
If in one child window if I drag a Scroll bar, then simulataneously the scroll bar in other child window also has to move!!!!

Please help me out as early as possible.

Thanks a lot...

Have a nice day!

0
Comment
Question by:madanponna
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 8
20 Comments
 
LVL 48

Assisted Solution

by:AlexFM
AlexFM earned 800 total points
ID: 12110727
This is a way to create MFC MDI application with CScrollView class, which scrolls all it's views synchronously. If number of child views are opened, scrolling of one view scrolls by the same way all others.

1) Create MFC MDI application (I called it Test). On the last step of MFC Application Wizard select CScrollView class instead of CView.
2) Add WM_VSCROLL and WM_HSCROLL message handlers to CTEstView classes and fill them by the following way:

void CTestView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    AfxGetMainWnd()->PostMessage(WM_APP + 1, (WPARAM)this, 0);
   
    CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
}

void CTestView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    AfxGetMainWnd()->PostMessage(WM_APP + 1, (WPARAM)this, 0);
   
    CScrollView::OnHScroll(nSBCode, nPos, pScrollBar);
}

3) Open MainFrm.h file and add this line to message map:

    LRESULT OnMessageScroll(WPARAM wParam, LPARAM lParam);     // add this line
    DECLARE_MESSAGE_MAP()                                                          // before this line

4) Open MainFrm.cpp file and add this include line:

#include <afxcoll.h>

5) Add the following code to the beginning of MainFrm.cpp file (before CMainFrame class functions):

// CDocEnumerator — Enumerates all the documents in an MFC application.
// To use:
//
//    CDocEnumerator it;
//    CDocument* pdoc;
//    while ((pdoc=it.Next())!=NULL) {
//       // do something
//    }
//
// Source: http://msdn.microsoft.com/msdnmag/issues/04/05/CQA/
// Paul DiLascia
// From the May 2004 issue of MSDN Magazine.
//
class CDocEnumerator {
private:
    CPtrArray m_doclist; // array of all docs
    int m_iPos;          // current position in array
public:
    CDocEnumerator();
    CDocument* Next();
    void Reset() { m_iPos=-1; }
};


//
CDocEnumerator::CDocEnumerator() {
    CWinApp* pApp = AfxGetApp();
    POSITION pos = pApp->GetFirstDocTemplatePosition();
    while (pos!=NULL) {
        CDocTemplate* pDocTemplate = pApp->GetNextDocTemplate(pos);
        POSITION pos2 = pDocTemplate->GetFirstDocPosition();
        while (pos2!=NULL) {
            m_doclist.Add(pDocTemplate->GetNextDoc(pos2));
        }
    }
    Reset();
}

//////////////////
// Fetch next document.
//
CDocument* CDocEnumerator::Next() {
    if (++m_iPos < m_doclist.GetSize()) {
        return (CDocument*)m_doclist[m_iPos];
    }
    return NULL;
}

6) Add this line to CMainFrame message map, MainFrm.cpp file:

    ON_MESSAGE(WM_APP + 1, OnMessageScroll)          // add this line
END_MESSAGE_MAP()                                                 // before this line

7) Add the following code to MainFrm.cpp file:

LRESULT CMainFrame::OnMessageScroll(WPARAM wParam, LPARAM lParam)
{
    CScrollView* pSourceView = (CScrollView*)wParam;
    CDocEnumerator it;
    CDocument* pdoc;

    while ((pdoc=it.Next())!=NULL)
    {
        POSITION pos = pdoc->GetFirstViewPosition();
       
        CScrollView* pView = (CScrollView*)pdoc->GetNextView(pos);
       
        if ( pView != pSourceView )
        {
            CPoint pt = pSourceView->GetScrollPosition();
            pView->ScrollToPosition(pt);
        }
    }
   
    return 0;
}
0
 

Author Comment

by:madanponna
ID: 12111940
Hai Alex,
      I'm very very glad to see your answer, thanks a lot.

But Alex, I'm extreamly sorry, as I did not explained my problem clearly.
But your answer is perfectly correct to my question.

Actully my problem is,  as I already said , I'm using MDI application.

And as you wrote in your answer that to inherit from CScrollView, but as per the requirement I inherited from CView class.

what i'm doing is, i'm splitting the child window into TWO panes in CChildFrm.cpp in OnCreateClient() function using CSplitterWnd object.

First Pane(0,0) is a class derived from CListView. And Second Pane(0,1) also derived from CListView.

I created a check box on the MainFrame, so that when I check it, Scrollbar synchronize should occur.

Suppose assume that there are more than one child window.
After checking the check box for scrollbar synchronization,
****whenever I drag a scrollbar in Pane(0,0) in one child window , then Pane(0,0) of other Child window also has to be dragged.

****Similarly whenever I drag a scrollbar in Pane(0,1) in one window , then Pane(0,1) of other Child window also has to be dragged.

Dear Alex, please solve this problem!!!!!!

Thanks a lot for your previous answer.

Waiting.....




0
 
LVL 45

Accepted Solution

by:
AndyAinscow earned 400 total points
ID: 12121872
From the description of a CView
A view handles scroll-bar messages with the CWnd::OnHScroll and CWnd::OnVScroll member functions
Alex has suggested you override those functions.  

What he did was provide a sample of code not specific to your question BUT one that should function as you require.  Ignore the CScrollView base class and try it with your CListView based class.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:madanponna
ID: 12131271
Thanks Andy!!!!

I changed it to CListView, It is working!!!!!!!

But when I  scroll the pane(0,0) in one of the child window, all other scrollbars of pane(0,0) are scrolled but LIST ITEMS are NOT repainting!!!!

I mean the data in other  panes(0,0) are not repainted and even the List Control HEADER is moving !!!!!!
But this is not happening with the pane(0,0) in which i'm dragging the scrollbar!!!

Please tell me how to solve this problem!!! I used Invalidate() but no use!!!

One more doubt is , in the below code which Alex sent for my question ,
/////////////////////////////////////////////////////////////////////////////////////
7) Add the following code to MainFrm.cpp file:
LRESULT CMainFrame::OnMessageScroll(WPARAM wParam, LPARAM lParam)
{
    CScrollView* pSourceView = (CScrollView*)wParam;
    CDocEnumerator it;
    CDocument* pdoc;

    while ((pdoc=it.Next())!=NULL)
    {
        POSITION pos = pdoc->GetFirstViewPosition();
       
        CScrollView* pView = (CScrollView*)pdoc->GetNextView(pos);
       
        if ( pView != pSourceView )
        {
            CPoint pt = pSourceView->GetScrollPosition();
            pView->ScrollToPosition(pt);
        }
    }
   
    return 0;
}
/////////////////////////////////////////////////////////////////////////


In place of "CScrollView" what I have to use? at present scroll bars are moving with the same above code.

But is it correct?

Because , the left pane(0,0) , say class name CLeftPane ,is derived from CListView.
And the right pane(0,1) , say class name CRightPane , is also derived from CListView.

Now in place of "CScrollView", what I have to use? still "CScrollView" is ok?

________________________

Also please see my other question at :
           http://www.experts-exchange.com/Programming/Programming_Languages/Q_21131575.html

Thanks!!!!


Waiting....






0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 12131528
If it is based on CListView try replacing CScrollView with CListView.
Does that sort it out?
0
 

Author Comment

by:madanponna
ID: 12132403
Hai,
  I pasted CListView in place of CScrollView but I get error as below:

error C2039: 'GetScrollPosition' : is not a member of 'CListView'

????
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 12132687
OK.  Get a pointer to the CListView and then get the underlying list control

pListView->GetListCtrl().GetScrollPosition()

I think the above line is what you would require.
0
 

Author Comment

by:madanponna
ID: 12133114
But Andy, CListView does not have GetScrollPosition() function but it has, GetScrollPos(int nBar), this function returns postion of the scrollbar. I dont find use of GetScrollPos()!!!

What to do now? and more over how to :

/////////////////////////////
But when I  scroll the pane(0,0) in one of the child window, all other scrollbars of pane(0,0) are scrolled but LIST ITEMS are NOT repainting!!!!

I mean the data in other  panes(0,0) are not repainted and even the List Control HEADER is moving !!!!!!
But this is not happening with the pane(0,0) in which i'm dragging the scrollbar!!!

Please tell me how to solve this problem!!! I used Invalidate() but no use!!!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

Waiting...
And thanks a lot for quick responses!
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 12133184
GetScrollPos(SB_HORZ) or SB_VERT

To repaint after you have scrolled you can use Invalidate() then  UpdateWindow().

Could you zip and e-mail your project to me, I would have a quick look tonight.  info@ainscow.ch
0
 

Author Comment

by:madanponna
ID: 12133334
Andy, actually i'm in office now, and I cant send code due to security reasons.

I try with you tips.
But really i'm very much confused!!!!
0
 

Author Comment

by:madanponna
ID: 12133618
I did as  you told :

LRESULT CMainFrame::OnMessageScroll(WPARAM wParam, LPARAM lParam)
{
    CScrollView* pSourceView = (CScrollView*)wParam;
    CDocEnumerator it;
    CDocument* pdoc;

    while ((pdoc=it.Next())!=NULL)
    {
        POSITION pos = pdoc->GetFirstViewPosition();
       
        CScrollView* pView = (CScrollView*)pdoc->GetNextView(pos);
       
        if ( pView != pSourceView )
        {
            CPoint pt = pSourceView->GetScrollPosition();
            pView->ScrollToPosition(pt);
->           Invalidate();
->          UpdateWindow();
        }
    }
   
    return 0;
}

Arrows indicate where I'm calling Invalidate and UpdateWindow functions.

But no use !!!!!

Same problem, unable to repaint after scrolling !!!!!

0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 12134071
No no no, Don't scroll the view itself, scroll the list control that is in the view.
Also you have a CListView -DO NOT CAST IT TO CScrollView, cast it to a CListView and use GetListCtrl() to get the underlying list control.  It is that that you want to scroll the contents of.
 
0
 

Author Comment

by:madanponna
ID: 12135038
Andy, in MDI Applications , we wont find Scroll bars, only to the child windows scroll bars will be there, am I right?

And i'm scrolling only the List view's scroll bar.
Andy , here in India, it is night 10pm. I'm leaving now. I catch you tommarrow.

But a milliion  thanks  for your continous replies!!!!!

Waiting for the right answer!!!!!
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 12136208
in MDI Applications , we wont find Scroll bars, only to the child windows scroll bars will be there, am I right?

Not really - any window COULD have a scrollbar, just does it make sense for it to have one?



And i'm scrolling only the List view's scroll bar

The code you posted you are casting to a CScrollView, not to a CListView AND you need to get the scrollbar of the CListCtrl which is the functional bit inside the CListView.  Just scrolling the view itself should scroll the control (header moving), not the contents of the list.
0
 

Author Comment

by:madanponna
ID: 12141011
Hai Andy,
             I'm doing as you said, but once I cast CScrollView to CListView,
then I cant use GetScrollPostion() function.
But I can use GetScrollPos(int nBar) function, this function return back scroll position,
But  problem is, to which function I have to pass the scroll position which I got from GetScrollPos() function???

Waiting....
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 12141056
You want to scroll the ListControl.  So you need a pointerto the list control you want to use SetScrollPos with.
0
 

Author Comment

by:madanponna
ID: 12142566
Andy,   I did as you said, as below:  

while ((pdoc=it.Next())!=NULL)
{
        POSITION pos = pdoc->GetFirstViewPosition();
       
        CListCtrl* pView = (CListCtrl*)pdoc->GetNextView(pos);
       
        if ( pView != pSourceView )
        {
            int pScrollPos = pSourceView->GetScrollPos(SB_VERT);
            pView->SetScrollPos(SB_VERT,pScrollPos,TRUE);

        }
}

but when I drag the vertical scroll bar, only in one view that is in which i'm dragging the scrollbar , all the  columns are moving. but in remaining views only vertical scrollbar is moving , columns data is not moving!!!

Waiting...
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 12143058
Do you invalidate the view after the SetScrollPos ?  (We are getting closer - the scroll bar does show an effect ! )
0
 

Author Comment

by:madanponna
ID: 12407667
Thanks to all for helping to solve my problem.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

There is an easy way, in .NET, to centralize the treatment of all unexpected errors. First of all, instead of launching the application directly in a Form, you need first to write a Sub called Main, in a module. Then, set the Startup Object to th…
This article will show, step by step, how to integrate R code into a R Sweave document
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
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.
Suggested Courses

656 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