CMFCPropertyGridCtrl实现复选框

MFC的CMFCPropertyGridCtrl控件虽然可以把值设置成True和False,可惜的是它是以组合框来呈现的。可能某些场合中,我们更希望它可以像复选框一样。
在这里插入图片描述
通过子类化CMFCPropertyGridProperty完成
实现代码:

/*
MFCPropertyCheckBox.h
*/
#pragma once
#include "afxpropertygridctrl.h"
class CMFCPropertyCheckBox : public CMFCPropertyGridProperty
{
public:
	CMFCPropertyCheckBox(const CString& strGroupName, bool bIsChecked = FALSE, LPCTSTR lpszDescr = NULL);
	
	virtual void OnDrawValue(CDC* pDC, CRect rect);
	virtual BOOL OnEdit(LPPOINT lptClick);
};
/*
MFCPropertyCheckBox.cpp
*/
#include "stdafx.h"
#include "MFCPropertyCheckBox.h"

CMFCPropertyCheckBox::CMFCPropertyCheckBox(const CString& strName, bool bIsChecked, LPCTSTR lpszDescr) 
	: CMFCPropertyGridProperty(strName, COleVariant(), lpszDescr)
{
	m_varValue = _variant_t(bIsChecked);
	m_varValueOrig = _variant_t(bIsChecked);
}

void CMFCPropertyCheckBox::OnDrawValue(CDC * pDC, CRect rect)
{
	ASSERT_VALID(this);
	ASSERT_VALID(pDC);
	ASSERT_VALID(m_pWndList);
	if (m_varValue.vt == VT_BOOL)
	{
		rect.right = rect.left + (rect.bottom - rect.top) * 2;
		//画复选框,方法一(推荐)
		CMFCVisualManager::GetInstance()->OnDrawCheckBox(pDC, rect, m_varValue.boolVal, m_varValue.boolVal, m_bEnabled);
		//画复选框,方法二
		/*UINT uStyle = DFCS_BUTTONCHECK;
		if (m_varValue.boolVal)
			uStyle |= DFCS_CHECKED ;//| DFCS_PUSHED
		pDC->DrawFrameControl(rect, DFC_BUTTON, uStyle);*/
	}
}

BOOL CMFCPropertyCheckBox::OnEdit(LPPOINT lptClick)
{
	ASSERT_VALID(this);
	ASSERT_VALID(m_pWndList);
	if (m_varValue.vt == VT_BOOL)
	{
		if (m_varValue.boolVal)
			m_varValue.boolVal = VARIANT_FALSE;
		else
			m_varValue.boolVal = VARIANT_TRUE;
		Redraw();//重绘
		this->m_pWndList->OnPropertyChanged(this);//产生值变更事件
	}
	return FALSE;//返回TRUE会导致其他控件可能无法获得焦点
}

原理很简单,重写OnDrawValue()和OnEdit()即可。
那为什么要重写OnDrawValue()和OnEdit()呢?
OnDrawValue()看命名就知道,功能是画"Value"(左边列的单元格为"Name",右边列的单元格为"Value")。在CMFCPropertyGridProperty中,OnDrawValue()的主要作用是画文字,重写后的功能是画一个复选框,这里给出了两种画复选框的方法,推荐使用方法一,其实在CMFCPropertyGridCtrl控件中,组合框的下拉按钮、展开折叠按钮等都是用方法一的方式画出来的。两种方法都可以画一些GUI控件,感兴趣的可以自己琢磨。
当然了,也是有OnDrawName()的,可以自己实现"Name"单元格的自定义。

OnEdit()的主要作用是在每次点击"Value"时,为"Value"所在的单元格创建一个编辑框。复选框并不需要文本编辑,同时OnEdit()是每次点击都会被执行的,正好可以用它作为点击复选框的事件处理。
在OnEdit()中m_varValue用于保存选中状态,因此可以继续延用SetValue()来设置值,调整复选框。

SetValue(_variant_t(true));//设置选中
SetValue(_variant_t(false));//取消选中

OnPropertyChanged(this)用于发送一个AFX_WM_PROPERTY_CHANGED消息。

使用示例:

	CMFCPropertyGridProperty *pGroup = new CMFCPropertyGridProperty(_T("参数"));
	//构造函数的第二个参数为复选框的初始状态
	pGroup->AddSubItem(new CMFCPropertyCheckBox(_T("属性1"), TRUE, _T("说明")));
	pGroup->AddSubItem(new CMFCPropertyCheckBox(_T("属性2"), FALSE, _T("说明")));
	pGroup->AddSubItem(new CMFCPropertyCheckBox(_T("属性3"), FALSE, _T("说明")));
	pGroup->AddSubItem(new CMFCPropertyCheckBox(_T("属性4"), FALSE, _T("说明")));
	pGroup->AddSubItem(new CMFCPropertyCheckBox(_T("属性5"), FALSE, _T("说明")));
	pGroup->AddSubItem(new CMFCPropertyCheckBox(_T("属性6"), FALSE, _T("说明")));
	pGroup->AddSubItem(new CMFCPropertyCheckBox(_T("属性7"), TRUE, _T("说明")));
	pGroup->AddSubItem(new CMFCPropertyCheckBox(_T("属性8"), TRUE, _T("说明")));
	m_pgcCtrl.AddProperty(pGroup);
	m_pgcCtrl.ExpandAll();


...
ON_REGISTERED_MESSAGE(AFX_WM_PROPERTY_CHANGED, OnPgcChanged)

//AFX_WM_PROPERTY_CHANGED消息响应
LRESULT CXXXXDlg::OnPgcChanged(WPARAM wParam, LPARAM lParam)
{
	CMFCPropertyGridProperty* pPGP = (CMFCPropertyGridProperty*)lParam;
	COleVariant b = pPGP->GetValue();
	if (b.vt == VT_BOOL)
	{
		if (b.boolVal == VARIANT_TRUE)
		{//选中
		}
		else
		{//取消选中
		}
		return 1;
	}
	return 0;
}
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值