Solved

Problem using TScroller if unit !=1

Posted on 1997-03-19
9
324 Views
Last Modified: 2013-12-03
I develop a program under Windows95 using Borland C++ 5.00 and OWL5.0.
The scroll box (thumb) desn't scroll the whole range if the unit parameter (e.g. YUnit) of TScroller differs from 1, but the arrows at the end of the scrollbar work correctly. Furthermore if the range parameter (YRange) is a little value (e.g. 6) the scrollbar doesn't appear. See the sample program of BC++ 5.00 in the examples\owl\classes\scroller directory.
Does anybody know a solution for my problem? Thanks.
0
Comment
Question by:moczar
[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
9 Comments
 

Author Comment

by:moczar
ID: 1298678
Edited text of question
0
 

Expert Comment

by:pangofil
ID: 1298679
You have to make your window scrollable :

put in your constructor follow :

{
...

Attr.tyle |= WS_HSCROLL | WS_VSCROLL ;
Sceoller = TScroller ( ... ) ;

...
}


It works fro me in 100% of cases.

Hope it helps
0
 

Author Comment

by:moczar
ID: 1298680
This is a code fragment of the Borland OWL sample program (examples\owl\classes\scroller\scrollex.cpp). It generates the described error for me.

const int XUnits = 7;
const int YUnits = 16;
const int XRange = 80;
const int YRange = 6; //60; was originally

// class TScrollWindow
class TScrollWindow : public TWindow {
  public:
    TScrollWindow(TWindow* parent = 0, const char* title = 0);
    void Paint(TDC& dc, bool, TRect&);
};

// Constructor for a TScrollWindow, sets scroll styles and
// constructs the Scroller object.

TScrollWindow::TScrollWindow(TWindow* parent, const char* title)
:
  TWindow(parent, title)
{
  Attr.Style |= WS_VSCROLL | WS_HSCROLL;
  Scroller = new TScroller(this, XUnits, YUnits, XRange, YRange);
}


0
SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

 
LVL 1

Expert Comment

by:jasonc
ID: 1298681
You cannot just change ranges like that and expect it to work properly.  Keep in mind that TScroller does not care what is in the window.  YOU are responsible for resetting the scrollers range and units every time the user resizes the window, etc.  If you set the range to 6 it's going to let you hit the down arrow 5 times and that's it. If you don't get all the way to the bottom of what you're trying to display it's your own fault.

0
 

Author Comment

by:moczar
ID: 1298682
Thank you for the answer. But it is not the content of the window  I have problems with. I have problem with the scrollbar itself.

Problem 1.: If the YRange is a small value (e.g. 6) the scrollbar doesn't appear. Why?

Problem 2.: If the YRange is a bigger value (e.g.60) the scrollbar appears and the arrows at its end work correctly, that is you can hit the down arrow 59 times. However if you don't scroll the window with the arrows but with the thumb (the scroll rectangle) it scrolls less, about 47 steps. In other words, the arrows at the end of it work properly, but dragging the thumb rectangle and pulling it from one end of the scrollbar to the other doesn't provide as big scrolling as the arrows did. Why?

0
 
LVL 15

Accepted Solution

by:
NickRepin earned 100 total points
ID: 1298683
There are errors in implementation of TScroller in OWL (namely in TScroller::SetPageSize()).
It is not work correctly if XUnit (YUnit)!=1.

Problem1:
If you set YRange=6, YUnit=8, TScroller set range value for window's scroll bar as 6, page size as 8. It is standard Windows behavior with these values to hide scroll bar.

Problem2:
There are two class members in TScroller,  XTotalUnits and YTotalUnits. You need to set them also. But as I said TScroller will not work correctly even in this case.

I had to write my own NScroller (descendant from TScroller) to fix this problem and to use variable-length thumb.

 May be better way for you to set  XUnit=YUnit=1, but use XLine & YLine instead.
0
 

Author Comment

by:moczar
ID: 1298684
Thank you for your answer.
The 'XUnit==YUnit=1 XLine,YLine' solution didn't conduce me to fix the Problem2. Would you describe me more detailed how to fix this problem using a descendant from TScroller, please!
Thank you.
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1298685
I used window with MM_ISOTROPIC map mode and various set of SetWindowExt&SetViewPortExt to display bitmap with different zoom value (5...3000%). But in following code I have stripped lines that handle zoom job.
I suppose your window has MM_TEXT map mode (1 device unit = 1 logical unit).

You can compare NScroller code with
TScroller source (BC5\SOURCE\OWL\scroller.cpp).

Write me if you have any questions.

//---------------------------------------------------------------------------
// NScroller class
//---------------------------------------------------------------------------
class NScroller : public TScroller
{
   public:
      NScroller(TWindow* win) : TScroller(win,1,1,0,0) { }
      void SetPageSize();
      void SetSBarRange() { }   // Override parent's function!
      void SetRange(long xRange,long yRange);
};
//---------------------------------------------------------------------------
void NScroller::SetPageSize()
{
   if(Window && Window->GetHandle()) {
      TPoint p(Window->GetClientRect().Size());
      if(p.x<1) p.x=1;
      if(p.y<1) p.y=1;

      // Number of bitmap's pixels to scroll when user press arrow
      // on scroll bar
      XLine=YLine=1;

      // Range to scroll, must be less then XTotalUnits (bitmap's width)
      XRange=XTotalUnits+1-p.x;
      YRange=YTotalUnits+1-p.y;

      // Page size equal width (height) of  window's client area
      XPage=p.x;
      YPage=p.y;

      Window->SetScrollPage(SB_HORZ,XPage,true);
      Window->SetScrollPage(SB_VERT,YPage,true);
      ScrollTo(XPos,YPos);
   }
}
//---------------------------------------------------------------------------
void NScroller::SetRange(long xRange,long yRange)
{
   XTotalUnits=xRange-1;
   YTotalUnits=yRange-1;
   if(Window && Window->GetHandle()) {
      int curMin,curMax;
      Window->GetScrollRange(SB_HORZ,curMin,curMax);
      int newMax=max(0,min(int(XTotalUnits),SHRT_MAX));
      if(newMax!=curMax || curMin!=0)
         Window->SetScrollRange(SB_HORZ,0,newMax,false);
      Window->GetScrollRange(SB_VERT,curMin,curMax);
      newMax=max(0,min(int(YTotalUnits),SHRT_MAX));
      if(newMax!=curMax || curMin!=0)
         Window->SetScrollRange(SB_VERT,0,newMax,false);
   }
   SetPageSize();
}

//---------------------------------------------------------------------------
// NView (bitmap's window) class functions
//---------------------------------------------------------------------------
NView::NView(...) : TMDIChild(parent)
{
   Attr.Style|=WS_VSCROLL|WS_HSCROLL;
   Scroller=new NScroller(this);
}
//---------------------------------------------------------------------------
bool NView::SetDib(TDib* newdib)
{

   // This function loads image into window
   // ...
   // Setting scroller range
   if(newdib==0)
      Scroller->SetRange(0,0);   // Hide scroll bar
   else
      Scroller->SetRange(dib->Width(),dib->Height());

   Invalidate();
   UpdateWindow();
}
//---------------------------------------------------------------------------
void NView::Paint(...)
{
   // ...
}
//---------------------------------------------------------------------------

0
 

Author Comment

by:moczar
ID: 1298686
Thank you very much, it works fine.
0

Featured Post

Revamp Your Training Process

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action.

Question has a verified solution.

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

In this article, I will show how to use the Ribbon IDs Tool Window to assign the built-in Office icons to a ribbon button.  This tool will help us to find the OfficeImageId that corresponds to our desired built-in Office icon. The tool is part of…
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

696 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