MFC OnPaint函数得问题

梦竹 2011-11-22 09:59:10
各位大侠,我正在学习MFC,对MFC掌握不足,所以有很多问题希望大家帮忙。

最近写一个控件,建立的是dlg的app工程(用vs2005做的),在其中写了一个Cmyctrl类,继承自CWnd

实现的目标是要用鼠标拖动一个坐标的x,y轴来得到交叉点的位置。

主要代码如下:
//按下按钮的时候捕获按下的消息,将(BOOL)m_LBtnDown 设置为真
void Cmyctrl::OnLButtonDown(UINT nFlags, CPoint point)
{
m_LBtnDown = TRUE;
this->SetCapture();
}
//放开鼠标时释放
void Cmyctrl::OnLButtonUp(UINT nFlags, CPoint point)
{
m_LBtnDown = FALSE;
ReleaseCapture();
}
//移动的时候如果移动到坐标线的轴上的时候改变鼠标形状,并判断是在横坐标还是纵坐标上,然后跟踪鼠标位置,重画界面
void Cmyctrl::OnMouseMove(UINT nFlags, CPoint point)
{
HWND hwnd = ::GetActiveWindow();
if(point.x==pcenter.x && !m_LBtnDown)
{
m_VLineSelected = TRUE;
m_HLineSelected = FALSE;
SetCursor(LoadCursor(NULL,IDC_SIZEWE));
}
else if(point.y == pcenter.y && !m_LBtnDown)
{
m_HLineSelected = TRUE;
m_VLineSelected = FALSE;
SetCursor(LoadCursor(NULL,IDC_SIZENS));
}
else if(!m_LBtnDown)
{
m_HLineSelected = FALSE;
m_HLineSelected = FALSE;
SetCursor(LoadCursor(NULL,IDC_ARROW));
}

if(m_LBtnDown && m_HLineSelected)
{
pcenter.y = point.y;
::InvalidateRect(hwnd,NULL,TRUE);
}
else if(m_LBtnDown && m_VLineSelected)
{
pcenter.x = point.x;
::InvalidateRect(hwnd,NULL,TRUE);
}
}

//OnPaint函数
void Cmyctrl::OnPaint()
{
CPaintDC dc(this);
CDC * pDC = new CDC;
CRect rectClient;
CBitmap bitmaptmp,*pOldBitmap;
//获取客户区信息
GetClientRect(rectClient);
TRACE(L"%d,%d,%d,%d\n",rectClient.left,rectClient.top,rectClient.right,rectClient.bottom);
//创建位图内存
bitmaptmp.CreateCompatibleBitmap(&dc,rectClient.Width(),rectClient.Height());
pDC->CreateCompatibleDC(&dc);
pOldBitmap = pDC->SelectObject(&bitmaptmp);
//填充客户区
pDC->FillSolidRect(&rectClient,0xff3030);
//画坐标线
pDC->MoveTo(rectClient.left,pcenter.y);
pDC->LineTo(rectClient.right,pcenter.y);
pDC->MoveTo(pcenter.x,rectClient.top);
pDC->LineTo(pcenter.x,rectClient.bottom);

dc.BitBlt(0, 0, rectClient.Width(), rectClient.Height(), pDC, 0, 0, SRCCOPY);

pDC->SelectObject(pOldBitmap);
ReleaseDC(pDC);
delete pDC;
}


这样做有个问题,就是在拖动坐标线的时候会不停闪屏,特别不舒服,请大虾指教,怎么做才能不出现闪屏,还能正常拖动坐标线。

...全文
427 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
梦竹 2011-11-24
  • 打赏
  • 举报
回复
这其实不是因为刷屏过快的原因,而是因为我是用的invalidaterect,换用invalidate函数就行了

关于invalidaterect和invalidate的区别见:http://blog.sina.com.cn/s/blog_5b2d79e90100f5w6.html
梦竹 2011-11-24
  • 打赏
  • 举报
回复
问题解决,真想把这个分给自己,但是这个贴吧的规则是这样定的,没有办法,哈哈哈
leegoex 2011-11-23
  • 打赏
  • 举报
回复
双缓冲你已经使用了,还是闪烁有可能是其他原因,推荐你看下这个
http://msdn.microsoft.com/en-us/library/ms969905.aspx
梦竹 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 mfcing 的回复:]

