Open source Gui-microwindows procedure Entrance analysis

Source: Internet
Author: User

*************************************************************************************************************** ************
Easywave Time: 2014.10.05

Category: Open source GUI system-microwindows procedure entrance Analysis declaration: reprint, please keep the link

Note: If there is an error, please correct me. These are the journal articles I studied ...

*************************************************************************************************************** ************

One: Microwindows program entrance

< Span style= "FONT-SIZE:14PX; Line-height:26px ">         Here only the analysis is based on the WIN32 message mode section, for the Nano is not the analysis focus here, Believe that familiar with the Linux kernel, should all know that under Linux, whether it is the device, the driver, or the process, is the use of linked list of the various host data structure link, and in the Microwindows also adopted in the same way, we first to review the Linux two-way link list bar, In the Linux kernel, there are a large number of data structures that need to use a double-loop list, such as processes, files, modules, pages and so on. If we adopt the traditional implementation of the double-loop list, we need to maintain the linked list for these data structures, and design the operation functions of inserting and deleting for each list. Because the next and prev pointers used to maintain the list point to Objects of the corresponding type, a list manipulation function of a data structure cannot be used to manipulate the linked list of other data structures.    

In the include/linux/list.h file of the Linux source tree, a type-independent, doubly-looped list implementation is used. The idea is to extract pointers prev and next from detailed data structures to form a common "doubly linked list" data structure List_head. Given the need to construct a particular list of objects of a certain class, a member of type List_head type is defined in its structure (called the host data structure), through which the member connects such objects, forms the desired list, and operates on them through a generic list function. The advantage is that simply writing a generic list function allows you to construct and manipulate linked lists of different objects without having to write a dedicated function for each type of object, which enables code reuse. For example, the following definitions are seen:

struct List_head {

struct List_head *next, *prev;

};

The two-loop list implementations in the Linux kernel are as follows:

    • A variable of type list_head is embedded in the host data structure as a member;
    • The ability to place the linked list structure within the host structure wherever it is;
    • Be able to take whatever name for the linked list structure;
    • The host structure can have multiple linked list structures;
    • The linked list is traversed by the members in the List_head and the corresponding processing functions;
    • If you want a pointer to the host structure, use list_entry to figure it out.
How does Linux get the host data structure through List_head? Here is an attempt to analyze:  Suppose a queue of data structures is required, and a list_head data structure is placed inside such a data structure definition. For example, the way to create a data structure foo list is to embed a list of list_head members in the definition of Foo. This is referred to as the "host".
typedef struct DTEST {
...
struct List_head list;
...
};

However, how to access the host structure items through List_head members? After all, List_head is just a connecting piece, and what we need is a "specific" data structure linked list.
let's introduce some basic macros: Offsetof, typeof, Containerof

#define __COMPILER_OFFSETOF (A, B) __builtin_offsetof (A, b)
The __builtin_offsetof () macro is a function that has been designed in the compiler, and can be called directly.  
#undef offsetof//Cancel any previous definition, to ensure that the following definitions are in effect
#ifdef __compiler_offsetof
#define OFFSETOF (Type,member) __compiler_offsetof (Type,member)
#else
#define OFFSETOF (Type, MEMBER) ((size_t) & ((TYPE *) 0)->member)
#endif
The algorithm above is divided into the following steps:
    • ((TYPE *) 0) 0 address force "convert" to a pointer of TYPE structure;
    • ((TYPE *) 0)->member access to data members in the structure;
    • & ((TYPE *) 0)->member The address of the data member
    • (size_t) (& (((type*) 0)->member) The result conversion type.
The trick is to convert 0 to (type*), with the first address 0 of the memory space as the starting address, the member address is naturally an offset address, and here is a small technique that takes advantage of the compiler technique (the compiler itself actively calculates the offset of the member), That is, the structure member variable in the structure relative to the first address of the structure of the offset address, and then according to the structure of the first address is 0, so that the offset address is the structure of the variable in the structure of the offset, that is: The structure member variable distance from the structure of the first. In Offsetof (), the address of this member member is actually the offset of the member member relative to the struct variable in the type data structure. For a given structure, offsetof (type,member) is a constant, and list_entry () is using this constant offset to obtain the address of the variable of the linked list data item.
Ontainer_of-cast a member of a structure out to the containing structure.
Ptr:the pointer to the member.
Type:the type of the container struct this was embedded in.
Member:the name of the member within the struct.
#define CONTAINER_OF (PTR, type, member) ({\
Const typeof (((type *) 0)->member) *__mptr = (PTR); \
( type *) ((char *) __mptr-offsetof (Type,member));})

