MFC 直线 虚线 折线 圆 椭圆 矩形 弧形
http://www.2cto.com/kf/201408/324222.html
****Dlg.h头文件添加:
//为工程添加画笔、点变量数组
public:
CPen m_pen[5];
CPoint m_point[5];
public:
void DrawLine(CDC *pDC);
void DrawPolyline(CDC *pDC);
void DrawPolygon(CDC *pDC);
void DrawRect(CDC *pDC);
void DrawRoundRect(CDC *pDC);
void DrawEllipse(CDC *pDC);
void DrawArc(CDC *pDC);
void DrawAngleArc(CDC *pDC);
****Dlg.cpp构造函数修改:
CLineTestDlg::CLineTestDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CLineTestDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
//初始化画笔、点变量数组
m_pen[0].CreatePen(PS_SOLID,1,RGB(255,0,0)); //红色实线,1像素宽---参数:样式、宽度、颜色
m_pen[1].CreatePen(PS_SOLID,6,RGB(0,255,0)); //绿色实线,6像素宽
m_pen[2].CreatePen(PS_DASH,1,RGB(255,0,0)); //红色虚线,必须为一个像素宽
m_pen[3].CreatePen(PS_DOT,1,RGB(0,0,255)); //蓝色点线,必须为一个像素宽
m_pen[4].CreatePen(PS_DASHDOTDOT,1,RGB(255,0,0));//红色双点虚线,必须为一个像素宽
//绘制多边形的点数组
m_point[0].x=10;
m_point[0].y=100;
m_point[1].x=10;
m_point[1].y=120;
m_point[2].x=100;
m_point[2].y=105;
m_point[3].x=170;
m_point[3].y=120;
m_point[4].x=170;
m_point[4].y=100;
}
***Dlg.cpp onpaint函数
void CLineTestDlg::OnPaint()
{
CPaintDC dc(this); // 用于绘制的设备上下文
CBrush brush(RGB(190,190,190));//画刷
dc.SelectObject(&brush);//将画刷选入DC
DrawLine(&dc);
DrawPolyline(&dc);
DrawPolygon(&dc);
DrawRect(&dc);
DrawRoundRect(&dc);
DrawEllipse(&dc);
DrawArc(&dc);
DrawAngleArc(&dc);
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
定义绘图函数:
//绘制直线函数
void CLineTestDlg::DrawLine(CDC *pDC)
{
CPen *oldPen=pDC->SelectObject(&m_pen[0]);//保存DC原始画笔
for(int i=0;i<5;i++)
{
pDC->SelectObject(&m_pen[i]); //将画笔选入DC
pDC->MoveTo(20,20+i*15); //设置DC当前点
pDC->LineTo(170,20+i*15); //绘制直线
}
pDC->SelectObject(oldPen); //回复DC原画笔
}
//绘制折线
void CLineTestDlg::DrawPolyline(CDC *pDC)
{
CPen *oldPen=pDC->SelectObject(&m_pen[0]);//保存DC原始画笔
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
m_point[j].y+=35; //每次下移35个像素
}
pDC->SelectObject(&m_pen[i]);
pDC->Polyline(m_point,5);
}
pDC->SelectObject(oldPen);
}
//绘制多边形
void CLineTestDlg::DrawPolygon(CDC *pDC)
{
for(int j=0;j<5;j++)
m_point[j].y+=75; //数组中的点下移75个像素
CPen *oldPen=pDC->SelectObject(&m_pen[0]);//保存DC原始画笔
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
m_point[j].y+=35; //每次绘制图形下移35个像素
}
pDC->SelectObject(&m_pen[i]);
pDC->Polygon(m_point,5); //绘制多边形
}
pDC->SelectObject(oldPen);
}
//绘制矩形
void CLineTestDlg::DrawRect(CDC *pDC)
{
CRect rect(150,20,220,80);
CPen *oldPen=pDC->SelectObject(&m_pen[0]);
for(int i=0;i<5;i++)
{
rect.OffsetRect(80,0);//每次绘图右移80个像素
pDC->SelectObject(&m_pen[i]);
pDC->Rectangle(&rect);//绘制矩形
}
pDC->SelectObject(oldPen);
}
//绘制圆角矩形
void CLineTestDlg::DrawRoundRect(CDC *pDC)
{
CRect rect(150,150,220,230);
CPen *oldPen=pDC->SelectObject(&m_pen[0]);
for(int i=0;i<5;i++)
{
rect.OffsetRect(80,0);//每次绘图右移80个像素
pDC->SelectObject(&m_pen[i]);
pDC->RoundRect(&rect,CPoint(15,15));
}
pDC->SelectObject(oldPen);
}
//绘制椭圆
void CLineTestDlg::DrawEllipse(CDC *pDC)
{
CRect rect(150,260,220,310);
CPen *oldPen=pDC->SelectObject(&m_pen[0]);
for(int i=0;i<5;i++)
{
rect.OffsetRect(80,0);
pDC->SelectObject(&m_pen[i]);
pDC->Ellipse(&rect);
}
pDC->SelectObject(oldPen);
}
//绘制弧线
void CLineTestDlg::DrawArc(CDC *pDC)
{
CRect rect(150,400,220,460);
CPoint ptStart(170,440);
CPoint ptEnd(210,400);
CPen *oldPen=pDC->SelectObject(&m_pen[0]);
for(int i=0;i<5;i++)
{
rect.OffsetRect(80,0);
ptStart+=CPoint(80,0);
ptEnd+=CPoint(80,0);
pDC->SelectObject(&m_pen[i]);
pDC->Arc(&rect,ptStart,ptEnd);
}
pDC->SelectObject(oldPen);
}
//绘制直线与弧线
void CLineTestDlg::DrawAngleArc(CDC *pDC)
{
CRect rect(150,500,220,560);
CPoint ptCenter(185,600);
CPoint ptStart(150,630);
int r=30;
float angleStart=0;
float angleEnd=180;
CPen *oldPen=pDC->SelectObject(&m_pen[0]);
for(int i=0;i<5;i++)
{
rect.OffsetRect(80,0);
ptStart+=CPoint(80,0);
pDC->MoveTo(ptStart);
pDC->SelectObject(&m_pen[i]);
pDC->AngleArc(ptCenter.x,ptCenter.y,r,angleStart,angleEnd);
}
pDC->SelectObject(oldPen);
}
运行效果:
PtInRect函数(MFC)
http://www.douban.com/note/26123508/
PtInRect
[声明]
DeclareFunction PtInRect Lib "user32" (lpRect As RECT, pt As POINTAPI) AsLong
[说明]
这个函数判断指定的点是否位于矩形lpRect内部
[参数表]
lpRect--------- RECT,欲检查的矩形
pt------------- POINTAPI,欲判断的点
[返回值]
Long,非零表示成功,零表示失败。会设置GetLastError
[其它]
如点位于矩形四边之内,或矩形的顶部或左侧边线上,则认为它在矩形内部。如位于矩形的右侧或底部边线,则不认为它在矩形内部
2009-02-0316:55:03 路人甲 (sunsing)
使用格式:inc(变量[,增量])
功能:将变量的值增加一个“增量”,
等价于:变量:=变量+增量
说明:[]中的部分为可选项,当无此项时默认增量为1
例1:inc(x);//相当于 x:=x+1;
例2:inc(x,3);//相当于x:=x+3;
------------
格式:dec(变量[,减量])
功能:将变量的值减少一个“减量”,
等价于:变量:=变量-减量
说明:[]中的部分为可选项,无此项时默认减量为1
例1:dec(x);相当于 x:=x-l;
例2:dec(x,3);相当于x:=x-3;
注:在Delphi使用时上网查询的结果
2009-02-0516:51:29 路人甲 (sunsing)
OffsetRect
OffsetRect函数将指定的矩形移动到指定的位置
BOOLOffsetRect(
LPRECTlprc, // 矩形
int dx,// 横向偏移
int dy// 纵向偏移
);
参数:
Lprc:[输入输出]指向一个RECT结构,其中包含了被移动矩形的逻辑坐标
Dx:[输入]指定的矩形左右移动的量。当向左移动的时候,这个参数必须是一个负值。
Dy:[输出]指定的矩形上下移动的量。当想上移动的时候,这个参数应该是一个负值。
返回值:
如果函数成功,返回非0,否则返回0。
备注:
因为使用矩形的目的不同,矩形函数没有很清楚的度量单位。通常,所有矩形的坐标和大小都是用逻辑值来表示。映射模式和矩形函数决定了最终的度量单位。
http://blog.youkuaiyun.com/jiftlixu/article/details/4893166
我现在需要一个静态控件,当鼠标放上去时字体与颜色都要改变,当鼠标离开时在变回来。
现在可以改变字体,但是改变字的颜色还不行。我去网上搜了一下,两种方法,一个在父窗口中相应onctlcolor消息,但是我想在类的内部解决问题,所以不想用这个办法。二就是重写onpain函数。但是,我重写了之后,在OnMouseOver函数中用Invaliadate控件并不会刷新,也就是当鼠标放上去时没有变化。
麻烦各位帮忙看看
void MyCstatic::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
// 改变字体
CStatic::OnMouseMove(nFlags, point);
static bool IsChanged = false;
CFont* cf=new CFont();
CWnd* ptrPrevWnd = NULL;
CRect rect;
if(!IsChanged){//还没改变,鼠标进入
IsChanged = true;
m_pOldFont = this->GetFont();
cf->CreatePointFont(120,"隶书");
m_pCurFont = cf;
m_hCurTextColor = RGB(255,0,0);
ptrPrevWnd = SetCapture();
Invalidate(FALSE);
this->RedrawWindow();
this->SendMessage(WM_PAINT,0,0);
}
else{
GetClientRect(rect);
if(!rect.PtInRect(point)){
IsChanged = false;
this->SetFont(m_pOldFont);
ReleaseCapture();
}
}
}
void MyCstatic::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
m_hOldTextColor = dc.SetTextColor(m_hCurTextColor);
MessageBox("OnPaint","paint");
CString str;
this->GetWindowText(str);
CRect rect;
this->GetClientRect(rect);
dc.SelectObject(m_pCurFont);
dc.SetBkMode(TRANSPARENT);
dc.DrawText(str,rect,DT_CENTER ¦DT_VCENTER¦DT_SINGLELINE);
// Do not call CStatic::OnPaint() for painting messages
}
可以使用消息反射在控件自身处理消息,比如WM_CTLCOLOR。
这个问题第1个回答:
这个问题第2个回答:
其实你并不需要在OnMouseMove里做主动刷新的事情,当鼠标移动到控件上的时候系统会自动重画该控件的。而且调用Invaliadate也应该注意,如果要一个控件Invaliadate,不论你调用多少次,系统都只按照最后一次调用来进行重画,所以调用的多并不一定能得到期望的效果。
楼主要做颜色变换的,最简单的嘛就是重载DrawItem,根据它的参数LPDRAWITEMSTRUCT,可以得到当前控件的状态,根据不同的状态去做不同的绘画的动作咯。
这个问题第3个回答:
ls说的正确,可以通过重写DrawItem函数。