C++ 控件关联对象
1.C++控件关联对象
方法1:用向导关联变量
CEdit× m_edit; m_edit = (CEdit*)GetDlgItem(IDC_EDIT1); // GetDlgItem只能获取子控件,可以在AboutDialog创建时,把句柄或窗口类的指针保存起来 // GetDlgItem返回CWIN*,这种方法关联的控件必须是CWIN类的派生类
方法2:GetDlgItem(IDC_EDIT1)获取句柄赋值
CEdit× m_edit; m_edit = (CEdit*)GetDlgItem(IDC_EDIT1); // GetDlgItem只能获取子控件,可以在AboutDialog创建时,把句柄或窗口类的指针保存起来 // GetDlgItem返回CWIN*,这种方法关联的控件必须是CWIN类的派生类
方法3:在用Tab控件添加关联变量时发现控件变量那里是灰的, 为了关联控件变量,有一种方法:
1.首先为控件添加变量,如CTabCtrl m_TabCtrl.
2.在OnInitDialog函数中,添加 m_TabCtrl.SubclassDlgItem(IDC_TAB1,this); //IDC_TAB1是控件ID
3.这样m_TabCtrl就是控件IDC_TAB1的关联变量。
关于窗口子类化:SubclassDlgItem
子类化概念: 用一个窗口过程替换另一个过程的行为叫SUBCLASSING,这是WINDOWS意义上的派生子类,与面向对象语言的派生子类是完全不同的概念。 (向导添加关联变量)在VC 中,DoDataExchange函数中的DDX_Control之类的函数会调用SubClassDlgItem完成窗口子类化,这样控件自己就能处理消息了。 子类化步骤: (1)窗体上放一个基类控件,如:CEdit—拖放 (2)有基类派生一个派生类,并生成该对象---如果这里用的是基类控件对象而不派生==就相当于变量关联 CEdit->(继承)CMyEdit; // 派生类的定义 CMyEdit m_myEdit; // 创建派生类对象 (3)将窗体上控件子类化(subclass)为派生类的对象CMyEdit, 等价于将窗体上拖放的控件改变为派生类的对象—类型变了 BOOL CMyDialog::OnInitDialog() //在窗体初始化函数OnInitDialog中进行子类化 { CDialog::OnInitDialog(); m_MyEdit.SubclassDlgItem(ID,CWnd* pParent,this); return TRUE; } 子类化后的效果以及相关函数: 简单来就是 对象转化和过程替换,拖放对象转化为派生对象,拖放对象的事件过程都有派生对象同名过程替换即由派生对象处理。 1.基类控件对象(拖放控件)变成了(自己派生的对象)派生控件对象 ; 2.该派生对象将接管控件对象的消息处理; 3.过程替换-对Dialog 上面的某个控件SubClass(子类化)后,其原控件对象的WindowProc(事件过程等)替换成你自己写的新派生控件CYourCWndClass 的 WindowProc(同名过程),这样你就可以处理这个控件的所有消息了;用 ClassWizard 维护自己的 CYourCWndClass 就可以了 SubclassDlgItem把某个空间类派生对象与对窗体中已有的控件动态连接起来,该派生对象将接管控件对象的消息处理,从而使控件变为派生对象的类型,具有新的特性. 实际应用—设计新的控件: 要在程序中创建新设计的控件,显然不能用自动创建的办法,因为对话框模板对新控件的特性一无所知. 原始方法:程序可以用手工方法创建控件,在调用派生类的Create函数时,派生类会调用基类的Create函数创建控件.用Create函数创建控件是一件比较麻烦的工作, 程序需要为函数指定一大堆的控件风格以及控件的坐标和ID.特别是控件的坐标,没有经验的程序员很难确切地安排控件的位置和大小,往往需要反复调整. 利用子类化方法:利用MFC的CWnd::SubclassDlgItem提供的动态连接功能,可以避免Create函数的许多麻烦,该函数大大简化了在对话框中创建派生控件的过程. 区别: 1.原始方法的过程:在用手工方法创建控件时,先要构建一个控件对象,然后再用Create函数在屏幕上创建控件窗口,也就是说,控件的创建工作是由控件对象完成的. 2.子类化方法的过程:动态连接的思路则不同,SubclassDlgItem可以把对话框中已有的控件与某个窗口对象动态连接起来,该窗口对象将接管控件的消息处理,从而使控件具有新的特性.
2.子窗口Create
m_drawPointDlg为子对话框(style)
m_drawPointDlg.Create(ID, ParentHandle);
3.ATL SubclassWindow
std::map<DWORD, boost::shared_ptr<CEdit2>> m_mapEdits; m_mapEdits[textBox_IPUseID].reset( new CEdit2() ); m_mapEdits[textBox_IPUseID]->SubclassWindow( GetDlgItem(textBox_IPUseID) );
4.ATL控件IVSFlexGridPtr
IVSFlexGridPtr m_spGrid; CAxWindow wndGrid = GetDlgItem(Grid_EigyoJikan); wndGrid.QueryControl(&m_spGrid); // http://helpcentral.componentone.com/docs/vsflexgrid8/vsflexgridpropertieseventsandmethods.htm