797 lines
18 KiB
C++
797 lines
18 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"));
|
|
}
|
|
}
|
|
|