Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Report Control
  New Posts New Posts RSS Feed - Scrollbars don't work with many large columns
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

Scrollbars don't work with many large columns

 Post Reply Post Reply
Author
Message
Sergio View Drop Down
Senior Member
Senior Member
Avatar

Joined: 18 September 2006
Status: Offline
Points: 216
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sergio Quote  Post ReplyReply Direct Link To This Post Topic: Scrollbars don't work with many large columns
    Posted: 29 April 2009 at 6:30am

Hello,

The report control scrollbars don't work correctly if the total width of columns exceed approximately 30000 pixels.

We are still using Codejock Version 12.0.1 (we will upgrade to the next version within one or two months).

Could you please check it and give us any feedback ?

Regards,
Sergio
Back to Top
mdoubson View Drop Down
Senior Member
Senior Member
Avatar

Joined: 17 November 2008
Status: Offline
Points: 1705
Post Options Post Options   Thanks (0) Thanks(0)   Quote mdoubson Quote  Post ReplyReply Direct Link To This Post Posted: 01 May 2009 at 12:17am
Just to give you potential idea - in some places bitmap used and function to allocate bitmap:

CBitmap bmpCache;

VERIFY(bmpCache.CreateCompatibleBitmap(pDC, W, H));

this function works only with W and H < 64K
 
So do your math with your so practical model with billions of columns
 
Also scrollbars have own restrictions
Back to Top
Sergio View Drop Down
Senior Member
Senior Member
Avatar

Joined: 18 September 2006
Status: Offline
Points: 216
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sergio Quote  Post ReplyReply Direct Link To This Post Posted: 01 May 2009 at 12:24pm
Thank you for your answer.

Yes, I agree with you for bitmaps, but I was speaking about scrollbars.

When you have large views, you must use scrollbars differently :

* Add member variables to your window :
    - int m_nViewOffsetX;
    - int m_nViewOffsetY;
    - int m_nTotalViewWidth;
    - int m_nTotalViewHeight;

* When the total width/height is larger than 30000 pixels, use the scrollbar as a percentage of the m_nTotalViewWidth/Height

* The scrollbar events : SB_LINEUP, ... modify the internal m_nViewOffsetX/Y variable and readjust the scrollbar position upon the percentage if the total width/height is larger than 30000 pixels

Doing so, you will be able to manage small and very large views using standard scrollbars.

Hope you will understand what I mean.

Regards,
Sergio
Back to Top
mdoubson View Drop Down
Senior Member
Senior Member
Avatar

Joined: 17 November 2008
Status: Offline
Points: 1705
Post Options Post Options   Thanks (0) Thanks(0)   Quote mdoubson Quote  Post ReplyReply Direct Link To This Post Posted: 01 May 2009 at 12:27pm
Right - sure - recent code only considered practical values - like few total witdh. Need to adjust for such extrema cases
Back to Top
znakeeye View Drop Down
Senior Member
Senior Member
Avatar

Joined: 26 July 2006
Status: Offline
Points: 1672
Post Options Post Options   Thanks (0) Thanks(0)   Quote znakeeye Quote  Post ReplyReply Direct Link To This Post Posted: 03 May 2009 at 5:24pm
Don't be too cocky. 30000 px is indeed a realistic value! I've been working with software that occupies up to FOUR mega-sized displays, for pathology etc.
 
Of course, support for this is an overkill, but I would still keep this in mind.
PokerMemento - http://www.pokermemento.com/
Back to Top
Sergio View Drop Down
Senior Member
Senior Member
Avatar

Joined: 18 September 2006
Status: Offline
Points: 216
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sergio Quote  Post ReplyReply Direct Link To This Post Posted: 04 May 2009 at 3:39am
Yes, I know that's an extreme case, but we have it.

We have two big lists with many columns inserted in one big report control for a kind of comparator.

In order to help you to enhance your report control more quickly, here is the kind of code needed :




// Return the maximum range of windows scroll bars
int GetScrollbarsRangeMax()
{
     return 30000;
}




