I have been reading Prosise's MFC book and am trying to get my first scrollbar working in a ruler application but have encountered a couple of problems. Firstly when the scrollbar is moved it snaps back to its original position although this only occurs in debug builds strangely. The second problme is that it doesnt redraw properly leaving the numbers out of place or not there at all
I'd appreciate it if someone could take a look at my code for me
Code:
//app.h
#ifndef APP_H
#define APP_H
#include <afxwin.h>
class RulerApp : public CWinApp
{
public:
virtual BOOL InitInstance( );
};
class RulerWin :public CFrameWnd
{
public:
RulerWin( );
afx_msg void OnPaint( );
afx_msg void OnSize( UINT nType, int cx, int cy );
afx_msg void OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar );
protected:
DECLARE_MESSAGE_MAP( )
private:
int horzScrollPos;
int horzPageSize;
int virtualWidth;
};
RulerApp app;
#endif
Code:
//app.cpp
#include "app.h"
BOOL RulerApp::InitInstance( )
{
m_pMainWnd = new RulerWin( );
m_pMainWnd->ShowWindow( m_nCmdShow );
m_pMainWnd->UpdateWindow( );
return TRUE;
}
BEGIN_MESSAGE_MAP( RulerWin, CFrameWnd )
ON_WM_PAINT( )
ON_WM_SIZE( )
ON_WM_HSCROLL( )
END_MESSAGE_MAP( )
RulerWin::RulerWin( )
{
Create( NULL, _T("A strange ruler..."), WS_OVERLAPPEDWINDOW | WS_HSCROLL );
virtualWidth = 4000;
}
void RulerWin::OnPaint( )
{
CPaintDC dc( this );
dc.SetWindowOrg( horzScrollPos, 0 ); //added to to ake
dc.SetMapMode( MM_LOMETRIC );
CBrush yellowBrush;
yellowBrush.CreateSolidBrush( RGB( 240, 240, 0 ) );
CRect ruler( 200, -700, 5000, -1150 ); //+ve up, +ve right
CBrush* oldBrush = dc.SelectObject( &yellowBrush );
dc.Rectangle( &ruler );
dc.SelectObject( oldBrush );
dc.SetBkMode( TRANSPARENT );
dc.SetTextAlign( TA_CENTER | TA_TOP );
int i;
for( i = 200; i <= 5000; i += 100 )
{
if( i != 200 )
{
char cm[ 3 ];
itoa( (i-200)/100, cm, 10 );
dc.TextOut( _T( i ), -1050, cm );
}
dc.MoveTo( i, -1100 );
dc.LineTo( i, -1150 );
}
}
void RulerWin::OnSize( UINT nType, int cx, int cy )
{
CFrameWnd::OnSize( nType, cx, cy );
//ALL THE FOLLOWING STUFF SYNCRONISES THE THUMB SIZE AND WINDOW SIZE
int horzScrollMax = 0;
horzScrollPos = horzPageSize = 0;
if( cx < virtualWidth ) //screenwidth < workspace width
{
horzScrollMax = virtualWidth - 1; //max scroll pos set to just less than workspace size
horzPageSize = cx; //page size set to screen width
horzScrollPos = min( horzScrollPos, virtualWidth - horzPageSize - 1 );
}
SCROLLINFO si;
si.fMask = SIF_ALL;
si.nMin = 0;
si.nMax = horzScrollMax;
si.nPos = horzScrollPos;
si.nPage = horzPageSize;
SetScrollInfo( SB_HORZ, &si, TRUE );
}
void RulerWin::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
{
int delta;
const int MOVEMENT = 10;
switch( nSBCode )
{
case SB_LINELEFT:
delta = -MOVEMENT;
break;
case SB_PAGELEFT:
delta = -horzPageSize;
break;
case SB_LINERIGHT:
delta = MOVEMENT;
break;
case SB_PAGERIGHT:
delta = horzPageSize;
break;
case SB_THUMBTRACK:
delta = (int)nPos - horzScrollPos;
break;
default:
break;
}
int scrollPos = horzScrollPos + delta;
int maxPos = virtualWidth - horzPageSize;
if( scrollPos < 0 )
{
delta = -horzScrollPos;
}
else if( scrollPos > maxPos )
{
delta = maxPos - horzScrollPos;
}
if( delta != 0 )
{
horzScrollPos += delta;
SetScrollPos( SB_HORZ, horzScrollPos, TRUE );
ScrollWindow( -delta, 0 );
}
}
tia