List_entry () macro that gets the host structure item that contains the current List_head linked list node. The first parameter is a pointer to the current List_head node, which is the List_head member that points to the host structure item. The second parameter is the definition type of the host data structure. The third parameter is the List_head member name in the host structure type definition.
#define List_entry (PTR, type, member) \
Container_of (PTR, type, member)

The extension substitution is:
#define List_entry (PTR, type, member) \
((Type *) ((char *) (PTR)-(unsigned Long) (& ((type *) 0)->member
)))

For example, we are going to visit the first element in the Dtest list (the head of the chain header), so call:
list_entry (head->next, struct dtest, list);
After the literal substitution of the C preprocessing, the content of this line becomes:
( struct Dtest *) ((char *) (Head->next)-(unsigned Long) (& ((struct dtest *) 0)->list )))
Consider the offset of the List_head type member member relative to the start address of the host structure (type). This offset is fixed for all host objects of that type. And can be obtained by returning the address of the member member if the host object address value is 0, which is equal to (unsigned long) (& ((type *) 0)->member). This subtracts the "connector" address (PTR) of the current host object from that offset, obtains the host object address, and then converts it to a pointer to the type of the host data structure. It is important to reiterate that the list header must be embedded in the host object.
and in the microwindows used also adopted in the same way the various wndclass link up, and through the Mwfindclassbyname (lpwndclass->lpszclassname); function to find the corresponding WNDCLASS has been registered, now to analyze the mircowindows of the initialization program bar, the source code is in the WINMAIN.C, such as the following see:

The mwopen (AC, AV) function in the 0064 row is the code that focuses on the analysis here, while the mwcreateinstance () function is the handle to the application, but it is relative to Rootwp, which is the desktop that everyone often says. and WinMain () is the application GUI that we need to implement, this is the place where we need to play, now here we analyze the Mwopen letter, for example, as seen below:
in the Mwopen function, by calling the Mwinitialize function, the details of the Mwinitialize function are as follows:


here the main analysis of this lineof code: Wp->pclass = (pwndclass) mwclasshead.head, and the definition of mwclasshead, such as the following see:

in other words, in the microwindows also used in Linux in the form of a linked list to achieve management, and Mwclasshead who is in use, the answer is registerclass (CONST wndclass *lpwndclass) Functions, such as those seen below:


The registerclass (CONST wndclass *lpwndclass) function will call Mwfindclassbyname (LPCSTR lpclassname), And in the Mwfindclassbyname (LPCSTR lpclassname) function will call GDITEMADDR, whether there is a sense of déjà vu, but we can parse such as the following:
(( wndclass*) ((long) mwclasshead.head-mwtem_offset (wndclass, link) )further parsing is for example the following:(( wndclass*) ((long) Mwclasshead.head-((Long) & ((((WNDCLASS *) 0)->link ))
in this way, it is possible to find out whether the same control was previously registered in the wndclass system. It's similar to the list of Linux kernels. The definition of WNDCLASS is as follows, by defining a member variable that can see a link in the WNDCLASS, as seen in the following:
from being able to see the mwlist link in the TAGWNDCLASSA structure.
Two: summary Microwindows also uses a type-independent, double-loop list implementation method. The idea is to extract the pointer head and tail from the detailed data structure to form a common "doubly linked list" data Structures Mwlisthead. Given the need to construct a particular list of objects of a certain class, a member of type Mwlisthead type is defined in its structure (called the host data structure), through which the member connects such objects, forms the desired list, and operates on them through a generic list function. The advantage is that simply writing a generic list function allows you to construct and manipulate linked lists of different objects without having to write a dedicated function for each type of object, which enables code reuse.


Open source Gui-microwindows program entrance analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.