CMFCButton类介绍
来源:互联网 发布:打印发票软件 编辑:程序博客网 时间:2024/05/21 07:08
CMFCButton类介绍
此类是基于MFC基本CButton类型集成而来的,具备CButton拥有的基本按钮属性和操作方法,此外它还具有一些特殊的功能:
----------------------------------------------------------------------------------------
更改文字: button->SetWindowTextW(_T("强制更改"));
更改背景颜色: button->SetFaceColor(RGB(153, 217, 234));
更改字体颜色: button->SetTextColor(RGB(255, 255, 255));
更改高亮颜色: button->SetTextHotColor(RGB(63, 72, 204));
更改位置: button->MoveWindow(50, 50, 100, 70);
鼠标经过时变成手势: button->SetMouseCursorHand();
工具提示: button->SetTooltip(_T("俺是提示"));
加载图片: button->SetImage(IDB_BITMAP1);
----------------------------------------------------------------------------------------
其中button为CMFCButton指针:CMFCButton *button;
由于CMFCButton是由MFC自己提供的,所以只要在源文件中加入“include <afxbutton.h>”即可直接使用。此外基于CMFCButton的派生类也有很多:
每个派生类都有某一方面的功能。
CMFCButton类使用方法
1、使用在对话框上直接拖放一个标准按钮控件,为此按钮添加变量,然后用CMFCButton直接替换CButton即可。如在对话框 上放置了两个按钮BUTTON1和BUTTON2.
2、在OnInitDlg或OnPaint等函数处对按钮进行修改,如在OnInitDlg中添加以下语句:
则显示效果如下所示:// 更改文字
button1->SetWindowTextW(_T("强制更改"));
// 更改背景颜色
button1->SetFaceColor(RGB(153, 217, 234));
// 更改字体颜色
button1->SetTextColor(RGB(255, 255, 255));
// 更改高亮颜色
button1->SetTextHotColor(RGB(63, 72, 204));
// 更改位置
button1->MoveWindow(50, 50, 100, 70);
// 鼠标经过时变成手势
button1->SetMouseCursorHand();
// 工具提示
button1->SetTooltip(_T("俺是提示"));
CMFCButton * button2 = new CMFCButton;
button2->Create(_T("Test Button"), WS_VISIBLE, CRect(160, 15, 280, 150), this, IDC_BUTTON2);
// 加载图片
button2->SetImage(IDB_BITMAP1);
使用起来比较简单,但是还是有缺陷,请看下节内容。
CMFCButton使用过程中发生内存泄露 - 此处引用他人地方,本人使用也遇到了此问题
问题发现过程:
--------------------------------------------------------------------------------------------------------
打开vs2010,新建一个对话框工程,什么都不做,运行,推出的时候看不到内存泄露,但是当你拖一个mfc button到对话框上时,运行程序,推出的时候会看到发生了内存泄露。现在还不知道什么原因。
--------------------------------------------------------------------------------------------------------
具体的原因分析:
--------------------------------------------------------------------------------------------------------
首先我们应该从VS2010提供的一些新类,比如CMFCButton的创建过程着手分析。
在CDialog::OnInitDialog()的执行过程中,会调用CMFCControlContainer::SubclassDlgControls()函数对对话框内的各种控件进行初始化,由于VS2010引入了一些新的控件类,这些控件类在本质上又不是新创造出来的类,而是原来的一些类的子类,比如CMFCButton就是CButton的一个子类,这样在一个CMFCButton创建的时候就需要进行一次重子类化的过程。
--------------------------------------------------------------------------------------------------------
详细的跟踪过程如下:
--------------------------------------------------------------------------------------------------------
1、 CDialog::OnInitDialog()函数会创建对话框界面上的控件,然后把这些对象保存起来。这个时候如果对话框模板被定义了会执
行ExecuteDlgInit()函数。
2、 ExecuteDlgInit()函数会调用CMFCControlContainer::SubclassDlgControls()开始子类化对话框内的控件。
3、 接下来CMFCControlContainer::CreateDlgControl()函数被调用,会创建一个CMFCBUTTON对象。
4、 然后会将该CMFCBUTTON对象进行子类化SubclassWindow()。
5、 然后会进入CMFCBUTTON对象的PreSubclassWindow()函数,这个函数基本上没有做什么事情。
6、 然后函数返回到ExecuteDlgInit()函数,这个时候对话框会发送一个WM_MFC_INITCTRL消息给该CMFCBUTTON对象。也就
是在这个时候CMFCBUTTON对象的消息提示控件m_pToolTip第一次被创建。
而这个创建的过程是委托给一个CTooltipManager类来管理的,这个类会将当前创建消息提示控件m_pToolTip的窗口(也就
是m_pToolTip的父窗口)的句柄记录下来。
7、 然后到了CWnd::UpdateData()函数,他用于更新和控件绑定的数据,接下来到了DoDataExchange(CDataExchange* pDX)
函数,然后是DDX_Control(pDX, IDC_MFCBUTTON1, mfcbut)函数,在这个函数中会重新子类化控件,即
CMFCControlContainer* pMFCCtrlContainer = pDX->m_pDlgWnd->GetMFCControlContainer();if (pMFCCtrlContainer != NULL && pMFCCtrlContainer->IsSubclassedFeaturePackControl(hWndCtrl)){pMFCCtrlContainer->ReSubclassControl(hWndCtrl, (WORD)nIDC, rControl);return;}
8、 然后消息又走到了CMFCButton对象的PreSubclassWindow()函数。
9、 子类化成功后CMFCControlContainer类又会发送一个WM_MFC_INITCTRL消息。又对m_pToolTip进行了初始化。
然而在该CMFCButton对象被销毁的时候,即OnDestroy()中,会把最后一次创建的m_pToolTip对象删除。这貌似不合逻辑,似乎少删除了一个m_pToolTip对象。
--------------------------------------------------------------------------------------------------------
果然是这么回事:
我想了很久才发现,第一次子类化的时候用到的CMFCButton对象是我们不绑定任何数据的对象,而第二次用到的才是我们定义的CMFCButton对象。那么按照顺序就是“开始的控件”-子类化-“第一个控件”--子类化--“第二个控件”,实际上第二次子类化的并不是最开始的那个对象。而实际上“第一个控件”和“第二个控件”的句柄是相同的,那么在“delete”的时候只会销毁第二次生成的“m_pToolTip”,第一次的没有被销毁。这样就合理了。
--------------------------------------------------------------------------------------------------------
解决的办法有两种:
1、动态创建CMFCButton对象。
2、修改DoDataExchange函数,主要是重载DDX_Control函数,在其中销毁tooltip控件。当你确定在使用CMFCButton的时候,可以调用这个函数。即重载CMFCButton中的DDX_Control函数:
void MFC_DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl){HWND hWndCtrl;pDX->m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);TCHAR lpszClassName [MAX_CLASS_NAME + 1];::GetClassName(hWndCtrl, lpszClassName, MAX_CLASS_NAME);CString strClass = lpszClassName;if (strClass == _T("MFCButton")){CMFCButton *pMFCButton = (CMFCButton *)pDX->m_pDlgWnd->GetDlgItem(nIDC);CToolTipCtrl& pToolTipCtrl = pMFCButton->GetToolTipCtrl();if (pToolTipCtrl.m_hWnd != NULL){CToolTipCtrl* pCtrl = &pToolTipCtrl;CTooltipManager::DeleteToolTip(pCtrl);}}DDX_Control(pDX, nIDC, rControl);}void CShrinkWndDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);MFC_DDX_Control(pDX, IDC_MFCBUTTON1, mfcbut);}
0 0
- CMFCButton类介绍
- CMFCButton
- CMFCBUTTON
- VS2010的MFC的CMFCButton等类的疑惑
- MFC中CMFCButton类改变颜色的使用
- CMFCButton 风格
- CMFCButton控件
- CMFCButton使用简介
- CMFCButton内存泄漏
- CMFCButton的问题 高手指教
- MFC控件积累——CMFCButton控件
- CMFCBUTTON使用过程中发生内存泄露
- 如何让一个CMFCButton在圆形区域内有效?
- MFC CMFCButton不能改变颜色和其他属性解决方法
- MFC中使用CMFCBUTTON按钮关闭对话框出现内存泄漏
- WinInet类的介绍
- UML 类图介绍
- UML 类图介绍
- UVA 10061-How many zero's and how many digits
- SDUT 3333 数据结构实验之栈六:下一较大值(二)
- React Native(Mac篇)
- 使用Jmeter进行http接口性能测试
- ios-微信浏览器刷新标题document.title
- CMFCButton类介绍
- Eclipse常用快捷键
- 美团机器学习岗面经
- 【CodeForces】699A - One Bomb(思维)
- Service Intent must be explicit错误
- UVA 350-Pseudo-Random Numbers
- 接口对象的实例化
- 年度创始人李志飞:出门问问打造接地气的人工智能
- Google账号登录不上Android Studio