// Set scroll bar data information, do not substract iPageSize from iPosMax
// pWnd = Window owning the scrollbars
BOOL SetScrollbarDataInfo(CWnd* pWnd, BOOL bHorizontalScrollbar, BOOL bForceShowDisabled, int iPos, int iPosMax, int iPageSize)
{
     HWND hwnd = pWnd->GetSafeHwnd();
     if ( !::IsWindow( hwnd ) )
          return FALSE;

     // Update scroll bars
     SCROLLINFO info;
     int iScrollbarsRangeMax = gGUI.GetScrollbarsRangeMax();

     if ( bForceShowDisabled )
     {
          ::memset( &info, 0, sizeof( info ) );
          info.cbSize = sizeof( info );

          info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
          info.nMin = 0;
          info.nMax = 2;
          info.nPage = 5;
          info.nPos = 0;
          if ( bHorizontalScrollbar )
          {
               ::ShowScrollBar( hwnd, SB_HORZ, TRUE );
               ::SetScrollInfo( hwnd, SB_HORZ, &info, TRUE );
               ::EnableScrollBar( hwnd, SB_HORZ, ESB_DISABLE_BOTH );
          }
          else
          {
               ::ShowScrollBar( hwnd, SB_VERT, TRUE );
               ::SetScrollInfo( hwnd, SB_VERT, &info, TRUE );
               ::EnableScrollBar( hwnd, SB_VERT, ESB_DISABLE_BOTH );
          }
     }
     else
     {
          if ( iPosMax <= iPageSize )
          {
               // Hide the scroll bar
               if ( bHorizontalScrollbar )
                    ::ShowScrollBar( hwnd, SB_HORZ, FALSE );
               else
                    ::ShowScrollBar( hwnd, SB_VERT, FALSE );
          }
          else
          {
               // Show the scroll bar
               if ( bHorizontalScrollbar )
                    ::ShowScrollBar( hwnd, SB_HORZ, TRUE );
               else
                    ::ShowScrollBar( hwnd, SB_VERT, TRUE );

               if ( iPosMax >= iScrollbarsRangeMax )
               {
                    // Process the scroll bar differently if the total display height is too big
                    if ( bHorizontalScrollbar )
                         ::EnableScrollBar( hwnd, SB_HORZ, ESB_ENABLE_BOTH );
                    else
                         ::EnableScrollBar( hwnd, SB_VERT, ESB_ENABLE_BOTH );

                    ::memset( &info, 0, sizeof( info ) );
                    info.cbSize = sizeof( info );

                    info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
                    info.nMin = 0;
                    info.nMax = iScrollbarsRangeMax;
                    info.nPage = 1;
                    info.nPos = iScrollbarsRangeMax * iPos / ( iPosMax - iPageSize );
                    if ( bHorizontalScrollbar )
                         ::SetScrollInfo( hwnd, SB_HORZ, &info, TRUE );
                    else
                         ::SetScrollInfo( hwnd, SB_VERT, &info, TRUE );
               }
               else
               {
                    // Process the scroll bar normally
                    ::memset( &info, 0, sizeof( info ) );
                    info.cbSize = sizeof( info );

                    info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
                    info.nMin = 0;
                    info.nMax = iPosMax;
                    info.nPage = iPageSize;
                    info.nPos = iPos;

                    if ( bHorizontalScrollbar )
                         ::EnableScrollBar( hwnd, SB_HORZ, ESB_ENABLE_BOTH );
                    else
                         ::EnableScrollBar( hwnd, SB_VERT, ESB_ENABLE_BOTH );

                    if ( bHorizontalScrollbar )
                         ::SetScrollInfo( hwnd, SB_HORZ, &info, TRUE );
                    else
                         ::SetScrollInfo( hwnd, SB_VERT, &info, TRUE );
               }
          }
     }

     return TRUE;
}




