Sometimes you will encounter a control that wants the function of multiple controls. At this time, you need to encapsulate the control yourself. Or when there are multiple same controls combined in one or more interfaces, these controls can also be encapsulated together.
1. Goal achievement effect
2. Realization
1, XML placement
<?xml version="1.0" encoding="UTF-8"?> <Window size="367,290"> <HorizontalLayout bkimage="skin/card_normal.png" selectedimage="skin/card_selected.png"> <Button name="btnPatSelected" width="367" height="290" bkimage="skin/card_man_normal.png" hotimage="skin/card_man_selected.png"></Button> <Label name="PatIcon" text="" float="true" pos="21,21,0,0" width="124" height="124" ></Label> <Label name="" text="姓名" float="true" font="4" pos="171,54,0,0" width="55" height="22" align="center" ></Label> <Label name="" text="年龄" float="true" font="4" pos="230,54,0,0" width="55" height="22" align="center" ></Label> <Label name="" text="性别" float="true" font="4" pos="292,54,0,0" width="55" height="22" align="center" ></Label> <Label name="PatName" text="罗文" float="true" font="4" pos="171,90,0,0" width="55" height="22" align="center" ></Label> <Label name="PatAge" text="22" float="true" font="4" pos="230,90,0,0" width="55" height="22" align="center" ></Label> <Label name="PatSex" text="男" float="true" font="4" pos="292,90,0,0" width="55" height="22" align="center" ></Label> <Label align="left" name="PatBornDate" text="2018-04-01" font="4" float="true" pos="250,175,0,0" width="120" height="17" ></Label> <Label align="left" name="PatTel" text="18627293017" font="4" float="true" pos="250,212,0,0" width="120" height="17" ></Label> <Label align="left" name="PatCreateDate" text="2018-04-14" font="4" float="true" pos="250,248,0,0" width="120" height="17" ></Label> <Label name="" text="ID" font="4" float="true" pos="21,190,0,0" width="124" height="24" align="center" ></Label> <Label name="PatID" font="4" text="212121" float="true" pos="21,228,0,0" width="124" height="34" align="center" ></Label> <Label name="" text="出生日期:" font="2" float="true" pos="175,175,0,0" width="70" height="17" ></Label> <Label name="" text="联系电话:" font="2" float="true" pos="175,212,0,0" width="70" height="17" ></Label> <Label name="" text="创建时间:" font="2" float="true" pos="175,248,0,0" width="70" height="17" ></Label> </HorizontalLayout> </Window>
C++ code
CPatInfoCardUI.h file
#ifndef _CPATINFO_CARD_UI_H__ #define _CPATINFO_CARD_UI_H__ namespace DuiLib { typedef struct DuiPatinfo //Define the structure to save the patient information that needs to be set (which needs to be displayed on the card) { DuiPatinfo() { ZeroMemory(this, sizeof(DUIPATINFO)); } CDuiString strPatID; //Patient ID CDuiString strPatName;//Patient name CDuiString strPatSex;//Patient gender CDuiString strBornDate;//Birthdate CDuiString strPatTel;//Phone number CDuiString strCreateDate;//Creation time CDuiString strPatAge;//patient age } DUIPATINFO, *PDUIPATINFO; class CPatinfoCardUI : public CContainerUI, INotifyUI { public: CPatinfoCardUI (); ~ CPatinfoCardUI (); private: LPCTSTR GetClass() const; LPVOID GetInterface(LPCTSTR pstrName); UINT GetControlFlags() const; void DoInit(); void Notify(TNotifyUI& msg); //Override setting properties virtual void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue); void SetHotImage(LPCTSTR pstrValue);//It's useless for now void SetNormalImage(LPCTSTR pstrValue);//It's useless for now void SetSelectedImage(LPCTSTR pstrValue);//It's useless for now void PaintStatusImage(HDC hDC);//It's useless for now //set patient parameters void SetPatInfo(DUIPATINFO &duipatinfo); private: UINT m_bButtonState; //selected state CLabelUI* m_pPatName; //Patient name display CLabelUI* m_pPatAge; //patient age CLabelUI* m_pPatSex; //patient gender CLabelUI* m_pPatBornDate; // patient's date of birth CLabelUI* m_pPatTel; //Create time display CLabelUI* m_pPatCreateDate; //Create time display CLabelUI* m_pPatID; //Patient ID display position CButtonUI * m_pSelectBtn; //Background button (originally prepared custom attributes, use this to solve first, so that you don't need to write code) CDuiString m_sNormalImage;//Background image in normal state CDuiString m_sHotImage;//Background image in normal state CDuiString m_sSelectedImage;//Background image in normal state PDUIPATINFO m_PatInfo;//Save and display patient information parameters }; } #endif
CPatInfoCardUI.cpp
#include "stdafx.h" #include "CPatInfoCardUI.h" namespace DuiLib { CPatinfoCardUI :: CPatinfoCardUI () { } CPatinfoCardUI :: ~ CPatinfoCardUI () { } LPCTSTR CPatinfoCardUI::GetClass()const { return _T("CPatInfoCard"); } LPVOID CPatinfoCardUI::GetInterface(LPCTSTR pstrName) { if( _tcscmp(pstrName, _T("CPatInfoCard")) == 0 ) return static_cast<CPatinfoCardUI*>(this); return CContainerUI::GetInterface(pstrName); } UINT CPatinfoCardUI::GetControlFlags()const { return CContainerUI::GetControlFlags(); } void CPatinfoCardUI :: DoInit () { CDialogBuilder builder; CContainerUI* pChildWindow = static_cast<CHorizontalLayoutUI*>(builder.Create(_T("ControlCard.xml"), (UINT)0, NULL, m_pManager)); if (pChildWindow) { this->Add(pChildWindow); //m_pManager->AddNotifier(this); //Maybe it's because of another person I referenced; he used class CMainWnd : public CWindowWnd, p //public INotifyUI, public IDialogBuilderCallback; if the main window is loaded in this way, it will not distribute messages // crash; I am using windowimpbase, so this line of code cannot be added here; otherwise it crashes } else { this->RemoveAll(); } m_pPatName = static_cast<CLabelUI*>(m_pManager->FindControl(_T("PatName"))); m_pPatAge = static_cast<CLabelUI*>(m_pManager->FindControl(_T("PatAge"))); m_pPatBornDate = static_cast<CLabelUI*>(m_pManager->FindControl(_T("PatBornDate"))); m_pPatSex = static_cast<CLabelUI*>(m_pManager->FindControl(_T("PatSex"))); m_pPatID = static_cast<CLabelUI*>(m_pManager->FindControl(_T("PatID"))); m_pPatCreateDate = static_cast<CLabelUI*>(m_pManager->FindControl(_T("PatCreateDate"))); m_pPatTel = static_cast<CLabelUI*>(m_pManager->FindControl(_T("PatTel"))); m_pSelectBtn = static_cast<CButtonUI*>(m_pManager->FindControl(_T("btnPatSelected"))); } void CPatinfoCardUI::Notify(TNotifyUI& msg) { if (msg.sType == DUI_MSGTYPE_SELECTCHANGED) { if (msg.pSender == m_pSelectBtn) { m_pSelectBtn->Selected(true); } } } } void CPatinfoCardUI::SetHotImage(LPCTSTR pstrValue) { m_sHotImage = pstrValue; } void CPatinfoCardUI::SetNormalImage(LPCTSTR pstrValue) { m_sNormalImage = pstrValue; } void CPatinfoCardUI::SetSelectedImage(LPCTSTR pstrValue) { m_sSelectedImage = pstrValue; } void CPatinfoCardUI::PaintStatusImage(HDC hDC) { } void CPatinfoCardUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) { if( _tcscmp(pstrName, _T("normalimage")) == 0 ) { // if (m_PatInfo->strPatSex == _T("男")) // { // m_pSelectBtn->SetHotImage(pstrValue); // } // else // { // m_pSelectBtn->SetHotImage(pstrValue); // } } else if (_tcscmp(pstrName, _T("hotimage")) == 0 ) { } else if (_tcscmp(pstrName, _T("selectedimage")) == 0) { //m_pSelectBtn->SetPushedImage(pstrValue); //SetSelectedImage(pstrValue); } else { CContainerUI::SetAttribute(pstrName, pstrValue); } } void CPatinfoCardUI::SetPatInfo(DUIPATINFO &duipatinfo) { m_pPatName->SetText(duipatinfo.strPatName); m_pPatSex->SetText(duipatinfo.strPatSex); if (m_PatInfo->strPatSex == _T("女")) { m_pSelectBtn->SetBkImage(_T("skin/card_man_normal.png")); m_pSelectBtn->SetHotImage(_T("skin/card_man_selected.png")); } else { m_pSelectBtn->SetBkImage(_T("skin/card_woman_normal.png")); m_pSelectBtn->SetHotImage(_T("skin/card_woman_selected.png")); } m_pPatTel->SetText(duipatinfo.strPatTel); m_pPatID->SetText(duipatinfo.strPatID); m_pPatCreateDate->SetText(duipatinfo.strCreateDate); m_pPatBornDate->SetText(duipatinfo.strBornDate); m_pPatAge->SetText(duipatinfo.strPatAge); }
main window code
CControlUI * CEtcdMainWnd::CreateControl(LPCTSTR pstrClass) { CControlUI* pControl = NULL;//= new CControl; if (_tcsicmp(pstrClass, _T("ControlCard")) == 0) { pControl = new CPatinfoCardUI(); } return pControl; }
Main window xml configuration
<?xml version="1.0" encoding="UTF-8"?> <HorizontalLayout size="1600,900" > <ControlCard width="380" height="300" bkimage="skin/card_normal.png" selectedimage="skin/card_selected.png"></ControlCard> </HorizontalLayout>
Since mine is an interface in the tablayout, I use HorizontalLayout instead of Window;
Effect picture:
The upper right corner is the control of the combination defined by yourself;
3. The core class content is the Doinit() function, the CreateControl() function, the base class CContainerUI, INotifyUI
In 2018, look at the source code and study the principle more! cheer for yourself!