1. widgetbase and its function 1. struct definition struct widgetbase {const aeevtbl (iwidget) * PVT; int nrefs; imodule * pimodule; wextent extent; icontainer * picontainer; imodel * pimodel; handlerdesc HD; pfnhandler pfndefhandler; // view model imodel * piviewmodel;}; 2. Description of each field
Field name |
Description |
Pvt |
Pointer to the virtual function table |
Nrefs |
Reference count |
Pimodule |
Pointer to the module |
Extent |
Widget size, width, and height |
Picontainer |
Pointer of the container to which the widget belongs |
Pimodel |
Widgets are made based on the MVC model. The pointer of the Model |
HD |
This processing function is called when an event occurs on the widget. |
Pfndefhandler |
Default event processing function |
Piviewmodel |
|
3. This struct defines the data members common to all widgets. Of course, public functions, such as widgetbase_xxx, are also provided. The struct is used as the first member in the implementation class of the widget. 2. containerbase and its function 1. The Container briefly describes the container of the widget, and the container can be considered as a special widget. Here is a composite mode. 2. Information about all widgets in the widgetnodecontainer is stored in a two-way linked list. The linked list nodes are defined as follows: struct widgetnode {widgetnode * pnext; widgetnode * pprev; iwidget * piwidget; aeerect RC; // If non-null, then this widget is raised ixycontainer * pixyraise; // XY container that widget is raised to # If defined (optimiz3) aeerect rcdraw; # endif flg fvisible: 1; flg fdraw: 1 ;}; pnext and pprev constitute a two-way linked list; piwidget is a pointer to a widget in the container; RC represents the position and size of the widget. Operations on containers, such as adding widgets, deleting widgets, searching for widgets, and traversing all widgets, are mapped to operations on the linked list. 3. struct definition: struct containerbase {aeevtbl (icontainer) * PVT; uint32 nrefs; imodule * pimodule; imodel * pimodel; wextent extent; icontainer * piparent; iwidget; aeevtbl (iwidget) vtwidget; Border border; imodel * piviewmodel; handlerdesc HD; pfnhandler pfndefhandler; widgetnode head ;...}; 4. Field description
Field |
Description |
Pvt |
Virtual function table pointing to icontainer |
From nrefs to piparent, and HR and pfndefhandler |
The meaning of widgetbase is exactly the same as that of widgetbase, because we need to regard the iner as a common widget. |
Widget |
Iwidgetvtbl * PVT; pointing to the next field vtwidget of the struct; this is a virtual function table, which can be considered as a common widget. When icontainer_queryinterface (iwidget) is called, the address of the pointer is returned. Containerbase * PME; is actually the this pointer |
Vtwidget |
The virtual function table of the widget, through which the container can be considered as a common widget. |
Head |
A linked list composed of Widgets |
The excerpt code is as follows: int containerbase_queryinterface (icontainer * Po, aeeclsid ID, void ** PPO) {If (ID = aeeiid_widget) | (ID = aeeiid_handler )) {* PPO = & Me-> widget; icontainer_addref (PO); Return success ;}} when the customer calls the iwidget interface method through this pointer, (* (iwidgetvtbl **) (void *) PTR)-> addref (); * PTR is the value of the field Pvt, that is, the pointer to the iwidgetvtbl struct. The preceding statement only adds forced type conversion. Here we can clearly understand that when icontainer is treated as a common widget, it has no relationship with the number of widgets in the container, nor is it any widget. NOTE 1: In fact, QueryInterface refers to the "is-a" relationship in object-oriented, that is, the inheritance relationship. In accordance with the principle of object-oriented, is-A is much stronger than has-a. If possible, we recommend that you use the get and set functions to express the relationship between has-. NOTE 2: in fact, common interface pointers, such as iwidget * And icontainer *, all point to Level 2 pointers of the virtual function table. Because it is a 2-level pointer, it adds quite flexibility (remember the famous saying that adds an indirect Layer ). 5. When the draw function displays the container, the container traverses all widgets and calls the iwidget_draw function to complete the display operation.
Widget1 container (wid2, wid3) widget3 |
Icontainer (0x11111111)
Iwidget (0x22222222) 3. decorator implementation method 1. decorator is a special container that manages and manages only one widget. It adds more UI functions 2 to the widget, struct widgetcontbase {widgetbase base; icontainer container; aeevtbl (icontainer) vtcontainer ;}; struct decorator {widgetcontbase base; iwidget * pchild;}; 3, Structure Description
Field |
Description |
Base |
This component is a common widget. |
Container |
Icontainervtbl * PVT; pointing to the next field vtcontainer of the struct; through this virtual function table, the decorator can be considered as a iner. When idecorator_queryinterface (icontainer) is called, the address of the pointer is returned. Widgetcontbase * PME; it is actually the this pointer |
Vtcontainer |
The virtual function table of the container. Through this table, a widget (decorator) can be considered as a container. |
Pchild |
Target widget that is decorated. |
The extracted code is as follows: int widgetcontbase_queryinterface (iwidget * Po, aeeclsid CLSID, void ** PPO) {widgetcontbase * Me = (widgetcontbase *) po; If (CLSID = aeeiid_container) {* PPO = (void *) & Me-> container; widgetbase_addref (iwidget *) po); Return success;} return widgetbase_queryinterface (PO, CLSID, PPO );} it can be seen that icontainer is a container, but it can be viewed as a widget. Idecorator itself is a widget, but it can be viewed as a iner. 4. If the idecorator has wrap target widget, call icontainer_getwidget to obtain the target widget. Irootcontainer_getfirstwidget returns the first widget to be added. Irootcontainer_getlastwidget returns the last added widget.