MFCPropertyGridCtrl分析

来源:互联网 发布:nginx配置端口访问 编辑:程序博客网 时间:2024/06/01 10:09

MFCPropertyGridCtrl

是VC 2008 pack中的类,实现了如下功能:

(1)界面分面两栏:一栏为属性,一栏为值

如这个图

virtual BOOL Create(DWORD dwStyle,const RECT& rect,CWnd* pParentWnd,UINT nID );

Parameters

[in] rect

A bounding rectangle that specifies the size and position of the window, in client coordinates of pParentWnd.

[in] pParentWnd

Pointer to the parent window. Must not be NULL.

Remarks

To create a property grid control, first call CMFCPropertyGridCtrl::CMFCPropertyGridCtrl to construct a property grid object. Then call CMFCPropertyGridCtrl::Create.

void EnableHeaderCtrl(BOOL bEnable=TRUE,LPCTSTR 

lpszLeftColumn=_T("Property"),LPCTSTR lpszRightColumn=_T("Value") );

功能:是否显示表头。

bEnable=TRUE显示表头,如下图

bEnable=FALSE,不显示表头,如下图


显而易见,后两个参数指定了表头名。

void EnableDescriptionArea(BOOL bEnable=TRUE );

功能:是事启用描述区

如下图所示


参见例子

MFCFeaturePackSample/NewControls/Page5.cpp /BOOL CPage5::OnInitDialog()

可研究CMFCPropertyGridCtrl控件。理解vs2008后的MFC新界面系统。

主要CMFCPropertyGridCtrl 数据成员

m_ToolTip

CToolTipCtrl

Tooltip control

 

m_wndHeader

CMFCHeaderCtrl

Property list header control

如图fig-11

m_IPToolTip

CMFCPropertyGridToolTipCtrl

Inplace tooltip control

 

m_wndScrollVert

CScrollBar

Vertical scroll bar

 

m_cListDelimeter

TCHAR

Customized list delimeter character

 

m_rectList

CRect

Properies area

 

m_lstProps

 

List of top-level properties

 

m_pSel

CMFCPropertyGridProperty

Current selection

 

Custom colors

m_clrBackground

   

m_clrText

   

m_clrGroupBackground

   

m_clrGroupText

   

...........................

   

功能:disable,双击,disable

更改。

CMFCPropertyGridProperty由{name, value}组成。

界面绘制主要代码

