Duilib create menu window

Source: Internet
Author: User
From: http://blog.163.com/zwei3666@126/blog/static/993128052012101272027399/

First. Supports multi-level extension, supports menu headers, supports text center/left/right alignment, supports font color settings, supports adding custom controls, and supports basic attributes (background color, image, icon.

Pretty? Cough ~ Generally ~ In fact, there is already a menudemo in duilib, But it loads the XML layout file. Of course, loading XML directly is much easier for anyone. It can be inherited and used as a template !!!!........ I just wrote it. It's rough. Just try it.

The menu is like that.

Main functions:

* Cmenuui menu window class. Used to create a menu window and display menu options.
* Menuelementui option class. Create menu options
* Wndsvector window queue. Used to manage display and hide of all menu windows

First look at the Framework process:

The overall process is not complex, but how can we solve the problem of displaying and hiding extended windows (that is, level-2 menus) of Window Options? Think about the two message loops.

List the areas that involve window creation and destruction, display, and hiding:

1. When creating a menu, only the main menu is displayed. All extended windows are hidden.

2. When the mouse enters the option with an extended window, the extended window is displayed (message: uievent_mouseenter)

3. Hide the extended window (uievent_mouseleave) when the mouse leaves the option)

4. When you click the option, if the option does not have an extended window, the entire menu is destroyed. And the ID corresponding to this option. (Uievent_buttondown)

5. When you click anywhere outside the menu window, the entire menu is destroyed. (Window message: wm_killfocus)

The above five points are a normal idea, But when processing the mouse exit option, I found that when the mouse leaves, it may leave the menu window or just enter the next option, how to judge it really makes me very hard .. Later, after reading the demo, I suddenly realized that I didn't need to deal with it when I left the menu window with the mouse ...... For the other option, leaving the mouse will inevitably go to the next option. It is very suitable to process only one option .. SO 2 and 3 are combined into one ~~~~ That is to say, "When the mouse enters the option, close the extension window, and then judge whether it has been extended. If so, re-display it?

To facilitate the processing of all window activities, I pushed the pointer of all created windows to the queue vector: wndvector for subsequent processing .~~~ Of course, it is to create one and press it into one, so it will not miss ~~~ It won't be heavy either ~~~ This queue is irrelevant to the user (not created by the user or cleaned by the user). It is dedicated to window management and is unique. Therefore, this class is set to a static class ~ All methods are static ~ In this way, you can directly use it without creating an instance ~

To reduce the coupling between different classes, and to facilitate the display and disappearance of the window... Cough .. In short, I have created a signal data structure:

Struct contextmenuparam
{
Hwnd;
Wparam; // if the value is 1, the entire menu is destroyed. If the value is 2, The hwnd and all its parent windows are displayed.
};

Why should I send such a signal to the queue as needed? Is it neat? That's what I think .. Hey ~~

Paste the management class code '~~

Class wndsvector
{
PRIVATE:
Typedef STD: vector <cmenuui *> receiversvector;
Static receiversvector receiverwnd;
Public:
Static hwnd roothwnd; // records the creation of the Main Window of the menu. In order to facilitate the direct transmission to the idnumber of the main window when you click the option with the mouse, avoid calculation ....

/*****
* Function: press the window pointer into the window queue.
* Parameter: PTR window pointer
* Return value:
******/
Static inline void addwnd (cmenuui * PTR)
{
Receiverwnd. push_back (PTR );
}

/*****
* Function: Send the window signal to each window in the queue.
* Parameter: Param window signal
* Return value:
******/
Static void broadcast (contextmenuparam & PARAM)
{
If (receiverwnd. Empty ())
Return;
Receiversvector: reverse_iterator it = receiverwnd. rbegin ();
For (; it! = Receiverwnd. rend (); It ++)
{
If (* It! = NULL)
(* It)-> canceclosemsg (PARAM );
}
}

/*****
* Function: Find the window class pointer that contains the handle in the window queue.
* Parameter: handle to be searched by hwnd
* Return value: Find the corresponding window class pointer; otherwise, return null.
******/
Static cmenuui * findwndclass (hwnd)
{
If (receiverwnd. Empty ())
Return NULL;
Receiversvector: iterator it = receiverwnd. Begin ();
For (; it! = Receiverwnd. End (); It ++)
{
If (* It! = NULL & (* It)-> gethwnd () = hwnd)
Return * it;
}
Return NULL;
}

/*****
* Function: Clear the queue
******/
Static inline void removeall ()
{
Receiverwnd. Clear ();
}
};

