Solved

Problem using TScroller if unit !=1

Posted on 1997-03-19
9
312 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
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
 
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
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

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

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
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…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

757 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

16 Experts available now in Live!

Get 1:1 Help Now