VC实现自定义控件步骤
一. 控件的最小實現
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?
?
總結
以上是生活随笔為你收集整理的VC实现自定义控件步骤的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转]移动视频监控(1)---项目综述
- 下一篇: [翻译]VC++中创建并使用自定义控件