Let's talk about the solution to these four problems:

1. When creating a menu, only the main menu is displayed. All extended windows are hidden.

Mm ~ As long as the position and size of all extended windows are not set when the main window is created, the size of the window is 0 to ~ by default ~~ The location is also 0, 0

2. When the mouse enters the option, close the extension window and check whether it has been extended. If yes, re-display it.

When entering the option, first determine whether the current option is the same as the next option ~~ Avoid entering the option with the mouse and then exit the window and go to this option directly ~ Because in this case, you don't need to do anything ~~~ If they are different, send a signal to the management queue {pmanager. getpaintwindow (), 2}, call wndsvector. broadcast (signal) is responsible for transmitting signals to all windows and letting them determine whether pmanager is used. dad or grandfather of getpaintwindow ~ If it is not, it will be hidden. Otherwise, it will not be processed ~~~ Then, check whether there is an extended window.

3. When you click the option, if the option does not have an extended window, the entire menu is destroyed. And the ID corresponding to this option. (Uievent_buttondown)

Sending signal {null, 1 }. All will be destroyed here. Just give a suicide signal and there is no need to transfer the handle together.

Upload ID. Postmessage (wndsvector: roothwnd, uid, event. wparam, event. lparam); the reason why sendmessage is not needed is that only this ID is sent here. After sending itself, it will destroy itself, and postmessage does not need to be returned. Just add the message to the Message Queue of the process and other lines.

4. When you click anywhere outside the menu window, the entire menu is destroyed. (Window message: wm_killfocus)

You can perform a check.

First. Supports multi-level extension, supports menu headers, supports text center/left/right alignment, supports font color settings, supports adding custom controls, and supports basic attributes (background color, image, icon.

Pretty? Cough ~ Generally ~ In fact, there is already a menudemo in duilib, But it loads the XML layout file. Of course, loading XML directly is much easier for anyone. It can be inherited and used as a template !!!!........ I just wrote it. It's rough. Just try it.

The menu is like that.

Main functions:

* Cmenuui menu window class. Used to create a menu window and display menu options.
* Menuelementui option class. Create menu options
* Wndsvector window queue. Used to manage display and hide of all menu windows

First look at the Framework process:

The overall process is not complex, but how can we solve the problem of displaying and hiding extended windows (that is, level-2 menus) of Window Options? Think about the two message loops.

List the areas that involve window creation and destruction, display, and hiding:

1. When creating a menu, only the main menu is displayed. All extended windows are hidden.

2. When the mouse enters the option with an extended window, the extended window is displayed (message: uievent_mouseenter)

3. Hide the extended window (uievent_mouseleave) when the mouse leaves the option)

4. When you click the option, if the option does not have an extended window, the entire menu is destroyed. And the ID corresponding to this option. (Uievent_buttondown)

5. When you click anywhere outside the menu window, the entire menu is destroyed. (Window message: wm_killfocus)

The above five points are a normal idea, But when processing the mouse exit option, I found that when the mouse leaves, it may leave the menu window or just enter the next option, how to judge it really makes me very hard .. Later, after reading the demo, I suddenly realized that I didn't need to deal with it when I left the menu window with the mouse ...... For the other option, leaving the mouse will inevitably go to the next option. It is very suitable to process only one option .. SO 2 and 3 are combined into one ~~~~ That is to say, "When the mouse enters the option, close the extension window, and then judge whether it has been extended. If so, re-display it?