还可以这样做
设置一个定时器
在定时器里面Invalidarte(TRUE)或者InvalidateRect();
定时器的时间可以自己试出来
怎样才能适合自己的
看起来不会闪得那么明显
[/Quote]

试过,效果不好
梦竹 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 mfcing 的回复:]

CPaintDC dc(this);
CDC * pDC = new CDC;
CRect rectClient;
CBitmap bitmaptmp,*pOldBitmap;
//获取客户区信息
GetClientRect(rectClient);
TRACE(L"%d,%d,%d,%d\n",rectClient.left,rectClient.top,rectClient.ri……
[/Quote]

这个我知道啊,现在就是为了把闪屏的这个问题解决,要是在一个函数里都不行的话放到多个函数中就更慢了
疯狂-的-蜗牛 2011-11-23
  • 打赏
  • 举报
回复
还可以这样做
设置一个定时器
在定时器里面Invalidarte(TRUE)或者InvalidateRect();
定时器的时间可以自己试出来
怎样才能适合自己的
看起来不会闪得那么明显
疯狂-的-蜗牛 2011-11-23
  • 打赏
  • 举报
回复
CPaintDC dc(this);
CDC * pDC = new CDC;
CRect rectClient;
CBitmap bitmaptmp,*pOldBitmap;
//获取客户区信息
GetClientRect(rectClient);
TRACE(L"%d,%d,%d,%d\n",rectClient.left,rectClient.top,rectClient.right,rectClient.bottom);
//创建位图内存
bitmaptmp.CreateCompatibleBitmap(&dc,rectClient.Width(),rectClient.Height());
pDC->CreateCompatibleDC(&dc);
pOldBitmap = pDC->SelectObject(&bitmaptmp);
//填充客户区
pDC->FillSolidRect(&rectClient,0xff3030);
//画坐标线
pDC->MoveTo(rectClient.left,pcenter.y);
pDC->LineTo(rectClient.right,pcenter.y);
pDC->MoveTo(pcenter.x,rectClient.top);
pDC->LineTo(pcenter.x,rectClient.bottom);

dc.BitBlt(0, 0, rectClient.Width(), rectClient.Height(), pDC, 0, 0, SRCCOPY);

pDC->SelectObject(pOldBitmap);
ReleaseDC(pDC);
delete pDC
你的这段代码应该重新放到一个函数里面去
尽量模块化
全放到OnPaint里面不好
梦竹 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 junkli 的回复:]

添加CClient cdc(this);试试
[/Quote]

大哥,求详细呀,新手不懂啊
梦竹 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 leegoex 的回复:]

添加WM_ERASEBKGND消息的处理,在里面添加return TRUE试试,例如
C/C++ code

BOOL CMyCtrl::OnEraseBkGnd()
{
return TRUE;
}
[/Quote]
不行啊,闪烁依然很明显
junkli 2011-11-23
  • 打赏
  • 举报
回复
添加CClient cdc(this);试试
梦竹 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 leegoex 的回复:]

添加WM_ERASEBKGND消息的处理,在里面添加return TRUE试试,例如
C/C++ code

BOOL CMyCtrl::OnEraseBkGnd()
{
return TRUE;
}
[/Quote]

大哥,能不能给个详细点的呢,怎么先画图怎么加载,用什么数据类型,最好能给个例子,谢谢!^_^
梦竹 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用楼主 luwenjin19881016 的回复:]
各位大侠,我正在学习MFC,对MFC掌握不足,所以有很多问题希望大家帮忙。

最近写一个控件,建立的是dlg的app工程(用vs2005做的),在其中写了一个Cmyctrl类,继承自CWnd

实现的目标是要用鼠标拖动一个坐标的x,y轴来得到交叉点的位置。

主要代码如下:
//按下按钮的时候捕获按下的消息,将(BOOL)m_LBtnDown 设置为真
voi……
[/Quote]


试试先,谢谢
诶呦 2011-11-22
  • 打赏
  • 举报
回复
先把线在图上画好然后贴出来(也就是双缓冲),然后的方法如楼上所说。可以达到减缓闪烁的效果。
leegoex 2011-11-22
  • 打赏
  • 举报
回复
添加WM_ERASEBKGND消息的处理,在里面添加return TRUE试试,例如

BOOL CMyCtrl::OnEraseBkGnd()
{
return TRUE;
}

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