DuiLib's message passing mechanism

foreword

I learned how to write XML files, but I still don't know how to implement message passing between controls. So I studied the source code carefully, and found that duilib, as an interface library, has its own independent packaged window class, that is, WindowsImplBase .

In this class, the processing of the message from the windows window is realized , as well as the functions of creating controls and drawing windows during initialization . By inheriting this window class, we can parse our own XML file and display the window designed by ourselves.

//.h头文件
virtual CControlUI* CreateControl(LPCTSTR pstrClass); //创建XML文件中的控件,如果自绘控件的话,需要重载这个函数,否则无法加载XML文件中的自绘控件
virtual CDuiString GetSkinFolder();  //设置XML文件的路径
virtual CDuiString GetSkinFile() = 0;//获取XML文件的名字

After the window class parses the XML file, the window can be displayed. We also need to overload the message processing function in the INotifyUI class to process the messages obtained by our window.

void Notify(TNotifyUI& msg)//消息处理函数;

In this function, msg is a structure, and novice students can go to see the definition. The msg.pSender pointer is the control pointer to obtain the message. Call the GetType() function to obtain the type of the message, whether it is a click or a right button, etc., and then call the GetName function to correspond to the control and do corresponding processing.
insert image description here

typedef struct tagTNotifyUI 
{
    
    
	CDuiString sType;
	CDuiString sVirtualWnd;
	CControlUI* pSender;
	DWORD dwTimestamp;
	POINT ptMouse;
	WPARAM wParam;
	LPARAM lParam;
} TNotifyUI;

There is a very useful point here, if you click this control, what should you do if you want to operate another control?
I also wondered for a long time here, maybe because I am a rookie. After looking at other people's codes, I summed up a method by myself. I don't know if there is a better one.

Each control has an object that manages the control ( m_PaintManager ). Through this object to manage the corresponding control, we can also find any control in the window. It provides a variety of search methods, commonly used as follows.

insert image description here

 CControlUI* FindSubControlByPoint(CControlUI* pParent, POINT pt) const;  
 CControlUI* FindSubControlByName(CControlUI* pParent, LPCTSTR pstrName) const;  
 CControlUI* FindSubControlByClass(CControlUI* pParent, LPCTSTR pstrClass, int iIndex = 0);  

Using these three functions can basically meet all our needs. There are those that are searched by coordinates, those that use names, and those that use control properties. The first parameter in the function is the parent control of the control to be found, or it can be a higher-level parent control. When using the third function, it should be noted that its way of traversing sub-controls is depth-first traversal. If you need to use iIndex (referring to the number of similar controls), you must consider all similar controls contained in the front, and the label starts from 0.

In this way, we can use msg.pSender->GetParent() to obtain the parent class (can be called repeatedly), GetManager() to use the search method, and then use the method of searching for child controls to obtain the pointer of the control to be processed, OK.

Another point is that the returned pointers are all of CControlUI type, and many functions for setting parameters cannot be used. Because all controls in duilib use CControlUI as the parent class, it can be converted to its original control type by using mandatory conversion, and it is very convenient to operate on it.

Guess you like

Origin blog.csdn.net/qq_44918090/article/details/131723315