To facilitate the processing of all window activities, I pushed the pointer of all created windows to the queue vector: wndvector for subsequent processing .~~~ Of course, it is to create one and press it into one, so it will not miss ~~~ It won't be heavy either ~~~ This queue is irrelevant to the user (not created by the user or cleaned by the user). It is dedicated to window management and is unique. Therefore, this class is set to a static class ~ All methods are static ~ In this way, you can directly use it without creating an instance ~

To reduce the coupling between different classes, and to facilitate the display and disappearance of the window... Cough .. In short, I have created a signal data structure:

Struct contextmenuparam
{
Hwnd;
Wparam; // if the value is 1, the entire menu is destroyed. If the value is 2, The hwnd and all its parent windows are displayed.
};

Why should I send such a signal to the queue as needed? Is it neat? That's what I think .. Hey ~~

Paste the management class code '~~

Class wndsvector
{
PRIVATE:
Typedef STD: vector <cmenuui *> receiversvector;
Static receiversvector receiverwnd;
Public:
Static hwnd roothwnd; // records the creation of the Main Window of the menu. In order to facilitate the direct transmission to the idnumber of the main window when you click the option with the mouse, avoid calculation ....

/*****
* Function: press the window pointer into the window queue.
* Parameter: PTR window pointer
* Return value:
******/
Static inline void addwnd (cmenuui * PTR)
{
Receiverwnd. push_back (PTR );
}

/*****
* Function: Send the window signal to each window in the queue.
* Parameter: Param window signal
* Return value:
******/
Static void broadcast (contextmenuparam & PARAM)
{
If (receiverwnd. Empty ())
Return;
Receiversvector: reverse_iterator it = receiverwnd. rbegin ();
For (; it! = Receiverwnd. rend (); It ++)
{
If (* It! = NULL)
(* It)-> canceclosemsg (PARAM );
}
}

/*****
* Function: Find the window class pointer that contains the handle in the window queue.
* Parameter: handle to be searched by hwnd
* Return value: Find the corresponding window class pointer; otherwise, return null.
******/
Static cmenuui * findwndclass (hwnd)
{
If (receiverwnd. Empty ())
Return NULL;
Receiversvector: iterator it = receiverwnd. Begin ();
For (; it! = Receiverwnd. End (); It ++)
{
If (* It! = NULL & (* It)-> gethwnd () = hwnd)
Return * it;
}
Return NULL;
}

/*****
* Function: Clear the queue
******/
Static inline void removeall ()
{
Receiverwnd. Clear ();
}
};

Let's talk about the solution to these four problems:

1. When creating a menu, only the main menu is displayed. All extended windows are hidden.

Mm ~ As long as the position and size of all extended windows are not set when the main window is created, the size of the window is 0 to ~ by default ~~ The location is also 0, 0

2. When the mouse enters the option, close the extension window and check whether it has been extended. If yes, re-display it.

When entering the option, first determine whether the current option is the same as the next option ~~ Avoid entering the option with the mouse and then exit the window and go to this option directly ~ Because in this case, you don't need to do anything ~~~ If they are different, send a signal to the management queue {pmanager. getpaintwindow (), 2}, call wndsvector. broadcast (signal) is responsible for transmitting signals to all windows and letting them determine whether pmanager is used. dad or grandfather of getpaintwindow ~ If it is not, it will be hidden. Otherwise, it will not be processed ~~~ Then, check whether there is an extended window.

3. When you click the option, if the option does not have an extended window, the entire menu is destroyed. And the ID corresponding to this option. (Uievent_buttondown)

Sending signal {null, 1 }. All will be destroyed here. Just give a suicide signal and there is no need to transfer the handle together.

Upload ID. Postmessage (wndsvector: roothwnd, uid, event. wparam, event. lparam); the reason why sendmessage is not needed is that only this ID is sent here. After sending itself, it will destroy itself, and postmessage does not need to be returned. Just add the message to the Message Queue of the process and other lines.

4. When you click anywhere outside the menu window, the entire menu is destroyed. (Window message: wm_killfocus)

You can perform a check.

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.