一. 控件的最小实现
1.1 添加MFC类CMyCtrl
添加MFC类CMyCtrl, 继承CWnd.(用向导添加, 自己手动写代码都可以).
1.2 添加CMyCtrl::RegisterWindowClass函数
添加和实现CMyCtrl::RegisterWindowClass函数(函数名随便), 该函数在构造函数中调用即可.
1.3 添加CMyCtrl::Create函数
函数名随便, 参数如下
int CMyCtrl::Create(CWnd *pParentWnd, const RECT &rect, UINT nID, DWORD dwStyle);
1.4 其他
前面三步就可以完成一个基本的控件的搭建, 而一般自定义控件就是为了重绘, 鼠标操作之类的, 添加这些功能就是重载CWnd对应的虚函数, 添加相关的消息处理函数就可以了.
类代码如下
</pre><pre name="code" class="cpp">// MyCtrl.h#pragma once// CMyCtrl#define MYCTRL_NAME _T("MyCtrl")class CMyCtrl : public CWnd{ // 有这个才支持动态创建 DECLARE_DYNAMIC(CMyCtrl) CMyCtrl(); virtual ~CMyCtrl(); bool RegisterWindowClass();// 注册类函数 int Create(CWnd *pParentWnd, const RECT &rect, UINT nID, DWORD dwStyle);protected: DECLARE_MESSAGE_MAP()}; / MyCtrl.cpp//#include "stdafx.h"#include "MyCtrl.h"// CMyCtrl// 有这个才支持动态创建IMPLEMENT_DYNAMIC(CMyCtrl, CWnd) CMyCtrl::CMyCtrl(){} CMyCtrl::~CMyCtrl(){} BEGIN_MESSAGE_MAP(CMyCtrl, CWnd)END_MESSAGE_MAP() // CCtrl 消息处理程序// 注册类函数bool CMyCtrl::RegisterWindowClass(){ WNDCLASS wndcls; HINSTANCE hInst = AfxGetInstanceHandle(); if (!(::GetClassInfo(hInst, MYCTRL_NAME, &wndcls))) { memset(&wndcls, 0, sizeof(WNDCLASS)); wndcls.hInstance= hInst; wndcls.lpfnWndProc= ::DefWindowProc; wndcls.hCursor= NULL; //LoadCursor(NULL, IDC_ARROW); wndcls.hIcon= 0; wndcls.lpszMenuName= NULL; wndcls.hbrBackground= (HBRUSH) ::GetStockObject(WHITE_BRUSH); wndcls.style= CS_DBLCLKS; wndcls.cbClsExtra= 0; wndcls.cbWndExtra= 0; wndcls.lpszClassName = MYCTRL_NAME; if (!RegisterClass(&wndcls)) { return false; } } return true;} int CMyCtrl::Create(CWnd *pParentWnd, const RECT &rect, UINT nID, DWORD dwStyle){ RegisterWindowClass(); // 注册类(最好不要在构造函数上注册类, 容易犯错.) dwStyle |= WS_CLIPCHILDREN; int Result = CWnd::Create(MYCTRL_NAME, _T(""), dwStyle, rect, pParentWnd, nID); if (Result) ;// do something return Result;}
二. 使用
这里以对话框为例
2.1 使用Custom Control资源自动绑定
1. 把这个控件拖到对话框资源上(大小/位置自己调).
2. 右键控件, 调到属性界面, 修改如下:
其中
Class选项的内容要与MYCTRL_NAME相同(看CMyCtrl中MYCTRL_NAME的定义);
ID选项随便填, 不重复即可.
3. 绑定IDC_CUSTOM_CTRL与CMyCtrl对象.(手动添加/向导添加都可以, 你懂得)
// h文件声明CCtrl m_ctrl;// cpp文件中代码void CTestCtrlDlg::DoDataExchange(CDataExchange* pDX){ CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_CUSTOM_CTRL, m_ctrl); // 这里}
4. 可以运行了.
绑定Custom Control的方法使用上比较简单, 调用代码少.
2.2 使用Custom Control资源自动绑定
1. 和2.1步骤1一样.
2. 和2.1步骤2一样.
3. 不使用DDX_Control(pDX, IDC_CUSTOM_CTRL, m_ctrl); 而是在CDlg::OnInitDialog中使用m_ctrl3.SubclassDlgItem(IDC_CUSTOM_CTRL, this);
4. 可以运行了.
这样子也很简单.
2.3 手动创建
1. 手动创建
只要声明 CCtrl对象, 然后调用CCtrl::Create函数就可以了, 但是要注意的是Create函数的参数必须要正确.
2. Create函数的参数
看这里的代码:
<pre name="code" class="cpp">// h文件 CCtrl m_ctrl; // CDlg::OnInitDialog CRect rect; GetDlgItem(IDC_STATIC_CUSTOM)->GetWindowRect(rect); ScreenToClient(rect);GetDlgItem(IDC_STATIC_CUSTOM)->ShowWindow(SW_HIDE); // 这里最好隐藏一下, 否则会盖掉自定义控件 m_ctrl2.Create(this, rect,12345, WS_VISIBLE);
其中IDC_STATIC_CUSTOM 我的是Picture Control, 你也可以使用Static Text
3. 可以运行了
该方法更简单, 而且可以动态创建, 但是构造Create函数的参数比较复杂.
原文:https://blog.csdn.net/bagboy_taobao_com/article/details/43086119