// Process OnHScroll(...) & OnVScroll(...) and return the new scroll bar position
//
// Example :
//
//void CWndName::OnHScroll(UINT nSBCode, UINT nPos, //CScrollBar* pScrollBar)
//{
//     CRect r;
//     GetClientRect( &r );
//
//     SetViewOffsetXY(
//          ProcessOnVHScroll( nSBCode, nPos, m_iDisplayPosX, m_iMinimumDisplaySizeX, r.Width(), m_iScrollbarsStepSize ),
//          m_iDisplayPosY );
//
//     CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
//}
//
//void CWndName::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
//{
//     CRect r;
//     GetClientRect( &r );
//
//     SetViewOffsetXY(
//          m_iDisplayPosX,
//          ProcessOnVHScroll( nSBCode, nPos, m_iDisplayPosY, m_iMinimumDisplaySizeY, r.Height(), m_iScrollbarsStepSize ) );
//
//     CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
//}
//
int ProcessOnVHScroll(UINT nSBCode, UINT nPos, int iPos, int iPosMax, int iPageSize, int iStepsSize)
{
     int iMaxPos = iPosMax - iPageSize;
     int iCurPos = iPos;
     int iScrollbarsRangeMax = gGUI.GetScrollbarsRangeMax();

     if ( iPosMax > iScrollbarsRangeMax )
     {
          iMaxPos = iScrollbarsRangeMax;
     }

     // Determine the new position of scroll box
     switch( nSBCode )
     {
          case SB_TOP: // Scroll to far top
               iCurPos = 0;
               break;

          case SB_BOTTOM: // Scroll to far bottom
               iCurPos = iMaxPos;
               break;

          case SB_ENDSCROLL: // End scroll
               break;

          case SB_LINEUP: // Scroll up
               iCurPos -= iStepsSize;
               break;

          case SB_LINEDOWN: // Scroll down
               iCurPos += iStepsSize;
               break;

          case SB_PAGEUP: // Scroll one page up
               iCurPos -= iPageSize;
               break;

          case SB_PAGEDOWN: // Scroll one page down
               iCurPos += iPageSize;
               break;

          case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position of the scroll box at the end of the drag operation
               if ( iPosMax > iScrollbarsRangeMax )
                    iCurPos = nPos * ( iPosMax - iPageSize ) / iScrollbarsRangeMax;
               else
                    iCurPos = nPos;
               break;

          case SB_THUMBTRACK: // Drag scroll box to specified position. nPos is the position that the scroll box has been dragged to
               if ( iPosMax > iScrollbarsRangeMax )
                    iCurPos = nPos * ( iPosMax - iPageSize ) / iScrollbarsRangeMax;
               else
                    iCurPos = nPos;
               break;
     }

     iCurPos = min( iCurPos, iPosMax - iPageSize );

     return iCurPos;
}

      
Regards,
Sergio
Back to Top
mdoubson View Drop Down
Senior Member
Senior Member
Avatar

Joined: 17 November 2008
Status: Offline
Points: 1705
Post Options Post Options   Thanks (0) Thanks(0)   Quote mdoubson Quote  Post ReplyReply Direct Link To This Post Posted: 04 May 2009 at 4:31am
OK - what prevent you to use your own scroll support in the View your Report belong to? You don't need to use built-in Horizontal Scrollbar.
You can use your own steps - e.g. on case SB_LINEUP and case SB_LINEDOWN can be treat as 1 or 10 or 100 columns jump
Back to Top
Sergio View Drop Down
Senior Member
Senior Member
Avatar

Joined: 18 September 2006
Status: Offline
Points: 216
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sergio Quote  Post ReplyReply Direct Link To This Post Posted: 04 May 2009 at 11:01am
I took a look at your code and you should not use value "nPos" of the OnHScroll(...)/OnVScroll(...). This value is limited to 16 bits due to the Windows message.

In the OnHScroll(...) & OnVScroll(...) methods, I think you just have to retrieve this value using the GetScrollInfo(...) which will give you a 32 bits value.

We don't make this change because we don't want to have any conflicts with your future changes.

Regards,
Sergio
Back to Top
mdoubson View Drop Down
Senior Member
Senior Member
Avatar

Joined: 17 November 2008
Status: Offline
Points: 1705
Post Options Post Options   Thanks (0) Thanks(0)   Quote mdoubson Quote  Post ReplyReply Direct Link To This Post Posted: 04 May 2009 at 11:05am
Right - I think our scroolbar based on 16 bit restriction. I don't propose you to modify Core but make desired implementation on App level.
Back to Top
Sergio View Drop Down
Senior Member
Senior Member
Avatar

Joined: 18 September 2006
Status: Offline
Points: 216
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sergio Quote  Post ReplyReply Direct Link To This Post Posted: 05 May 2009 at 9:00am
Ok, we will do your job and fix your OnHScroll(...) & OnVScroll(...).

Regards,
Sergio
Back to Top
mdoubson View Drop Down
Senior Member
Senior Member
Avatar