OnPaint(){OnFillBackgroundOnDrawList}void CMFCPropertyGridCtrl::OnFillBackground(CDC* pDC, CRect rectClient){......//CBrush m_brBackground;用指定好的画刷绘制背景pDC->FillRect(rectClient, &m_brBackground);......}}void CMFCPropertyGridCtrl::OnDrawList(CDC* pDC){//画中间的分隔线pDC->MoveTo(nXCenter, m_rectList.top - 1);pDC->LineTo(nXCenter, m_rectList.bottom);//得到属性项的链表const CList<CMFCPropertyGridProperty*, CMFCPropertyGridProperty*>& lst = m_bAlphabeticMode ? m_lstTerminalProps : m_lstProps;for (POSITION pos = lst.GetHeadPosition(); pos != NULL;){CMFCPropertyGridProperty* pProp = lst.GetNext(pos);//画每个属性项if (!OnDrawProperty(pDC, pProp)){break;}}}BOOL CMFCPropertyGridCtrl::OnDrawProperty(CDC* pDC, CMFCPropertyGridProperty* pProp) const{if (!pProp->IsEnabled()){clrTextOld = pDC->SetTextColor(afxGlobalData.clrGrayedText);}CRect rectName = pProp->m_Rect;CRgn rgnClipName;CRect rectNameClip = rectName;rectNameClip.bottom = min(rectNameClip.bottom, m_rectList.bottom);rgnClipName.CreateRectRgnIndirect(&rectNameClip);pDC->SelectClipRgn(&rgnClipName);pProp->OnDrawName(pDC, rectName);CRect rectValue = pProp->m_Rect;rectValue.left = nXCenter + 1;CRgn rgnClipVal;CRect rectValClip = rectValue;rectValClip.bottom = min(rectValClip.bottom, m_rectList.bottom);rgnClipVal.CreateRectRgnIndirect(&rectValClip);pDC->SelectClipRgn(&rgnClipVal);pProp->OnDrawValue(pDC, rectValue);}void CMFCPropertyGridProperty::OnDrawName(CDC* pDC, CRect rect){int nTextHeight = pDC->DrawText(m_strName, rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_END_ELLIPSIS);//计算出文字是被截断m_bNameIsTruncated = pDC->GetTextExtent(m_strName).cx > rect.Width(); }void CMFCPropertyGridProperty::OnDrawValue(CDC* pDC, CRect rect){CString strVal = FormatProperty();pDC->DrawText(strVal, rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_END_ELLIPSIS);}COLORREF m_clrLine;                  // Color of the grid linesBOOL m_bAlphabeticMode;         // Use property list in alphabetic (non-"tree") mode没有皮肤这种概念。所有风格都靠代码画出来。CMFCPropertyGridCtrl 代码特点。拆分成多个函数。每个函数的代码行数都少,可读性强。The GetTextExtentPoint32 function computes the width and height of the specified string of text.///////////////////////////////////////////////主要事件响应代码///////////////////////////////////////////////左键单击void CMFCPropertyGridCtrl::OnLButtonDown(UINT nFlags, CPoint point){SetFocus();CRect rectClient;GetClientRect(rectClient);CMFCPropertyGridProperty::ClickArea clickArea;CMFCPropertyGridProperty* pHit = HitTest(point, &clickArea);   //与当前的属性项比较,不同则属性项变更BOOL bSelChanged = pHit != GetCurSel();SetCurSel(pHit);if (pHit == NULL){return;}switch (clickArea){case CMFCPropertyGridProperty::ClickExpandBox:pHit->Expand(!pHit->IsExpanded()); //展开/收起子项break;case CMFCPropertyGridProperty::ClickName:pHit->OnClickName(point);break;case CMFCPropertyGridProperty::ClickValue:if (pHit->m_bEnabled){if (EditItem(pHit, &point) && pHit->m_pWndInPlace != NULL){if (pHit->m_rectButton.PtInRect(point)){CString strPrevVal = pHit->FormatProperty();if (::GetCapture() == GetSafeHwnd()){ReleaseCapture();}pHit->OnClickButton(point);if (strPrevVal != pHit->FormatProperty()){OnPropertyChanged(pHit);}}else if (!bSelChanged || pHit->IsProcessFirstClick()){pHit->OnClickValue(WM_LBUTTONDOWN, point);}}}break;default:break;}}//输入鼠标点,判断鼠标点在哪个属性项的矩形边界内,进而测试出鼠标点下的属性项。CMFCPropertyGridProperty* CMFCPropertyGridCtrl::HitTest(CPoint pt, CMFCPropertyGridProperty::ClickArea* pnArea, BOOL bPropsOnly) const{for (POSITION pos = lst.GetHeadPosition(); pos != NULL;){CMFCPropertyGridProperty* pProp = lst.GetNext(pos);ASSERT_VALID(pProp);CMFCPropertyGridProperty* pHit = pProp->HitTest(pt, pnArea);if (pHit != NULL){return pHit;}}}void CMFCPropertyGridCtrl::SetCurSel(CMFCPropertyGridProperty* pProp, BOOL bRedraw){m_pSel = pProp;OnChangeSelection//是一个空的虚函数OnChangeSelection(m_pSel, pOldSelectedItem);if (pOldSelectedItem != NULL){  //CMFCPropertyGridProperty中的空的虚函数pOldSelectedItem->OnKillSelection(pProp);}

鼠标单击某项,编辑响应过程

void CMFCPropertyGridCtrl::OnLButtonDown(UINT nFlags, CPoint point){case CMFCPropertyGridProperty::ClickValue:if (pHit->m_bEnabled){if (EditItem(pHit, &point) && pHit->m_pWndInPlace != NULL)}BOOL CMFCPropertyGridCtrl::EditItem(CMFCPropertyGridProperty* pProp, LPPOINT lptClick){ASSERT_VALID(this);ASSERT_VALID(pProp);if (!EndEditItem()){return FALSE;}if (pProp->IsGroup() && !pProp->m_bIsValueList){return FALSE;}if (pProp->OnEdit(lptClick)){pProp->Redraw();SetCurSel(pProp);SetCapture();}return TRUE;}////////////////////////////////////////////////////////CMFCPropertyGridProperty{BOOL     m_bEnabled;//是否允许编辑CWnd*              m_pWndInPlace; // Pointer to InPlace editing windowCComboBox*         m_pWndCombo;   // Pointer to combboxCSpinButtonCtrl*   m_pWndSpin;    // Pointer to spin buttonCMFCPropertyGridCtrl*     m_pWndList;    // Pointer to the PropertyList windowCMFCPropertyGridProperty* m_pParent;     // Parent property (NULL for top-level properties)enum ClickArea{ClickExpandBox,ClickName,ClickValue,ClickDescription};};

禁止扩展

void Expand(BOOL bExpand = TRUE);m_bEnabledvoid CMFCPropertyGridCtrl::OnLButtonDown(UINT nFlags, CPoint point){switch (clickArea){case CMFCPropertyGridProperty::ClickExpandBox:pHit->Expand(!pHit->IsExpanded());break;..................................}

编辑完

virtual BOOL CMFCPropertyGridProperty::OnEndEdit();///////////////////////////////////双击////////////////////////////////////if (m_pSel->GetRect().PtInRect(point)){m_pSel->OnDblClk(point);}

出现编辑框

void CMFCPropertyGridCtrl::OnLButtonDown(UINT nFlags, CPoint point){if (EditItem(pHit, &point) && pHit->m_pWndInPlace != NULL)}BOOL CMFCPropertyGridCtrl::EditItem(CMFCPropertyGridProperty* pProp, LPPOINT lptClick){if (pProp->OnEdit(lptClick))}BOOL CMFCPropertyGridProperty::OnEdit(LPPOINT /*lptClick*/){m_pWndInPlace = CreateInPlaceEdit(rectEdit, bDefaultFormat);}

CMFCPropertyGridProperty子类

CCheckBoxProp

CPasswordProp

CSliderProp

CBoundedNumberPairProp

CBoundedNumberSubProp

CIconListProp

CComboBoxExProp

COwnerDrawDescrProp

CTwoButtonsProp

CCustomDlgProp


响应点击属性项Combox框中的下拉项事件

ON_CBN_SELENDOK(AFX_PROPLIST_ID_INPLACE, &CMFCPropertyGridCtrl::OnSelectCombo)void CMFCPropertyGridCtrl::OnSelectCombo(){..............ASSERT_VALID(m_pSel);m_pSel->OnSelectCombo();}void CMFCPropertyGridProperty::OnSelectCombo(){ASSERT_VALID(this);ASSERT_VALID(m_pWndCombo);ASSERT_VALID(m_pWndInPlace);int iSelIndex = m_pWndCombo->GetCurSel();if (iSelIndex >= 0){CString str;m_pWndCombo->GetLBText(iSelIndex, str);m_pWndInPlace->SetWindowText(str);OnUpdateValue();}}

CComboBox ClassA

Each message-map entry takes the following form:

ON_Notification( id, memberFxn )

where id specifies the child-window ID of the combo-box control sending the notification and memberFxn is the name of the parent member function you have written to handle the notification.

The parent's function prototype is as follows:

afx_msg void memberFxn( );

ON_CBN_SELENDOK   The user selects an item and then either presses the ENTER key or clicks the DOWN ARROW key to hide the list box of a combo box. This notification message is sent before the CBN_CLOSEUP message to indicate that the user's selection should be considered valid. The CBN_SELENDCANCEL or CBN_SELENDOK notification message is sent even if the CBN_CLOSEUP notification message is not sent (as in the case of a combo box with the CBS_SIMPLE style).


例子程序

截图




源码VS2008





原创粉丝点击