MFC补充第十四天 句柄嫁接与子类化

这篇具有很好参考价值的文章主要介绍了MFC补充第十四天 句柄嫁接与子类化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

句柄嫁接与子类化

句柄嫁接与子类化:
a)Attach和Detach就是单纯的嫁接与分离函数。
对象一旦嫁接入一个句柄,就可以自由地调用CWnd或其派生类的功能。
b)子类化Subclass内部包含Attach,额外再增加一个消息转拨到派生类(SubClass就是子类)
c)SubClassWindow函数内部核心功能就是Attach和::SetWindowLong
d)SubClassWindow必须与UnsubclassWindow()成对使用,如同Attach与Detach那样。
e)SubClassDlgItem是把2个函数合成一个函数:m_eye.SubclassDlgItem(IDC_SHOW, this);
m_eye.SubclassWindow(::GetDlgItem(m_hWnd, IDC_SHOW));
f)而且SubClassDlgItem不需要反子类化,可以不用调用UnsubclassWindow

示例代码

BOOL CLoginDlg::OnInitDialog(){
//m_eye.Attach(::GetDlgItem(m_hWnd, IDC_SHOW)); //attach让你自由的调用CWnd类的成员
//m_eye.SubclassWindow(::GetDlgItem(m_hWnd, IDC_SHOW));//子类化 消息不穿透里面包含attach 和消息转拨
	m_eye.m_pDlg = this;	
	m_eye.SubclassDlgItem(IDC_SHOW, this); //升级版  不需要成对使用		句柄和父窗口
	CDialogEx::OnInitDialog();
	auto hIcon = theApp.LoadIcon(IDI_LOGIN);
	SetIcon(hIcon,false);
	return TRUE;  // return TRUE unless you set the focus to a control 
}
void CLoginDlg::OnDestroy(){
	CDialogEx::OnDestroy();
	m_eye.UnsubclassWindow();	 
}

SubclassWindow源码

BOOL CWnd::SubclassWindow(HWND hWnd)
{
	if (!Attach(hWnd))
		return FALSE;

	// allow any other subclassing to occur
	PreSubclassWindow();

	// now hook into the AFX WndProc
	WNDPROC* lplpfn = GetSuperWndProcAddr();
	WNDPROC oldWndProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC,
		(INT_PTR)AfxGetAfxWndProc());
	ASSERT(oldWndProc != AfxGetAfxWndProc());

	if (*lplpfn == NULL)
		*lplpfn = oldWndProc;   // the first control of that type created
#ifdef _DEBUG
	else if (*lplpfn != oldWndProc)
	{
		TRACE(traceAppMsg, 0, "Error: Trying to use SubclassWindow with incorrect CWnd\n");
		TRACE(traceAppMsg, 0, "\tderived class.\n");
		TRACE(traceAppMsg, 0, "\thWnd = $%08X (nIDC=$%08X) is not a %hs.\n", (UINT)(UINT_PTR)hWnd,
			_AfxGetDlgCtrlID(hWnd), GetRuntimeClass()->m_lpszClassName);
		ASSERT(FALSE);
		// undo the subclassing if continuing after assert
	  ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (INT_PTR)oldWndProc);
	}
#endif

	return TRUE;
}


总结嫁接与子类化:

a)Attach和Detach就是单纯的嫁接
b)子类化Subclass内部包含Attach,增强了消息转移机制。
c)SubClassDlgItem简化了子类化功能,不需要反子类化UnsubclassWindow
d)类向导中建立关联变量的方法(内部就是子类化)文章来源地址https://www.toymoban.com/news/detail-566677.html

DDX_Control函数内的核心内容是,引用类成员变量m_xxx,
{
pDX->m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
rControl.SubclassWindow(hWndCtrl))

}
void CXxxxxx::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST, m_list);
	DDX_Control(pDX, IDC_PRIOR, m_combo);
}

DDX_CONTROL源码

void AFXAPI DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl)
{
	if ((rControl.m_hWnd == NULL) && (rControl.GetControlUnknown() == NULL))    // not subclassed yet
	{
		ASSERT(!pDX->m_bSaveAndValidate);

		pDX->PrepareCtrl(nIDC);
		HWND hWndCtrl;
		pDX->m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);

#if defined(_AFXDLL) || !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS)
		CMFCControlContainer* pMFCCtrlContainer = pDX->m_pDlgWnd->GetMFCControlContainer();
		if (pMFCCtrlContainer != NULL && pMFCCtrlContainer->IsSubclassedFeaturePackControl(hWndCtrl))
		{
			pMFCCtrlContainer->ReSubclassControl(hWndCtrl, (WORD)nIDC, rControl);
			return;
		}
#endif

		if ((hWndCtrl != NULL) && !rControl.SubclassWindow(hWndCtrl))
		{
			ASSERT(FALSE);      // possibly trying to subclass twice?
			AfxThrowNotSupportedException();
		}
		else
		{
			if (hWndCtrl == NULL)
			{
				if (pDX->m_pDlgWnd->GetOleControlSite(nIDC) != NULL)
				{
					rControl.AttachControlSite(pDX->m_pDlgWnd, nIDC);
				}
			}
			else
			{
				// If the control has reparented itself (e.g., invisible control),
				// make sure that the CWnd gets properly wired to its control site.
				if (pDX->m_pDlgWnd->m_hWnd != ::GetParent(rControl.m_hWnd))
					rControl.AttachControlSite(pDX->m_pDlgWnd);
			}
		}
	}
}

