Adding a horizontal scrollbar to a Single Document Interface Application

Hi,

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->SetMapMode(MM_ANISOTROPIC);
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->SetMapMode(MM_ANISOTROPIC);
pDC->SetWindowExt(RESOLUTION, 80000);

thank you
actionjackson88Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jaime OlivaresSoftware ArchitectCommented:
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:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cscrollview.asp
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
_mb_Commented:
Here's a nice application, that uses CScrollView:
http://www.codeguru.com/Cpp/W-D/doc_view/scrolling/article.php/c6101/
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

actionjackson88Author Commented:
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...
0
Jaime OlivaresSoftware ArchitectCommented:
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.
0
actionjackson88Author Commented:
i think i know what you mean ... here's what i have so far

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

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

      pDC->SaveDC();
      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->SelectObject(&pen);

      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 );
      pDC->RestoreDC(-1);
}

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.
0
Jaime OlivaresSoftware ArchitectCommented:
0
actionjackson88Author Commented:
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

0
Jaime OlivaresSoftware ArchitectCommented:
You have to add the CZoomView cpp file to your project, is not enough to include the .h file
0
actionjackson88Author Commented:
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?
0
Jaime OlivaresSoftware ArchitectCommented:
> 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.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.