我正在尝试实现一个所有者绘制CSliderCtrl。看起来绘图很好,但改变拇指位置的鼠标非常奇怪。它仅限于非常小的矩形。我发现GetChannelRect的rect比我用来创建滑块控件的rect要小得多。 下面是.h文件:
#if !defined(AFX_OWNDRAWSLIDER_H__82981708_4CBC_4D1E_8982_504E99BE489D__INCLUDED_)
#define AFX_OWNDRAWSLIDER_H__82981708_4CBC_4D1E_8982_504E99BE489D__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// OwnDrawSlider.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// COwnDrawSlider window
class COwnDrawSlider : public CSliderCtrl
{
// Construction
public:
COwnDrawSlider();
// Attributes
public:
CBrush black_brush;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COwnDrawSlider)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~COwnDrawSlider();
// Generated message map functions
protected:
//{{AFX_MSG(COwnDrawSlider)
afx_msg void OnPaint();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_OWNDRAWSLIDER_H__82981708_4CBC_4D1E_8982_504E99BE489D__INCLUDED_)
这是OwnDrawSlider类cpp:
// OwnDrawSlider.cpp : implementation file
//
#include "stdafx.h"
#include "OwnDrawSlider.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// COwnDrawSlider
COwnDrawSlider::COwnDrawSlider()
{
black_brush.CreateSolidBrush(RGB(0,0,0));
}
COwnDrawSlider::~COwnDrawSlider()
{
}
BEGIN_MESSAGE_MAP(COwnDrawSlider, CSliderCtrl)
//{{AFX_MSG_MAP(COwnDrawSlider)
ON_WM_PAINT()
ON_WM_CTLCOLOR()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COwnDrawSlider message handlers
void COwnDrawSlider::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect channelRect,thumbRect;
GetChannelRect(&channelRect);
GetThumbRect(&thumbRect);
GetClientRect(&channelRect);
thumbRect=channelRect;
channelRect.top+=5;
channelRect.bottom-=5;
int mid=(channelRect.top+channelRect.bottom)/2;
int w=channelRect.right-channelRect.left;
int pos=GetPos();
int minVal,maxVal;
GetRange(minVal,maxVal);
thumbRect.left=(pos-minVal)*w/(maxVal-minVal);
thumbRect.right=thumbRect.left+(channelRect.right-channelRect.left)*0.025f;
thumbRect.top+=12;
thumbRect.bottom-=12;
//draw the channel
//CBrush whiteBrush(RGB(255,255,255));
//dc.SelectObject(whiteBrush);
//dc.FrameRect(&channelRect,&whiteBrush);
//draw the thumb
CBrush yellowBrush(RGB(255,255,0));
dc.SelectObject(yellowBrush);
dc.Ellipse(&thumbRect);
CFont myFont;
myFont.CreatePointFont(96,"Tahoma");
dc.SetBkColor(RGB(0,0,0));
dc.SetTextColor(RGB(255,255,255));
dc.SelectObject(&myFont);
char msg[128];
sprintf(msg,"%d",pos);
CRect msgRect=thumbRect;
msgRect.top=thumbRect.bottom;
msgRect.bottom=msgRect.top+16;
int mid0=(thumbRect.left+thumbRect.right)/2;
msgRect.left=mid0-6*strlen(msg);
msgRect.right=mid0+6*strlen(msg);
dc.DrawText(msg,strlen(msg),&msgRect,DT_CENTER);
sprintf(msg,"%d",minVal);
msgRect.left=channelRect.left;
msgRect.right=channelRect.left+12*strlen(msg);
dc.DrawText(msg,strlen(msg),&msgRect,DT_LEFT);
sprintf(msg,"%d",maxVal);
msgRect.left=channelRect.right-12*strlen(msg);
msgRect.right=channelRect.right;
dc.DrawText(msg,strlen(msg),&msgRect,DT_RIGHT);
//draw the axis
CPen yellowPen(PS_SOLID,3,RGB(255,255,255));
dc.SelectObject(yellowPen);
dc.MoveTo(channelRect.left,mid);
dc.LineTo(channelRect.right,mid);
dc.MoveTo(channelRect.left,channelRect.top+12);
dc.LineTo(channelRect.left,channelRect.bottom-12);
dc.MoveTo(channelRect.right,channelRect.top+12);
dc.LineTo(channelRect.right,channelRect.bottom-12);
CPen thinPen(PS_SOLID,1,RGB(255,255,0));
dc.SelectObject(thinPen);
int numTick=GetNumTics();
DWORD* ptick=GetTicArray();
float pixelPerTick=w*1.0/numTick;
for(int i=0;i<numTick;i++)
{
dc.MoveTo((ptick[i])*pixelPerTick+channelRect.left,mid-3);
dc.LineTo((ptick[i])*pixelPerTick+channelRect.left,mid+3);
}
// Do not call CSliderCtrl::OnPaint() for painting messages
}
HBRUSH COwnDrawSlider::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CSliderCtrl::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the DC here
// TODO: Return a different brush if the default is not desired
return black_brush;
}
BOOL COwnDrawSlider::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
RECT client;
GetClientRect(&client);
//COLORREF color=pDC->GetBkColor();
COLORREF color=::GetSysColor(COLOR_WINDOW);
//FillRect(pDC->m_hDC,&client,::GetStockObject(GRAY_BRUSH));
//pDC->FillSolidRect(&client,color);
pDC->FillSolidRect(&client,RGB(0,0,0));
return true;//do not call OnEraseBkgrnd, it will fill it white
//return CSliderCtrl::OnEraseBkgnd(pDC);
}
使用程序创建滑块(没有与之关联的资源):
pFrameSlider=new COwnDrawSlider();
pFrameSlider->Create(WS_CHILD|WS_VISIBLE|BS_OWNERDRAW|TBS_HORZ|TBS_AUTOTICKS,rButton,this,ID_FRAME_SLIDER);
//pFrameSlider->SizeToContent();
pFrameSlider->SetTicFreq(50);
pFrameSlider->ShowWindow(SW_SHOW);
在父窗口中,捕获了NM_RELEASECAPTURE。创建时,rect = [9,57,384,822]。由GetChannelRect获得的rect是[19,23,8,40]。并且鼠标操作在此矩形中受到限制。 我的问题是:为什么两个矩形是如此不同?如何通过程序更改通道rect(没有任何与之关联的资源)?