+ -
当前位置:首页 → 问答吧 → 动态添加自绘控件

动态添加自绘控件

时间:2011-12-24

来源:互联网

我自己绘制了一个按钮控件,继承自CButton类,可以实现鼠标移上、获得焦点、按下和普通不同情况的不同形态。
用资源编辑器拖到对话框上然后添加MyButton类的变量可以实现以上各种功能。
但是如果用代码动态添加的话就不行了。
MyButton *d = new MyButton();//这是继承的类,不能实现点击动作,不是响应事件,而是根本就不能点击
CButton *d = new CButton();//这是MFC的类,可以实现按钮动作,可以点击
TCHAR ca[3];
_itow(i,ca,10);
RECT rect;
rect.top = 10*(i/10+1)+i/10*50;
rect.left=i%10*50;
rect.bottom = rect.top+60;
rect.right = rect.left+50;
d->Create(ca,WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON,rect,this,WM_USER+i);
d->ShowWindow(SW_SHOW);
d->UpdateWindow();
望各位大侠指教啊!

作者: jokers_i   发布时间: 2011-12-24

MyButton *d = new MyButton();//这是继承的类,不能实现点击动作,不是响应事件,而是根本就不能点击
// CButton *d = new CButton();//这是MFC的类,可以实现按钮动作,可以点击

作者: schlafenhamster   发布时间: 2011-12-24

RECT rect;
rect.top = 10*(i/10+1)+i/10*50;
rect.left=i%10*50;
rect.bottom = rect.top+60;
rect.right = rect.left+50;
看看rect对不对。
afxDump << rect << "\n";

作者: schlafenhamster   发布时间: 2011-12-24

引用 1 楼 schlafenhamster 的回复:

MyButton *d = new MyButton();//这是继承的类,不能实现点击动作,不是响应事件,而是根本就不能点击
// CButton *d = new CButton();//这是MFC的类,可以实现按钮动作,可以点击

我知道只能定义一个,我的意思是用下面那句可以实现动态添加按钮,但是用我自己的MyButton类就不可以了,
rect应该没问题啊,因为界面上都显示出来了,位置也对,但就是不能改变状态,鼠标按下和获得焦点是都不变。
而用手动添加的却可以。

作者: jokers_i   发布时间: 2011-12-24

WM_USER+i对不对?与资源编辑器拖到对话框上的比较,
响应函数要用到这些ID

作者: schlafenhamster   发布时间: 2011-12-24

引用 4 楼 schlafenhamster 的回复:

WM_USER+i对不对?与资源编辑器拖到对话框上的比较,
响应函数要用到这些ID

这个应该也没问题,因为用CButton的话这些ID都是可以用的, 而且我要的效果并不是相应点击事件,而只是实现自会控件的效果,应该和ID号没关系
void MyButton::DrawItem(LPDRAWITEMSTRUCT lpDS)
{
CDC dc;
dc.Attach(lpDS->hDC);
CString text;
this->GetWindowTextW(text);
if(lpDS->itemState&ODS_SELECTED)
color = RGB(255,1,1);
else if(lpDS->itemState&ODS_FOCUS)
color = RGB(1,255,1);
else if(m_hover)
color = RGB(188,50,99);
else
color = RGB(1,1,255);
CRgn rgn;
RECT rect = lpDS->rcItem;
rgn.CreateEllipticRgn(rect.left,rect.top,rect.right,rect.bottom);
dc.FillRgn(&rgn,&CBrush(color));

SetBkMode(lpDS->hDC,TRANSPARENT);

CFont f;
f.CreatePointFont(150,L"微软雅黑");
dc.SelectObject(&f);
::DrawTextW(lpDS->hDC,text,
text.GetLength(),
&(lpDS->rcItem),
DT_CENTER|DT_VCENTER|DT_SINGLELINE);
dc.Detach();
}
这是重载的DrawItem函数,手动添加的话是可以实现的,但是动态添加的话就不可以了。

作者: jokers_i   发布时间: 2011-12-24

“而是根本就不能点击”,什么意思,程序出错?

作者: schlafenhamster   发布时间: 2011-12-24

引用 6 楼 schlafenhamster 的回复:

“而是根本就不能点击”,什么意思,程序出错?

还是上图吧:
这是动态添加的CButton按钮,可以点击还有鼠标移上颜色变化

这是动态添加的MyButton按钮,鼠标移上没有变化,而右下方的按钮是手动添加的MyButton按钮,可以实现这些功能

作者: jokers_i   发布时间: 2011-12-24

这是右下方按钮的点击事件函数:
int i = 0;
void CDIDlg::OnBnClickedMyButton()
{
MyButton *d = new MyButton();
//CButton *d = new CButton();
TCHAR ca[3];
_itow(i,ca,10);
RECT rect;
rect.top = 10*(i/10+1)+i/10*50;
rect.left=i%10*50;
rect.bottom = rect.top+60;
rect.right = rect.left+50;
d->Create(ca,WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON,rect,this,WM_USER+i);
d->ShowWindow(SW_SHOW);
d->UpdateWindow();
d->EnableWindow();
i++;
}

作者: jokers_i   发布时间: 2011-12-24

C/C++ code
这是右下方按钮的点击事件函数:
int i = 0;
void CDIDlg::OnBnClickedMyButton()
{
MyButton *d = new MyButton();
//CButton *d = new CButton();    
TCHAR ca[3];
_itow(i,ca,10);
RECT rect;
rect.top = 10*(i/10+1)+i/10*50;
rect.left=i%10*50;
rect.bottom = rect.top+60;
rect.right = rect.left+50;
d->Create(ca,WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON,rect,this,WM_USER+i);
d->ShowWindow(SW_SHOW);
d->UpdateWindow();
d->EnableWindow();
i++;
}

作者: jokers_i   发布时间: 2011-12-24

动态创建后应该添加点击响应命令啊

作者: heksn   发布时间: 2011-12-24

引用 10 楼 heksn 的回复:

动态创建后应该添加点击响应命令啊

我并没有想让每个按钮都有响应时间,而是有不同状态的颜色改变,重载的DrawItem中有实现这个功能。
如果右下方按个按钮不添加点击事件响应函数的话也是有这个功能的,我怀疑MFC在创建这些对话框上的按钮时都做了些什么?是不是只是简单的调用了Create函数?
尝试F11一路到创建对话框还是没有看出来。

作者: jokers_i   发布时间: 2011-12-24

上传到你的资源,我看看。

作者: schlafenhamster   发布时间: 2011-12-24

也可是说是动态添加的自绘控件不能获取焦点,这个问题不知道能不能解决?

作者: jokers_i   发布时间: 2011-12-24