796 lines
38 KiB
C++
796 lines
38 KiB
C++
// ==========================================================================
|
||
// Class Implementation : COXRulerOrganizer
|
||
// ==========================================================================
|
||
|
||
// Version: 9.3
|
||
|
||
// This software along with its related components, documentation and files ("The Libraries")
|
||
// is ?1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
|
||
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
|
||
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
|
||
// to obtain this file, or directly from our office. For a copy of the license governing
|
||
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
|
||
|
||
// //////////////////////////////////////////////////////////////////////////
|
||
|
||
#include "stdafx.h"
|
||
#include "OXRulerOrganizer.h"
|
||
|
||
#include <math.h>
|
||
|
||
#ifdef _DEBUG
|
||
#define new DEBUG_NEW
|
||
#undef THIS_FILE
|
||
static char THIS_FILE[]=__FILE__;
|
||
#endif
|
||
|
||
double COXRulerBar::PIXEL_PAD=14.0;
|
||
|
||
COXRulerBar::COXRulerBar() :
|
||
m_rectInvert(0,0,0,0),
|
||
m_rectOldInvert(0,0,0,0)
|
||
{
|
||
m_bHorizontal=TRUE;
|
||
m_nPos=0;
|
||
m_nZoom=100;
|
||
m_nCalibrate=100;
|
||
m_bOldIsHilited=FALSE;
|
||
m_dDisplayDpi=100.0;
|
||
m_bUseNonDefaultDpi=FALSE;
|
||
}
|
||
|
||
COXRulerBar::~COXRulerBar()
|
||
{
|
||
}
|
||
|
||
BOOL COXRulerBar::Init(BOOL bHorizontal /*=TRUE*/, UINT nCalibrate /*=100*/)
|
||
{
|
||
m_nCalibrate=nCalibrate;
|
||
m_bHorizontal=bHorizontal;
|
||
|
||
// for 1, 2, ...
|
||
// font for horizontal bar
|
||
VERIFY(m_font.CreateFont(-12,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,ANSI_CHARSET,
|
||
0,0,0,0,_T("Times New Roman")));
|
||
// font for vertical bar
|
||
VERIFY(m_fontVert.CreateFont(-12,0,900,0,FW_NORMAL,FALSE,FALSE,FALSE,ANSI_CHARSET,
|
||
0,0,0,0,_T("Times New Roman")));
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
BEGIN_MESSAGE_MAP(COXRulerBar, CWnd)
|
||
//{{AFX_MSG_MAP(COXRulerBar)
|
||
ON_WM_PAINT()
|
||
//}}AFX_MSG_MAP
|
||
END_MESSAGE_MAP()
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// COXRulerBar implementation
|
||
|
||
BOOL COXRulerBar::Create(CWnd* pParentWnd, BOOL bHorizontal, CRect rect,
|
||
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE*/,
|
||
UINT nCalibrate/*=100*/,
|
||
UINT nID/*=IDC_STATIC*/)
|
||
{
|
||
ASSERT(pParentWnd!=NULL);
|
||
|
||
WNDCLASS wndClass;
|
||
wndClass.style=CS_DBLCLKS;
|
||
wndClass.lpfnWndProc=AfxWndProc;
|
||
wndClass.cbClsExtra=0;
|
||
wndClass.cbWndExtra=0;
|
||
wndClass.hInstance=AfxGetInstanceHandle();
|
||
wndClass.hIcon=::LoadCursor(NULL,IDC_ARROW);
|
||
wndClass.hCursor=0;
|
||
wndClass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
|
||
wndClass.lpszMenuName=NULL;
|
||
wndClass.lpszClassName=_T("RulerBarWnd");
|
||
|
||
if(!AfxRegisterClass(&wndClass))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
if(!CWnd::Create(wndClass.lpszClassName,NULL,dwStyle,rect,pParentWnd,nID,NULL))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
return Init(bHorizontal,nCalibrate);
|
||
}
|
||
|
||
|
||
void COXRulerBar::DrawTick(CDC* pDC, CRect& rect, double dOffset, BOOL bMidTick)
|
||
{
|
||
int nTickX, nTickY;
|
||
int nTickWidth, nTickHeight;
|
||
|
||
if(dOffset < 0)
|
||
return;
|
||
|
||
if(m_bHorizontal)
|
||
{
|
||
if(bMidTick)
|
||
nTickHeight=rect.Height()/2;
|
||
else
|
||
nTickHeight=rect.Height()/4;
|
||
|
||
nTickWidth=0;
|
||
|
||
nTickX=(int)floor(rect.left+dOffset);
|
||
nTickY=rect.top+(rect.Height()-nTickHeight+1)/2;
|
||
}
|
||
else
|
||
{
|
||
if(bMidTick)
|
||
nTickWidth=rect.Width()/2;
|
||
else
|
||
nTickWidth=rect.Width()/4;
|
||
|
||
nTickHeight=0;
|
||
nTickX=rect.left+(rect.Width()-nTickWidth+1)/2;
|
||
nTickY=(int)floor(rect.top+dOffset);
|
||
}
|
||
|
||
CPoint pt(nTickX, nTickY);
|
||
CPoint ptTo(nTickX+nTickWidth, nTickY+nTickHeight);
|
||
if(rect.PtInRect(pt) && rect.PtInRect(ptTo))
|
||
{
|
||
pDC->MoveTo(nTickX, nTickY);
|
||
pDC->LineTo(nTickX+nTickWidth, nTickY+nTickHeight);
|
||
}
|
||
}
|
||
|
||
void COXRulerBar::DrawScale(CDC* pDC, CRect rect)
|
||
{
|
||
CBrush bkgndBrush(::GetSysColor(COLOR_WINDOW));
|
||
pDC->FillRect(rect,&bkgndBrush);
|
||
pDC->DrawEdge(rect,EDGE_SUNKEN,BF_RECT);
|
||
rect.DeflateRect(2,2);
|
||
|
||
// Clip all output to the rectangle
|
||
pDC->IntersectClipRect(rect);
|
||
|
||
CFont* oldFont=NULL;
|
||
if(m_bHorizontal)
|
||
pDC->SelectObject(&m_font);
|
||
else
|
||
pDC->SelectObject(&m_fontVert);
|
||
COLORREF crOldText=pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
|
||
CPen pen(PS_SOLID,1,::GetSysColor(COLOR_BTNTEXT));
|
||
CPen* oldPen=pDC->SelectObject(&pen);
|
||
int oldMode=pDC->SetBkMode(TRANSPARENT);
|
||
|
||
double dSpacer=m_nZoom*0.1;
|
||
int nTicksPerUnit=(100!=m_nCalibrate) ? 4 : 10;
|
||
double dDPI=(m_bUseNonDefaultDpi) ? m_dDisplayDpi : 100.0;
|
||
double dPixelsPerUnit=m_nZoom*100.0/m_nCalibrate*dDPI/100.0;
|
||
double dTickSpace=dPixelsPerUnit/nTicksPerUnit;
|
||
double dOrg=nTicksPerUnit-fmod(m_nPos, dSpacer);
|
||
int nSpan=(m_bHorizontal) ? rect.Width() : rect.Height();
|
||
|
||
double dSpanEnd=nSpan+2*dSpacer+dPixelsPerUnit;
|
||
int nUnitNumber=(int)(m_nPos/dPixelsPerUnit);
|
||
|
||
int nXErr=0;
|
||
int nYErr=0;
|
||
|
||
for(double d=dOrg; d<dSpanEnd; d+=dPixelsPerUnit, nUnitNumber++)
|
||
{
|
||
double dPos=-fmod(m_nPos,dPixelsPerUnit)-dOrg;
|
||
|
||
// If the space between ticks is greater than PIXEL_PAD/2.0,
|
||
// draw all of the ticks
|
||
if(dTickSpace>PIXEL_PAD/2.0)
|
||
{
|
||
for(int nIndex=1; nIndex<nTicksPerUnit; nIndex++)
|
||
{
|
||
double dOffset=d+dPos+0.5+dTickSpace*nIndex;
|
||
DrawTick(pDC,rect,dOffset,nIndex==nTicksPerUnit/2);
|
||
}
|
||
}
|
||
// Just draw the mid tick
|
||
else if(dPixelsPerUnit>=PIXEL_PAD)
|
||
{
|
||
double dOffset=d+dPos+0.5+dTickSpace*nTicksPerUnit/2;
|
||
DrawTick(pDC,rect,dOffset,TRUE);
|
||
}
|
||
|
||
if(dPixelsPerUnit<PIXEL_PAD && nUnitNumber%5)
|
||
continue;
|
||
|
||
// draw the unit number, starting at 1
|
||
if(nUnitNumber>0)
|
||
{
|
||
char nCh=(char)(48+(nUnitNumber%10)); // 47 is '0'
|
||
// Keep things as ASCII, since Unicode numeric characters
|
||
// may be non-consective
|
||
CString sCh(nCh);
|
||
|
||
if(dPixelsPerUnit<PIXEL_PAD)
|
||
{
|
||
int nHundreds=nUnitNumber%100;
|
||
sCh.Format(_T("%d"),nHundreds);
|
||
}
|
||
|
||
CSize sNum=pDC->GetOutputTextExtent(sCh);
|
||
int nXPos;
|
||
int nYPos;
|
||
|
||
if(m_bHorizontal)
|
||
{
|
||
nXPos=(int)floor(rect.left+d+dPos+0.5-(sNum.cx/2.0));
|
||
nYPos=rect.top+(rect.Height()-sNum.cy)/2;
|
||
|
||
if(nXPos <= nXErr)
|
||
continue;
|
||
else
|
||
nXErr=sNum.cx+nXPos;
|
||
}
|
||
else
|
||
{
|
||
nXPos=rect.left+(rect.Width()-sNum.cy)/2;
|
||
nYPos=(int)floor(rect.top+d+dPos+0.5+(sNum.cx/2.0));
|
||
|
||
if(nYPos <= nYErr)
|
||
continue;
|
||
else
|
||
nYErr=sNum.cy+nYPos;
|
||
}
|
||
|
||
pDC->TextOut(nXPos, nYPos, sCh);
|
||
}
|
||
|
||
}
|
||
|
||
// Get rid of the clipping region
|
||
pDC->SelectClipRgn(NULL,RGN_COPY);
|
||
|
||
pDC->SetBkMode(oldMode);
|
||
pDC->SelectObject(oldPen);
|
||
pDC->SetTextColor(crOldText);
|
||
pDC->SelectObject(oldFont);
|
||
}
|
||
|
||
void COXRulerBar::DrawRuler(CDC* pDC, CRect rect, CRect rectClip)
|
||
{
|
||
ASSERT(pDC!=NULL);
|
||
if(rect.IsRectEmpty() || rectClip.IsRectEmpty())
|
||
return;
|
||
|
||
// create and initialize the memory DC which we are going to draw on first
|
||
CDC memDc;
|
||
CBitmap bmpMem,*pOldMemBmp;
|
||
memDc.CreateCompatibleDC( pDC );
|
||
bmpMem.CreateCompatibleBitmap( pDC, rect.right, rect.bottom );
|
||
pOldMemBmp = memDc.SelectObject( &bmpMem );
|
||
|
||
memDc.IntersectClipRect(rectClip);
|
||
DrawScale(&memDc,rect);
|
||
memDc.SelectClipRgn(NULL,RGN_COPY);
|
||
|
||
if(m_bOldIsHilited)
|
||
{
|
||
CRect rectIntersect;
|
||
rectIntersect.IntersectRect(m_rectOldInvert,rectClip);
|
||
ReverseHilite(&memDc,rectIntersect);
|
||
}
|
||
|
||
//Copy drawing from memory device context to the screen
|
||
pDC->BitBlt( rect.left, rect.top, rect.Width(), rect.Height(),
|
||
&memDc, rect.left, rect.top, SRCCOPY );
|
||
// a final clean up
|
||
memDc.SelectObject( pOldMemBmp );
|
||
}
|
||
|
||
void COXRulerBar::ReverseHilite(CDC* pDC, CRect rect)
|
||
{
|
||
ASSERT(pDC!=NULL);
|
||
pDC->PatBlt(rect.left,rect.top,rect.Width(),rect.Height(),PATINVERT);
|
||
}
|
||
|
||
void COXRulerBar::Hilite(CDC* pDC, CRect rect, int nStartPos, int nWidth/*=1*/)
|
||
{
|
||
ASSERT(pDC!=NULL);
|
||
|
||
BOOL bRemoveHilite=FALSE;
|
||
m_rectInvert=rect;
|
||
m_rectInvert.DeflateRect(2,2);
|
||
|
||
if(m_bHorizontal)
|
||
{
|
||
m_rectInvert.left+=nStartPos;
|
||
bRemoveHilite=((m_rectInvert.left<=2) || (m_rectInvert.left>=m_rectInvert.right));
|
||
m_rectInvert.right=m_rectInvert.left+nWidth;
|
||
if(m_rectInvert.right>rect.right-2)
|
||
m_rectInvert.right=rect.right-2;
|
||
}
|
||
else
|
||
{
|
||
m_rectInvert.top+=nStartPos;
|
||
bRemoveHilite=((m_rectInvert.top<=2) || (m_rectInvert.top>=m_rectInvert.bottom));
|
||
m_rectInvert.bottom=m_rectInvert.top+nWidth;
|
||
if(m_rectInvert.bottom>rect.bottom-2)
|
||
m_rectInvert.bottom=rect.bottom-2;
|
||
}
|
||
|
||
m_rectInvert.NormalizeRect(); // for nWidth < 0
|
||
|
||
if(bRemoveHilite)
|
||
{
|
||
if(m_bOldIsHilited)
|
||
{
|
||
CRect rectOldInvert=m_rectOldInvert;
|
||
rectOldInvert.IntersectRect(rectOldInvert,rect);
|
||
ReverseHilite(pDC,rectOldInvert);
|
||
}
|
||
m_rectOldInvert.SetRectEmpty();
|
||
m_rectInvert.SetRectEmpty();
|
||
m_bOldIsHilited=FALSE;
|
||
}
|
||
else
|
||
{
|
||
if(m_bOldIsHilited)
|
||
{
|
||
CRect rectIntersect;
|
||
rectIntersect.IntersectRect(m_rectOldInvert,m_rectInvert);
|
||
|
||
CRect rectOldInvert;
|
||
rectOldInvert.SubtractRect(m_rectOldInvert,rectIntersect);
|
||
rectOldInvert.IntersectRect(rectOldInvert,rect);
|
||
ReverseHilite(pDC,rectOldInvert);
|
||
|
||
CRect rectInvert;
|
||
rectInvert.SubtractRect(m_rectInvert,rectIntersect);
|
||
ReverseHilite(pDC,rectInvert);
|
||
}
|
||
else
|
||
ReverseHilite(pDC,m_rectInvert);
|
||
m_bOldIsHilited=TRUE;
|
||
m_rectOldInvert=m_rectInvert;
|
||
}
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// COXRulerBar message handlers
|
||
|
||
void COXRulerBar::Scroll(UINT nPos, BOOL bRedraw/*=TRUE*/)
|
||
{
|
||
m_nPos=m_nZoom*nPos/100;
|
||
if(bRedraw)
|
||
Invalidate();
|
||
}
|
||
|
||
void COXRulerBar::Zoom(UINT nZoom, BOOL bRedraw/*=TRUE*/)
|
||
{
|
||
m_nZoom=nZoom;
|
||
if(bRedraw)
|
||
Invalidate();
|
||
}
|
||
|
||
void COXRulerBar::SetDpi(double dDpi, BOOL bRedraw/*=TRUE*/)
|
||
{
|
||
m_dDisplayDpi=dDpi;
|
||
m_bUseNonDefaultDpi=TRUE;
|
||
if(bRedraw)
|
||
Invalidate();
|
||
}
|
||
|
||
void COXRulerBar::UseDefaultDpi(BOOL bUseDefaultDpi, BOOL bRedraw/*=TRUE*/)
|
||
{
|
||
m_bUseNonDefaultDpi=!bUseDefaultDpi;
|
||
if(bRedraw)
|
||
Invalidate();
|
||
}
|
||
|
||
void COXRulerBar::SetCalibrate(UINT nCalibrate, BOOL bRedraw/*=TRUE*/)
|
||
{
|
||
m_nCalibrate=nCalibrate;
|
||
if(bRedraw)
|
||
Invalidate();
|
||
}
|
||
|
||
void COXRulerBar::OnPaint()
|
||
{
|
||
CPaintDC dc(this); // device context for painting
|
||
|
||
CRect rectClient;
|
||
GetClientRect(rectClient);
|
||
CRect rectClip;
|
||
dc.GetClipBox(&rectClip); // invalidated region
|
||
|
||
DrawRuler(&dc,rectClient,rectClip);
|
||
}
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
|
||
COXRulerOrganizer::COXRulerOrganizer()
|
||
:
|
||
m_bShowHorzRulerBar(FALSE),
|
||
m_bShowVertRulerBar(FALSE),
|
||
m_rectHorzRulerBar(0,0,0,0),
|
||
m_rectVertRulerBar(0,0,0,0),
|
||
m_rectBlank(0,0,0,0),
|
||
m_nHorzRulerBarHeight(OXRB_HORZHEIGHT),
|
||
m_nVertRulerBarWidth(OXRB_VERTWIDTH),
|
||
m_nTimerCheckScrollPos(NULL)
|
||
{
|
||
}
|
||
|
||
|
||
COXRulerOrganizer::~COXRulerOrganizer()
|
||
{
|
||
}
|
||
|
||
BOOL COXRulerOrganizer::Attach(CWnd* pWnd, BOOL bHorzRuler/*=TRUE*/,
|
||
BOOL bVertRuler/*=TRUE*/)
|
||
{
|
||
ASSERT(pWnd!=NULL);
|
||
|
||
if(!::IsWindow(pWnd->GetSafeHwnd()))
|
||
{
|
||
TRACE(_T("COXRulerOrganizer::Attach: failed, invalid window handle has been specified\n"));
|
||
return FALSE;
|
||
}
|
||
|
||
if(IsAttached())
|
||
{
|
||
TRACE(_T("COXRulerOrganizer::Attach: failed, object already has attached window. Call Detach() before!\n"));
|
||
return FALSE;
|
||
}
|
||
|
||
HookWindow(pWnd);
|
||
|
||
// create ruler bars
|
||
ASSERT(!::IsWindow(m_horzRulerBar.GetSafeHwnd()) &&
|
||
!::IsWindow(m_vertRulerBar.GetSafeHwnd()));
|
||
CRect rect(0,0,0,0);
|
||
if(!m_horzRulerBar.Create(pWnd,TRUE,rect,WS_CHILD) ||
|
||
!m_vertRulerBar.Create(pWnd,FALSE,rect,WS_CHILD))
|
||
{
|
||
TRACE(_T("COXRulerOrganizer::Attach: failed to create the ruler bars\n"));
|
||
Detach();
|
||
return FALSE;
|
||
}
|
||
|
||
// create timer for checking scroll position
|
||
m_nTimerCheckScrollPos=pWnd->SetTimer(IDT_OXRBO_CHECK_SCROLLPOS,
|
||
OXRBO_CHECK_SCROLLPOS_DELAY,NULL);
|
||
if(m_nTimerCheckScrollPos==NULL)
|
||
{
|
||
TRACE(_T("COXRulerOrganizer::Attach: failed to create timer\n"));
|
||
Detach();
|
||
return FALSE;
|
||
}
|
||
|
||
m_bShowHorzRulerBar=bHorzRuler;
|
||
m_bShowVertRulerBar=bVertRuler;
|
||
|
||
CalcLayout(TRUE);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
void COXRulerOrganizer::Detach()
|
||
{
|
||
// destroy ruler bars
|
||
if(::IsWindow(m_horzRulerBar.GetSafeHwnd()))
|
||
m_horzRulerBar.DestroyWindow();
|
||
if(::IsWindow(m_vertRulerBar.GetSafeHwnd()))
|
||
m_vertRulerBar.DestroyWindow();
|
||
|
||
if(::IsWindow(m_hWndHooked))
|
||
{
|
||
if(m_nTimerCheckScrollPos!=NULL)
|
||
{
|
||
GetHookedWnd()->KillTimer(m_nTimerCheckScrollPos);
|
||
}
|
||
|
||
RedrawAttached(TRUE);
|
||
}
|
||
|
||
UnhookWindow();
|
||
|
||
m_bShowHorzRulerBar=FALSE;
|
||
m_bShowVertRulerBar=FALSE;
|
||
|
||
m_nTimerCheckScrollPos=NULL;
|
||
}
|
||
|
||
|
||
void COXRulerOrganizer::SetHorzRulerBarHeight(int nHorzRulerBarHeight)
|
||
{
|
||
m_nHorzRulerBarHeight=nHorzRulerBarHeight;
|
||
CalcLayout(TRUE);
|
||
}
|
||
|
||
|
||
void COXRulerOrganizer::SetVertRulerBarWidth(int nVertRulerBarWidth)
|
||
{
|
||
m_nVertRulerBarWidth=nVertRulerBarWidth;
|
||
CalcLayout(TRUE);
|
||
}
|
||
|
||
|
||
LRESULT COXRulerOrganizer::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
#if defined (_WINDLL)
|
||
#if defined (_AFXDLL)
|
||
AFX_MANAGE_STATE(AfxGetAppModuleState());
|
||
#else
|
||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
#endif
|
||
#endif
|
||
|
||
LRESULT result=0;
|
||
|
||
switch(uMsg)
|
||
{
|
||
case WM_NCCALCSIZE:
|
||
{
|
||
result=COXHookWnd::WindowProc(uMsg,wParam,lParam);
|
||
|
||
LPNCCALCSIZE_PARAMS lpncsp=(LPNCCALCSIZE_PARAMS)lParam;
|
||
// add an offset
|
||
if(GetShowVertRulerBar())
|
||
{
|
||
if(lpncsp->rgrc[0].right-lpncsp->rgrc[0].left>
|
||
GetVertRulerBarWidth()+OXRBO_BORDER)
|
||
{
|
||
lpncsp->rgrc[0].left+=GetVertRulerBarWidth()+OXRBO_BORDER;
|
||
}
|
||
else
|
||
{
|
||
lpncsp->rgrc[0].left=lpncsp->rgrc[0].right;
|
||
}
|
||
}
|
||
|
||
if(GetShowHorzRulerBar())
|
||
{
|
||
if(lpncsp->rgrc[0].bottom-lpncsp->rgrc[0].top>
|
||
GetHorzRulerBarHeight()+OXRBO_BORDER)
|
||
{
|
||
lpncsp->rgrc[0].top+=GetHorzRulerBarHeight()+OXRBO_BORDER;
|
||
}
|
||
else
|
||
{
|
||
lpncsp->rgrc[0].top=lpncsp->rgrc[0].bottom;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
|
||
case WM_NCPAINT:
|
||
{
|
||
result=COXHookWnd::WindowProc(uMsg,wParam,lParam);
|
||
|
||
CWindowDC dc(GetHookedWnd());
|
||
|
||
if(!m_rectBlank.IsRectEmpty())
|
||
dc.FillSolidRect(m_rectBlank,::GetSysColor(COLOR_BTNFACE));
|
||
|
||
if(GetShowHorzRulerBar())
|
||
{
|
||
m_horzRulerBar.DrawRuler(&dc,m_rectHorzRulerBar,m_rectHorzRulerBar);
|
||
|
||
dc.MoveTo(m_rectHorzRulerBar.left+1,m_rectHorzRulerBar.bottom+1);
|
||
dc.LineTo(m_rectHorzRulerBar.right+1,m_rectHorzRulerBar.bottom+1);
|
||
CPen pen(PS_SOLID,1,::GetSysColor(COLOR_3DSHADOW));
|
||
CPen* pOldPen=dc.SelectObject(&pen);
|
||
dc.MoveTo(m_rectHorzRulerBar.left,m_rectHorzRulerBar.bottom);
|
||
dc.LineTo(m_rectHorzRulerBar.right+1,m_rectHorzRulerBar.bottom);
|
||
if(pOldPen!=NULL)
|
||
dc.SelectObject(pOldPen);
|
||
}
|
||
if(GetShowVertRulerBar())
|
||
{
|
||
m_vertRulerBar.DrawRuler(&dc,m_rectVertRulerBar,m_rectVertRulerBar);
|
||
|
||
dc.MoveTo(m_rectVertRulerBar.right+1,m_rectVertRulerBar.top+1);
|
||
dc.LineTo(m_rectVertRulerBar.right+1,m_rectVertRulerBar.bottom+1);
|
||
CPen pen(PS_SOLID,1,::GetSysColor(COLOR_3DSHADOW));
|
||
CPen* pOldPen=dc.SelectObject(&pen);
|
||
dc.MoveTo(m_rectVertRulerBar.right,m_rectVertRulerBar.top);
|
||
dc.LineTo(m_rectVertRulerBar.right,m_rectVertRulerBar.bottom+1);
|
||
if(pOldPen!=NULL)
|
||
dc.SelectObject(pOldPen);
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
case WM_SIZE:
|
||
{
|
||
result=COXHookWnd::WindowProc(uMsg,wParam,lParam);
|
||
if(wParam==SIZE_MAXIMIZED || wParam==SIZE_RESTORED)
|
||
{
|
||
CalcLayout();
|
||
CheckScrollPos();
|
||
RedrawAttached();
|
||
}
|
||
break;
|
||
}
|
||
|
||
case WM_HSCROLL:
|
||
{
|
||
result=COXHookWnd::WindowProc(uMsg,wParam,lParam);
|
||
CheckScrollPos();
|
||
break;
|
||
}
|
||
|
||
case WM_VSCROLL:
|
||
{
|
||
result=COXHookWnd::WindowProc(uMsg,wParam,lParam);
|
||
CheckScrollPos();
|
||
break;
|
||
}
|
||
|
||
case WM_MOUSEMOVE:
|
||
{
|
||
result=COXHookWnd::WindowProc(uMsg,wParam,lParam);
|
||
|
||
if(GetShowHorzRulerBar())
|
||
{
|
||
HiliteRuler(LOWORD(lParam),TRUE,1);
|
||
}
|
||
|
||
if(GetShowVertRulerBar())
|
||
{
|
||
HiliteRuler(HIWORD(lParam),FALSE,1);
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
case WM_TIMER:
|
||
{
|
||
if(wParam==(UINT)m_nTimerCheckScrollPos)
|
||
{
|
||
CheckScrollPos();
|
||
return 0;
|
||
}
|
||
result=COXHookWnd::WindowProc(uMsg,wParam,lParam);
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
result=COXHookWnd::WindowProc(uMsg,wParam,lParam);
|
||
break;
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
void COXRulerOrganizer::CalcLayout(BOOL bRepositionBars/*=FALSE*/)
|
||
{
|
||
m_rectHorzRulerBar.SetRectEmpty();
|
||
m_rectVertRulerBar.SetRectEmpty();
|
||
m_rectBlank.SetRectEmpty();
|
||
|
||
if(!IsAttached())
|
||
return;
|
||
|
||
ASSERT(::IsWindow(m_hWndHooked));
|
||
|
||
CRect rectWindow;
|
||
::GetWindowRect(m_hWndHooked,rectWindow);
|
||
GetHookedWnd()->ScreenToClient(rectWindow);
|
||
CRect rect;
|
||
::GetClientRect(m_hWndHooked,rect);
|
||
rect-=rectWindow.TopLeft();
|
||
|
||
DWORD dwStyle=GetHookedWnd()->GetStyle();
|
||
if((dwStyle&WS_VSCROLL)==WS_VSCROLL)
|
||
{
|
||
rect.right+=::GetSystemMetrics(SM_CXVSCROLL);
|
||
}
|
||
if((dwStyle&WS_HSCROLL)==WS_HSCROLL)
|
||
{
|
||
rect.bottom+=::GetSystemMetrics(SM_CYHSCROLL);
|
||
}
|
||
if(GetShowVertRulerBar())
|
||
{
|
||
rect.left-=GetVertRulerBarWidth()+OXRBO_BORDER;
|
||
}
|
||
if(GetShowHorzRulerBar())
|
||
{
|
||
rect.top-=GetHorzRulerBarHeight()+OXRBO_BORDER;
|
||
}
|
||
|
||
|
||
if(GetShowHorzRulerBar() && GetShowVertRulerBar())
|
||
{
|
||
m_rectBlank=rect;
|
||
m_rectBlank.right=m_rectBlank.left+GetVertRulerBarWidth();
|
||
m_rectBlank.bottom=m_rectBlank.top+GetHorzRulerBarHeight();
|
||
}
|
||
|
||
if(GetShowHorzRulerBar())
|
||
{
|
||
m_rectHorzRulerBar.left=m_rectBlank.right;
|
||
m_rectHorzRulerBar.right=rect.right;
|
||
m_rectHorzRulerBar.top=rect.top;
|
||
m_rectHorzRulerBar.bottom=m_rectHorzRulerBar.top+GetHorzRulerBarHeight();
|
||
}
|
||
|
||
if(GetShowVertRulerBar())
|
||
{
|
||
m_rectVertRulerBar.top=m_rectBlank.bottom;
|
||
m_rectVertRulerBar.bottom=rect.bottom;
|
||
m_rectVertRulerBar.left=rect.left;
|
||
m_rectVertRulerBar.right=m_rectVertRulerBar.left+GetVertRulerBarWidth();
|
||
}
|
||
|
||
if(bRepositionBars)
|
||
RedrawAttached(TRUE);
|
||
}
|
||
|
||
|
||
void COXRulerOrganizer::CheckScrollPos()
|
||
{
|
||
BOOL bRedraw=FALSE;
|
||
if(GetShowHorzRulerBar())
|
||
{
|
||
SCROLLINFO scrollInfo={ sizeof(SCROLLINFO) };
|
||
if(GetHookedWnd()->GetScrollInfo(SB_HORZ,&scrollInfo))
|
||
{
|
||
int nNewScrollPos=scrollInfo.nPos;
|
||
|
||
if(nNewScrollPos!=0 && scrollInfo.nPage!=0)
|
||
{
|
||
CRect rectClient;
|
||
::GetClientRect(m_hWndHooked,rectClient);
|
||
|
||
nNewScrollPos*=(rectClient.Width()/scrollInfo.nPage);
|
||
}
|
||
|
||
int nOldScrollPos=(int)m_horzRulerBar.GetCurrentPos();
|
||
nNewScrollPos=nNewScrollPos*100/m_horzRulerBar.GetZoomLevel();
|
||
m_horzRulerBar.Scroll(nNewScrollPos,FALSE);
|
||
if(nOldScrollPos!=(int)m_horzRulerBar.GetCurrentPos())
|
||
{
|
||
bRedraw=TRUE;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(GetShowVertRulerBar())
|
||
{
|
||
SCROLLINFO scrollInfo={ sizeof(SCROLLINFO) };
|
||
if(GetHookedWnd()->GetScrollInfo(SB_VERT,&scrollInfo))
|
||
{
|
||
int nNewScrollPos=scrollInfo.nPos;
|
||
|
||
if(nNewScrollPos!=0 && scrollInfo.nPage!=0)
|
||
{
|
||
CRect rectClient;
|
||
::GetClientRect(m_hWndHooked,rectClient);
|
||
|
||
nNewScrollPos*=(rectClient.Height()/scrollInfo.nPage);
|
||
}
|
||
|
||
int nOldScrollPos=(int)m_vertRulerBar.GetCurrentPos();
|
||
nNewScrollPos=nNewScrollPos*100/m_vertRulerBar.GetZoomLevel();
|
||
m_vertRulerBar.Scroll(nNewScrollPos,FALSE);
|
||
if(nOldScrollPos!=(int)m_vertRulerBar.GetCurrentPos())
|
||
{
|
||
bRedraw=TRUE;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(bRedraw)
|
||
{
|
||
RedrawAttached();
|
||
TRACE(_T("RedrawAttached\n"));
|
||
}
|
||
}
|
||
|