为什么我自绘的edit控件一开始就会得到焦点?

maomao85 2014-01-05 04:15:27

如上图所示,我的鼠标都没有移动到edit控件上,就是一进入到这个界面的时候,edit控件就获取了焦点这事为什么啊?我用CEdit类的派生类CMyEdit来重绘,代码如下:

#pragma once
#ifndef _H_MYEDIT_H
#define _H_MYEDIT_H

class CMyEdit :public CEdit
{
DECLARE_DYNAMIC(CMyEdit)
public:
CMyEdit(void);
~CMyEdit(void);
void DrawFrame();
void Text();

protected:

afx_msg void OnMouseLeave();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnMouseHover(UINT nFlags, CPoint point);
afx_msg void OnNcPaint();
// afx_msg void OnPaint();
// afx_msg void OnSetFocus(CWnd* pOldWnd);
DECLARE_MESSAGE_MAP()

public:
bool m_isinedit;
CBrush m_normalbrush1;
CBrush m_normalbrush2;
CBrush m_hoverbrush1;
CBrush m_hoverbrush2;
bool isfocus;
};

#endif

实现文件

#include "StdAfx.h"
#include "MyEdit.h"

IMPLEMENT_DYNAMIC(CMyEdit, CEdit)
CMyEdit::CMyEdit(void)
{
m_isinedit=false;
m_hoverbrush1.CreateSolidBrush(0xFDC860);
m_hoverbrush2.CreateSolidBrush(0xE7AC49);
m_normalbrush1.CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
m_normalbrush2.CreateSolidBrush(GetSysColor(COLOR_WINDOWFRAME));
isfocus=false;
}


CMyEdit::~CMyEdit(void)
{
}

BEGIN_MESSAGE_MAP(CMyEdit, CEdit)
ON_WM_MOUSEMOVE()
ON_WM_MOUSELEAVE()
ON_WM_MOUSEHOVER()
ON_WM_NCPAINT()
/* ON_WM_SETFOCUS()*/
END_MESSAGE_MAP()


void CMyEdit::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_isinedit)
{
TRACKMOUSEEVENT mouseevent;
mouseevent.cbSize=sizeof(mouseevent);
//mouseevent.dwFlags=TME_LEAVE|TME_HOVER;
mouseevent.dwFlags=TME_LEAVE;
mouseevent.dwHoverTime=10;
mouseevent.hwndTrack=m_hWnd;
_TrackMouseEvent(&mouseevent);
m_isinedit=true;
DrawFrame();
}
}

void CMyEdit::OnMouseLeave()
{
m_isinedit=false;
DrawFrame();
isfocus=true;
}

void CMyEdit::OnMouseHover(UINT nFlags, CPoint point)
{
DrawFrame();
}

void CMyEdit::OnNcPaint()
{
CEdit::OnNcPaint();//先调用基类的OnNcPaint()让系统画图,系统画完后再我们画
DrawFrame();
if (!isfocus)
{
Text();
TRACE("1\n");
}
}

// void CMyEdit::OnPaint()
// {
// CEdit::OnPaint();
// DrawFrame();
// }

void CMyEdit::DrawFrame()
{
CDC* pDC = GetWindowDC( );
CRect rect;
GetWindowRect( &rect);
rect.OffsetRect( -rect.left, -rect.top);
if (m_isinedit)
{
pDC->FrameRect( &rect, &m_hoverbrush1);
rect.InflateRect(-1,-1);
pDC->FrameRect( &rect, &m_hoverbrush2);
}
else
{
pDC->FrameRect( &rect, &m_normalbrush1);
rect.InflateRect(-1,-1);
pDC->FrameRect( &rect, &m_normalbrush2);
}
ReleaseDC( pDC);
}

void CMyEdit::Text()
{
CDC* pDC = GetDC();
CRect rect;
GetClientRect(&rect);
rect.OffsetRect(1,1);
pDC->SelectObject( (*GetFont()) );
pDC->SetBkMode(TRANSPARENT);
CString text=_T("hello");
pDC->DrawText (text,&rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER ) ;
}

// void CMyEdit::OnSetFocus(CWnd* pOldWnd)
// {
// CEdit::OnSetFocus(pOldWnd);
// isfocus=true;
// }