到了这里,关于MFC补充第十四天 句柄嫁接与子类化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 学习Android的第十四天

    目录 Android DatePicker 日期选择器 DatePicker 属性 和 事件 DatePicker 事件 获得 DatePicker 的值 Android TimePicker 时间选择器 TimePicker 属性 TimePicker 事件 获得 TimePicker 的值 Android CalendarView 日历视图 CalendarView 属性 CalendarView 事件 获得 CalendarView 的值 在Android中,DatePicker是一个用户界面组件

    2024年02月21日
    浏览(48)
  • 【力扣刷题 | 第二十四天】

    目录 前言: 1049. 最后一块石头的重量 II - 力扣(LeetCode) 494. 目标和 - 力扣(LeetCode) 总结:                  今天我们依然暴打动态规划 有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合,从中选出任意两块石头,然后将它们一起粉

    2024年02月14日
    浏览(37)
  • 算法练习第六十四天

    LCR 184. 设计自助结算系统 - 力扣(LeetCode) 总结:利用一个双端维护队列一个往后递减的队列,对头是最大值,每次进入一个新值时就一直和队尾元素比较将比新的值小的数排出,这样能保证留在队列中的数都是会对最大值产生影响的数,而当主队列中将要排出的数与双端队

    2024年02月07日
    浏览(56)
  • 学习c#的第二十四天

    目录 C# 事件(Event) 事件概述 如何订阅和取消订阅事件 以编程方式订阅事件 使用匿名函数订阅事件 取消订阅 如何发布符合 .NET 准则的事件 发布基于 EventHandler 模式的事件 如何在派生类中引发基类事件 如何实现接口事件 如何实现自定义事件访问器 示例 事件(Event) 基本

    2024年02月04日
    浏览(38)
  • 十四天学会C++之第五天:类的详细讨论

    什么是友元函数和友元类,它们的作用。 如何声明和使用友元函数和友元类,访问类的私有成员。 友元函数(Friend Functions) 友元函数是一种特殊的函数,它被允许访问类的私有成员。这意味着即使成员是私有的,友元函数也能够直接访问它们,而不需要通过公有接口。这提

    2024年02月07日
    浏览(43)
  • 十四天学会C++之第一天(入门和基本语法)

    C++诞生于20世纪80年代初,它的创造者是计算机科学家Bjarne Stroustrup。当时,Stroustrup在贝尔实验室工作,他希望为C语言添加一些功能,以便更好地支持系统开发。这个愿望促使他创建了C++。 C++的名字来源于它的基因,其中的\\\"C\\\"代表了C语言,而\\\"++\\\"表示C语言的一个增强版本。这

    2024年02月07日
    浏览(49)
  • 蓝桥杯十四天冲刺班 第十四天《考场经验 | 历年考点 | 蓝桥杯押题》《C,JAVA,PY在蓝桥杯中必须要会用的容器 | 集合》(3K+字解析)

     📒博客首页:Sonesang的博客 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 ❤️ :热爱Java与算法学习,期待一起交流! 🙏作者水平很有限,如果发现错误,求告知,多谢! 🌺有问题可私信交流!!!   目录 算法 实力 = 知识点+刷题量+速度+灵活的大脑 C++组知识点 java组知识点

    2023年04月15日
    浏览(42)
  • Python学习笔记第六十四天(Matplotlib 网格线)

    我们可以使用 pyplot 中的 grid() 方法来设置图表中的网格线。 grid() 方法语法格式如下: 参数说明: b:可选,默认为 None,可以设置布尔值,true 为显示网格线,false 为不显示,如果设置 **kwargs 参数,则值为 true。 which:可选,可选值有 ‘major’、‘minor’ 和 ‘both’,默认为

    2024年02月12日
    浏览(43)
  • 从零开始的力扣刷题记录-第四十四天

    题目描述: 和谐数组是指一个数组里元素的最大值和最小值之间的差别 正好是 1 。 现在,给你一个整数数组 nums ,请你在所有可能的子序列中找到最长的和谐子序列的长度。 数组的子序列是一个由数组派生出来的序列,它可以通过删除一些元素或不删除元素、且不改变其余

    2024年02月07日
    浏览(52)
  • 从零开始的力扣刷题记录-第六十四天

    题目描述: 给你一个下标从 0 开始的整数数组 nums 。在一步操作中,你可以执行以下步骤: 从 nums 选出 两个 相等的 整数 从 nums 中移除这两个整数,形成一个 数对 请你在 nums 上多次执行此操作直到无法继续执行。 返回一个下标从 0 开始、长度为 2 的整数数组 answer 作为答

    2024年02月11日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包