Joined: 17 November 2008
Status: Offline
Points: 1705
Post Options Post Options   Thanks (0) Thanks(0)   Quote mdoubson Quote  Post ReplyReply Direct Link To This Post Posted: 05 May 2009 at 9:50am
Very good - if you make a simple test case I can try it and if it properly supported any scroll size - we can use it in the Core - I should be sure that it will also works in ActiveX (e.g. for old VB6)
Back to Top
mdoubson View Drop Down
Senior Member
Senior Member
Avatar

Joined: 17 November 2008
Status: Offline
Points: 1705
Post Options Post Options   Thanks (0) Thanks(0)   Quote mdoubson Quote  Post ReplyReply Direct Link To This Post Posted: 05 May 2009 at 5:47pm
In some moment you was interested in Expand-Collapse action with all deep levels covered - I propose you to test current app but you did not try?
Back to Top
Sergio View Drop Down
Senior Member
Senior Member
Avatar

Joined: 18 September 2006
Status: Offline
Points: 216
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sergio Quote  Post ReplyReply Direct Link To This Post Posted: 07 May 2009 at 12:39pm
Could you please give me the reference of that post (the link) ?

------

Take a look in the Microsoft MSDN Library - Visual Studio 2008 - CWnd::OnHScroll(...), their example uses 32 bits values with correct implementation (look at the curpos variable).

The new code will work as the previous one, but will just use a 32 bits value as input instead of 16 bits.

Just do this kind of change to your code (do the same for OnVScroll(...)) :


Your code :

     void CXTPReportControl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
     {
          if (pScrollBar != NULL)
          {
               CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
               return;
          }
          int nCurPos = m_nLeftOffset;
     
          ...




32 bits fix :

     void CXTPReportControl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
     {
          if (pScrollBar != NULL)
          {
               CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
               return;
          }

          // Use 32 bits scrollbar position instead of 16 bits - End
          nPos = GetScrollPos(SB_HORZ);

          int nCurPos = m_nLeftOffset;
     
          ...


Hope you will agree now and see that you will have no further impacts.

Regards,
Sergio
Back to Top
mdoubson View Drop Down
Senior Member
Senior Member
Avatar

Joined: 17 November 2008
Status: Offline
Points: 1705
Post Options Post Options   Thanks (0) Thanks(0)   Quote mdoubson Quote  Post ReplyReply Direct Link To This Post Posted: 07 May 2009 at 2:52pm
it was 2 different threads - http://forum.codejock.com/forum_posts.asp?TID=13387 (about multi-selection)
and it was another thread about the problem with expand all function which not covered full deep of hierarchy but I can't find it now?
Back to Top
Sergio View Drop Down
Senior Member
Senior Member
Avatar

Joined: 18 September 2006
Status: Offline
Points: 216
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sergio Quote  Post ReplyReply Direct Link To This Post Posted: 08 May 2009 at 6:08am
For the first thread, I thought it was ended and closed. I will look and give you an answer soon.


For the second one, we solved it like that (I can't retrieve it too.) :


     BOOL COverridenXTPReportControl::FFullExpandAll()
     {
          //ExpandAll();   <--------   22.03.2007 - Doesn't work properly (only one level is expanded)

          CXTPReportRows* pRows = GetRows();
          if (pRows)
          {
               CXTPReportRow* pRow;
               for (int i=0; i<pRows->GetCount(); i++)
               {
                    pRow = pRows->GetAt(i);
                    if (pRow && pRow->HasChildren() && !pRow->IsExpanded())
                    {
                         pRow->SetExpanded(TRUE);
                    }
               }

               return TRUE;
          }

          return FALSE;
     }



Regards,
Sergio
Back to Top
Sergio View Drop Down
Senior Member
Senior Member
Avatar

Joined: 18 September 2006
Status: Offline
Points: 216
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sergio Quote  Post ReplyReply Direct Link To This Post Posted: 08 May 2009 at 12:10pm
I never posted the ExpandAll() query.

It was someone else : https://forum.codejock.com/forum_posts.asp?TID=13445&KW=expandall

I found the clue by myself.
Sergio
Back to Top
mdoubson View Drop Down
Senior Member
Senior Member
Avatar

Joined: 17 November 2008
Status: Offline
Points: 1705
Post Options Post Options   Thanks (0) Thanks(0)   Quote mdoubson Quote  Post ReplyReply Direct Link To This Post Posted: 08 May 2009 at 12:17pm
Thanks, Sergio.
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.04
Copyright ©2001-2021 Web Wiz Ltd.

This page was generated in 0.156 seconds.