我这里有借鉴版主邓学彬来实现edit框架重绘~~
...全文
323 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
gfm688 2014-01-07
  • 打赏
  • 举报
回复
引用 33 楼 maomao85 的回复:
在BeginPaint 会自动设置剪切区域,这个区域是windows帮我设置的吗?那我这个edit控件重绘的情况,无效区域是windows自动帮我设置为整个客户区?
The BeginPaint function automatically sets the clipping region of the device context to exclude any area outside the update region. 这个剪切区域就是BeginPaint帮你设置的 下面的红字部份就是说明什么情况下无效区域是windows自动帮你设置,当然,不一定是整个客户区的 The update region is set by the InvalidateRect or InvalidateRgn function and by the system after sizing, moving, creating, scrolling, or any other operation that affects the client area. 我所说的无效区域就是MSDN所说的update region,因为它可以由InvalidateRect或InvalidateRgn设置的,而Invalid的意思就是无效,所以称之为无效区域
maomao85 2014-01-06
  • 打赏
  • 举报
回复
引用 31 楼 gfm688 的回复:
据此,可以分析一下CEdit::OnPaint();先后顺序的不同产生的不同结果: 如果CEdit::OnPaint();先执行,那么,CPaintDC dc(this);执行时已没有无效区域,相当于dc的所有区域都是剪切区域(在剪切区域绘制不会有任何效果) 反之,如果CPaintDC dc(this);先执行, CEdit::OnPaint();也不会绘制出任何东西出来 画边框的时候,你是用GetWindowDC获取的DC,剪切区域不一样
在BeginPaint 会自动设置剪切区域,这个区域是windows帮我设置的吗?那我这个edit控件重绘的情况,无效区域是windows自动帮我设置为整个客户区?
maomao85 2014-01-06
  • 打赏
  • 举报
回复
引用 31 楼 gfm688 的回复:
据此,可以分析一下CEdit::OnPaint();先后顺序的不同产生的不同结果: 如果CEdit::OnPaint();先执行,那么,CPaintDC dc(this);执行时已没有无效区域,相当于dc的所有区域都是剪切区域(在剪切区域绘制不会有任何效果) 反之,如果CPaintDC dc(this);先执行, CEdit::OnPaint();也不会绘制出任何东西出来 画边框的时候,你是用GetWindowDC获取的DC,剪切区域不一样
十分感谢~~你的知识好扎实啊,很多细节都懂。可以结贴了~~
gfm688 2014-01-06
  • 打赏
  • 举报
回复
引用 29 楼 gfm688 的回复:
因为CEdit::OnPaint();和CPaintDC dc(this);都会调用BeginPaint BeginPaint 会自动设置剪切区域(在无效区域以外的区域绘制不会有任何效果),并使无效区域成为有效区域
据此,可以分析一下CEdit::OnPaint();先后顺序的不同产生的不同结果: 如果CEdit::OnPaint();先执行,那么,CPaintDC dc(this);执行时已没有无效区域,相当于dc的所有区域都是剪切区域(在剪切区域绘制不会有任何效果) 反之,如果CPaintDC dc(this);先执行, CEdit::OnPaint();也不会绘制出任何东西出来
引用 30 楼 maomao85 的回复:
那为什么我画边框的时候,就不会出现这个问题呢?我还是没懂~~
画边框的时候,你是用GetWindowDC获取的DC,剪切区域不一样
maomao85 2014-01-06
  • 打赏
  • 举报
回复
引用 29 楼 gfm688 的回复:
因为CEdit::OnPaint();和CPaintDC dc(this);都会调用BeginPaint BeginPaint 会自动设置剪切区域(在无效区域以外的区域绘制不会有任何效果),并使无效区域成为有效区域
那为什么我画边框的时候,就不会出现这个问题呢?我还是没懂~~
gfm688 2014-01-06
  • 打赏
  • 举报
回复
引用 26 楼 maomao85 的回复:
[quote=引用 25 楼 dingxz105090 的回复:] 把CEdit::OnPaint()放到最后也可以看到,这个不太清楚怎么回事
我测试了下,是啊,这是怎么回事.....[/quote] 因为CEdit::OnPaint();和CPaintDC dc(this);都会调用BeginPaint BeginPaint 会自动设置剪切区域(在无效区域以外的区域绘制不会有任何效果),并使无效区域成为有效区域
maomao85 2014-01-05
  • 打赏
  • 举报
