Custom Control 控件的使用

本文深入探讨了如何在Windows应用程序中使用CustomControl类,包括注册自定义类、映射自定义消息以及如何与父窗口交互。通过示例代码,详细解释了如何在对话框中实现CustomControl,并利用自定义类与主程序进行通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、注册Custom Control类

要使用Custom Control,必须把Custom Control的Class属性设置为一个窗口类,这个窗口类可以VC的类,例如:Button、Edit。
在窗体上拉个Custom Control,设置ID为IDC_EDIT,Class为Edit。在头文件增加一个CEdit类的成员变量:CEdit m_Text;
然后在OnInitDialog()中使用SubclassDlgItem把IDC_EDIT和对话框连接起来:
m_Text.SubclassDlgItem(IDC_EDIT,this);  //从对话框模板创建动态子类控件,然后附加到CWnd对象
m_Text.SetWindowText("Custom Control例子");  //在其父类中可以直接操作了!

也可以把Custom Control设置为一个自定义类。
使用RegisterClass注册自定义类,然后设置Custom Control的Class属性为该类就行了,参考注册自定义类的代码:
BOOL CMyCtrl::RegisterWndClass(HINSTANCE hInstance)
{
WNDCLASS wc;
wc.lpszClassName = "CMyCtrl"; // 自定义类名
wc.hInstance = hInstance;
wc.lpfnWndProc = ::DefWindowProc;
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wc.hIcon = 0;
wc.lpszMenuName = NULL;
wc.hbrBackground = (HBRUSH) ::GetStockObject(LTGRAY_BRUSH);
wc.style = CS_GLOBALCLASS;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;

// 注册自定义类
return (::RegisterClass(&wc) != 0);
}

二、映射自定义消息

这里只介绍Custom Control向父窗口发送WM_NOTIFY消息,然后映射到操作函数。
在自定义操作类里增加一个Login()成员函数,当主程序调用这个成员函数后,会触发LoginEvent事件。
Login()的实现代码:
BOOL CMyCtrl::Login()
{
AfxMessageBox("主程序调用Login,将触发LoginEvent事件!");

NMHDR nm;
// 设置消息代码
nm.code = 12345;
nm.hwndFrom =m_hWnd;
nm.idFrom = GetDlgCtrlID();

// 发父窗口发送WM_NOTIFY消息
CWnd* pParent = GetParent();
pParent->SendMessage(WM_NOTIFY,nm.idFrom, (LPARAM)&nm);

return true;
}

在主窗体的头文件里声明消息响应函数:
afx_msg void LoginEvent;
在BEGIN_MESSAGE_MAP里加上:
ON_NOTIFY(12345, IDC_CUSTOM1, LoginEvent)
12345:消息代码;
IDC_CUSTOM1:控件的ID
LoginEvent:映射的函数。

然后再实现LoginEvent()的代码:
void CMainDlg::LoginEvent()
{
AfxMessageBox("触发LoginEvent事件!");
}
也可以在主窗体的OnNotify里处理WM_NOTIFY消息。

 

 第二种自定义类的方法:

VC里的Custom Control的使用很简单,用鼠标拖动到窗体上,然后设置其“Class”属性为已注册的窗口类,比哪Edit、Button等等。因为像Edit、Button等控件可以很容易的画到窗体上,而对继承于CWnd的自定义窗口类则没有办法直接用鼠标画到窗体上,这时Custom Control就用上了,只要类是使用RegisterClass注册后就能被使用,如:

view plaincopy to clipboardprint?
WNDCLASS wc;
wc.lpszClassName = _T("MyWindow"); // matches class name in client
wc.hInstance = hInstance;
wc.lpfnWndProc = ::DefWindowProc;
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wc.hIcon = 0;
wc.lpszMenuName = NULL;
wc.hbrBackground = (HBRUSH) ::GetStockObject(LTGRAY_BRUSH);
wc.style = CS_GLOBALCLASS; // To be modified
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;

::RegisterClass(&wc) != 0
WNDCLASS wc;
wc.lpszClassName = _T("MyWindow"); // matches class name in client
wc.hInstance = hInstance;
wc.lpfnWndProc = ::DefWindowProc;
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wc.hIcon = 0;
wc.lpszMenuName = NULL;
wc.hbrBackground = (HBRUSH) ::GetStockObject(LTGRAY_BRUSH);
wc.style = CS_GLOBALCLASS; // To be modified
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;

::RegisterClass(&wc) != 0

这时保存在CustomControl的Class属性上输入MyWindow后,程序运行正常。

其实我们可以不用这么“麻烦”的来使用自定义类。只一个SubclassWindow就搞定了。使用方法:

1:定义我们需要类,比如从CWnd继承一个新的类MyWindow、并编写自己的代码实现。

2:在窗体上放任何一个控件(目的是使用这个控件的大小及位置),比如可以放一个Static在窗体上。为控件添加一个变量,变量类型为MyWindow,然后在代码的合适的地方(比如OnInitDialog)添加如下的代码就可以了:

view plaincopy to clipboardprint?
this->m_MyWindow.SubclassWindow(this->GetDlgItem(IDC_Static)->GetSafeHwnd()); //子类窗口句柄通过参数传递,将其与CContainedWindowT对象联系起来
this->m_MyWindow.SubclassWindow(this->GetDlgItem(IDC_Static)->GetSafeHwnd());

直接运行程序,绝不会出现CustomControl那种运行不起来的现象。

Notice:

Do not call SubclassWindow if you have already called Create.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值