Adding a horizontal scrollbar to a Single Document Interface Application

Posted on 2004-11-21
Medium Priority
Last Modified: 2013-11-20

in the onDraw function of my view.cpp file I have some code that draws a waveform (from a wavefile) on the client area.

in my program the top-level view will allow the user to see the entire waveform. however if he/she should zoom in not all of it will be visible so what I require is a horizontal scrollbar. how can i dynamically add this to my app?

also, is it possible to determine the current display resolution the monitor is using. for example in my code i have the following (in the onDraw function)

pDC->SetWindowExt(1024, 80000);

the value 1024 is just because my display is currently at 1024x768 resolution but what I would really like is something like

const inst RESOLUTION = someFunctionToDetermineResolution();
pDC->SetWindowExt(RESOLUTION, 80000);

thank you
Question by:actionjackson88
LVL 55

Accepted Solution

Jaime Olivares earned 2000 total points
ID: 12640504
To determine resolution, use the WinAPI's GetSystemMetrics() function:

int hres = GetSystemMetrics(CXSCREEN);
int vres = GetSystemMetrics(CYSCREEN);

Best way to work with scroll bars and views  is to derive your view from CScrollView class:


Expert Comment

ID: 12643022
Here's a nice application, that uses CScrollView:
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Author Comment

ID: 12648695
hi thanks for all the good information, however i still need a bit of help.

i'll elaborate on my problem a little :

basically I reduce all the wave data (which can be several millions of values) into a representative 1000 values (using a Root Mean Square analysis).

For the top level view (no zoom) I want to see the entire wave. Right now that is what my program is doing in the on draw function:

sets map mode to MM_ANISOTROPIC and setsWindowExt(1000, 8000). 1000 for the x-axis because that is how many points there are to draw. Then I simply draw out those values contained those arrays.

This is sufficient to be able to see the entire wave. The difficulty now is somehow involving scrolling and zooming.

So now suppose I derive CScrollView. This is not compatible with MM_ANISOTROPIC so I am a little stuck. After deriving CScrollView exactly how do I control the scroll bars? During every redraw i.e. in the onDraw function or else where?

For every zoom of the data would I have to recalculate a new set of points or can I some how "spread" a specific portion of 1000 available across the width of the screen.

I apologize if I seem to be merely restating my problem. the information *has* been helpful but I'm still struggling to get it together...
LVL 55

Expert Comment

by:Jaime Olivares
ID: 12649049
You don't need to use MM_ANISOTROPIC, just have to use a "scale" variable, so before painting any point, multiply x value by scale value. To zoom in and out, just change the scale value.

Author Comment

ID: 12650184
i think i know what you mean ... here's what i have so far

oid CSDITEST2View::OnDraw(CDC* pDC)
      CSDITEST2Doc* pDoc = GetDocument();

      if (pDoc->isOpen==false) return; //if a document is not yet open return early

      CRect rect;
      CBrush brush( RGB( 255, 255, 255 ) );
      GetClientRect( &rect );
      FillRect( *pDC, &rect, brush ); //colour the area white

      pDC->MoveTo( rect.left, rect.bottom/2 );

      //start drawing now

      CPen pen(PS_SOLID, 1, RGB(0,0,255) ); //make the pen blue

      pDC->SetMapMode(MM_ANISOTROPIC); // <-exactly what should go here?

      long numSamples = pDoc->currentWave.getNumSamples();
      long dataSize = pDoc ->currentWave.getDataSize();

      pDC->SetWindowExt(1000, 80000); //<-i have a thousand points to plot so x=1000 is correct?

      /* this line sets the origin to the middle, negative values go up,
      positive values go down */

      pDC->SetViewportOrg( m_szSize.cx - rect.right, m_szSize.cy/4);
      /* i think this code lets the app know the physical size of the drawing area */
       pDC->SetViewportExt( m_szSize.cx, m_szSize.cy );

      pDC->MoveTo( rect.left, rect.bottom/2 );

      short int* drawData = pDoc->currentWave.getData(); //the data itself
      short int* leftSpeaker;

      leftSpeaker = extractChannelValues(drawData, numSamples, 0);
      short int* RMSL;

      RMSL = calculatePointsRMS(leftSpeaker, numSamples/2); //array containing a 1000 values to plot

      pDC->MoveTo(0,  0);
      for (DWORD p = 0; p<1000; p++)
            pDC->MoveTo(p, 0);
            pDC->LineTo(p, (RMSL[ p ])/30 );
      for (p=0; p<1024; p++) //reflect about the axis
            pDC->MoveTo(p, 0);
            pDC->LineTo(p, (RMSL[p] * -1)/30);

      short int* rightSpeaker;

      rightSpeaker = extractChannelValues(drawData, numSamples, 1);
      short int* RMSR = calculatePointsRMS(rightSpeaker, numSamples/2);

      pDC->SetViewportOrg( m_szSize.cx - rect.right, rect.bottom- m_szSize.cy/4);

      pDC->MoveTo(0,  0);
      for ( p = 0; p<1000; p++)
            pDC->MoveTo(p, 0);
            pDC->LineTo(p, (RMSR[ p ]) / 30);
      for (p=0; p<1024; p++)
            pDC->MoveTo(p, 0);
            pDC->LineTo(p, (RMSR[p] * -1)/30);

      //after drawing finished

      pDC->MoveTo( rect.left, rect.bottom/2 );
      //pDC->LineTo(rect.right, rect.bottom/2 );

my view class is derived from cscrollview. but yeah, i'm not sure exactly how to implement your advice.

the code above prints out the entire wave in the window. but i don't see a scrollbar - but thats OK it doesn't need one at that moment because everything fits. so you are saying that if i adjust some value a scrollbar should automatically appear as a result of that? if you can give me pointers on how i can amend the above code to introduce the horizontal scrollbar and zoom function that would be of great help.

Author Comment

ID: 12654188
hi, concerning the second link you gave me

i followed the guy's instruction and made my view class inherit from his CZoomView class like this:

#include "ZoomView.h"

class CWaveShowView : public CZoomView

these were his instructions : "Create a Doc/View application by using application wizard. Change your CView class to inherit from CZoomView instead of CView or CScrollView. And that's it, your application has zoom feature"

however the app doesn't compile, i get these errors:

WaveShowView.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall CZoomView::OnInitialUpdate(void)" (?OnInitialUpdate@CZoomView@@MAEXXZ)
WaveShowView.obj : error LNK2001: unresolved external symbol "protected: __thiscall CZoomView::CZoomView(void)" (??0CZoomView@@IAE@XZ)
WaveShowView.obj : error LNK2001: unresolved external symbol "protected: virtual __thiscall CZoomView::~CZoomView(void)" (??1CZoomView@@MAE@XZ)
Debug/WaveShow.exe : fatal error LNK1120: 3 unresolved externals

LVL 55

Expert Comment

by:Jaime Olivares
ID: 12656891
You have to add the CZoomView cpp file to your project, is not enough to include the .h file

Author Comment

ID: 12657739
yeah i got it to compile but when i put my wavefile drawing code in the on draw function i got some very bizzarre results like the screen turning into all sorts of different colours and sometimes i could see "through" the window at the windows behind it.

let me just ask a simple question. i just need to strengthen my basic understanding - if i derive cscrollview shouldn't i automatically see a scrollbars on my app?
LVL 55

Expert Comment

by:Jaime Olivares
ID: 12657874
> if i derive cscrollview shouldn't i automatically see a scrollbars on my app?
yes, then use CScrollView methods to set range and thumb position, and to detect scroll events.

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

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

This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
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.
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Suggested Courses

839 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