回复
引用 27 楼 line_us 的回复:
怎么会这样。
你指的什么?
line_us 2014-01-05
  • 打赏
  • 举报
回复
怎么会这样。
maomao85 2014-01-05
  • 打赏
  • 举报
回复
引用 25 楼 dingxz105090 的回复:
把CEdit::OnPaint()放到最后也可以看到,这个不太清楚怎么回事
我测试了下,是啊,这是怎么回事.....
凌乱哥 2014-01-05
  • 打赏
  • 举报
回复
引用 23 楼 maomao85 的回复:
为什么这样我看不到hello,只有把CEdit::OnPaint()去掉才看的到? 我先等默认的OnPaint()画完后我再画,为什么就看到hello了?
把CEdit::OnPaint()放到最后也可以看到,这个不太清楚怎么回事
maomao85 2014-01-05
  • 打赏
  • 举报
回复
引用 22 楼 dingxz105090 的回复:
就是你的原程序放大了的
我的程序是画了2层框框的~~
maomao85 2014-01-05
  • 打赏
  • 举报
回复
引用 11 楼 dingxz105090 的回复:
你只要把void CMyEdit::OnPaint()加上,什么都不要写就可以看到Hello了

void  CMyEdit::OnPaint()
 {
 //	CEdit::OnPaint();
 }

void  CMyEdit::OnPaint()
{
	CEdit::OnPaint();
	CPaintDC dc(this);
	CRect r;
	GetClientRect(&r);
	dc.SetBkMode(TRANSPARENT);
	CString text=_T("hello"); 
	dc.DrawText (text,&r,DT_SINGLELINE | DT_CENTER | DT_VCENTER ) ;  
}
为什么这样我看不到hello,只有把CEdit::OnPaint()去掉才看的到? 我先等默认的OnPaint()画完后我再画,为什么就看到hello了?
凌乱哥 2014-01-05
  • 打赏
  • 举报
回复
就是你的原程序放大了的
maomao85 2014-01-05
  • 打赏
  • 举报
回复
引用 20 楼 dingxz105090 的回复:
就是框框了,那就给你看个放大的有焦点带蓝色边框的图
你这是画了2层蓝色的框框咩??
凌乱哥 2014-01-05
  • 打赏
  • 举报
回复
就是框框了,那就给你看个放大的有焦点带蓝色边框的图
maomao85 2014-01-05
  • 打赏
  • 举报
回复
引用 18 楼 dingxz105090 的回复:
你可以改写一下OnPain,自己测试看看就知道了

void  CMyEdit::OnPaint()
 {
	 CPaintDC dc(this);
	 CRect r;
	 GetClientRect(&r);//这样取得的就是客户区
	 dc.FillSolidRect(&r,RGB(255,0,0));//选一个显眼的颜色来测试
 //CEdit::OnPaint();
 }
感觉看的好模糊啊,我在网上看有人说,非客户区就是比客户区长宽大2个像素的那个框框
凌乱哥 2014-01-05
  • 打赏
  • 举报
回复
你可以改写一下OnPain,自己测试看看就知道了

void CMyEdit::OnPaint()
{
CPaintDC dc(this);
CRect r;
GetClientRect(&r);//这样取得的就是客户区
dc.FillSolidRect(&r,RGB(255,0,0));//选一个显眼的颜色来测试
//CEdit::OnPaint();
}



maomao85 2014-01-05
  • 打赏
  • 举报
回复
引用 16 楼 dingxz105090 的回复:
OnPaint是画客户区,OnNcPaint是画非客户区,边框自然属于后者了
那我有个疑问,对于edit控件来说 非客户区有多大?就是一圈边框吗?
凌乱哥 2014-01-05
  • 打赏
  • 举报
回复
OnPaint是画客户区,OnNcPaint是画非客户区,边框自然属于后者了
maomao85 2014-01-05
  • 打赏
  • 举报
回复
引用 13 楼 dingxz105090 的回复:
个人认为,你没重写OnPaint函数,所以WM_PAINT消息还是按默认处理了,即调用了CEdit::OnPaint();
那位什么我的边框是画的出来的?我没有重写OnPaint函数
加载更多回复(14)

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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