New version menudemo--using Duilib to emulate Windows native menus

Source: Internet
Author: User

Believe that playing duilib friends has begun to look forward to a very long article. Since my article was published a week ago-"Implementation without focus forms" refers to the application of the Unfocused form in the menu, and promises to everyone, write a demo about the menu implementation to share to everyone.

Let's take a look at the effect.

Watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvu2tpbgxh/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70 /gravity/center ">

How, Skilla This work also can let you heart. That's right. The above menu effect is not the cool dog inside, is our familiar duilib realizes.

Speaking of the menu, we all think of the original Menudemo, anyone who has read the original Menudemo friend, should be very clear about its principle. It uses focus to control how the menu is destroyed. The involvement of the focus adds a lot of difficulty to the maintenance of cascading menus, and the unnecessary focus switching is also a waste. What's more, how keyboard events are added is also a tricky issue.

This time the Skilla provides the Menudemo is unfocused, makes it use more natural, more primitive ecology. About the Directui menu. We focus on "analog" two words. When the menu is implemented. Not only to simulate the appearance. More to simulate the essence.

When we were taking the form to simulate the menu. Be sure to first touch the original Windows native menu implementation of the internal principle, otherwise you will go very many detours.

The following is a first introduction to the Windows native menu mechanism, first a section of code.


int Cduimenu::runmenu () {int nret (-1); BOOL bmenudestroyed (FALSE); BOOL Bmsgquit (FALSE); while (TRUE) {if (m_menuret.bexit) {nret = 0;break;} if (GetForegroundWindow ()! = M_hwndowner) {break;} BOOL Binterceptother (FALSE); msg msg = {0};if (PeekMessage (&msg, NULL, 0, 0, pm_remove)) {if (Msg.message = = wm_keydown| | msg.message = = Wm_syskeydown || Msg.message = = wm_keyup| | Msg.message = = wm_syskeyup| | Msg.message = = wm_char| | Msg.message = = Wm_ime_char) {//transfer The Message to menu windowif (M_menus->iskeyevent ()) {Skill_assert (m_ Pkeyevent->getmenuwnd ()->gethwnd ()) Msg.hwnd = M_pkeyevent->getmenuwnd ()->gethwnd ();}} else if (msg.message = = wm_lbuttondown| | msg.message = = wm_rbuttondown| | msg.message = wm_nclbuttondown| | msg.message = = wm_ncrbuttondown| | Msg.message ==wm_lbuttondblclk) {//click on other windowif (! Ismenuwnd (Msg.hwnd)) {DestroyMenu ();//In order to synchronize with the menu popup message again::P ostmessage (Msg.hwnd,msg.message,msg.wparam,msg.lparam); Binterceptother = True;bmenudestroyed = true;}} else if (MSG.MESSAGE = = wm_lbuttonup| | msg.message==wm_rbuttonup| | msg.message==wm_nclbuttonup| | msg.message==wm_ncrbuttonup| | Msg.message==wm_contextmenu) {if (! Ismenuwnd (Msg.hwnd)) {//prevents the menu from popping multiple times at the same time::P ostmessage (Msg.hwnd,msg.message,msg.wparam,msg.lparam); else if (msg.message = = wm_quit) {bmsgquit = TRUE;} Block MOUSEMOVE messages for non-menu forms if (msg.message = = wm_mousemove) {if (! Ismenuwnd (Msg.hwnd)) {binterceptother=true;}} if (!binterceptother) {translatemessage (&msg);D ispatchmessage (&msg);}} Else{msgwaitformultipleobjects (0, 0, 0, ten, qs_allinput);} if (bmenudestroyed) break;if (bmsgquit) {postquitmessage (msg.wparam); break;}} if (!bmenudestroyed) {DestroyMenu ();} return nret;}

We all know that the focus is on the "stage" of the keyboard message. To say that the menu has no focus. So when we press the Vk_up,vk_down,vk_left,vk_right,vk_return on the keyboard, why does the menu react? Maybe you don't believe it yet. When the menu pops up, the interior is plugged in, and it will open a while loop like Domodel. In this way we can control the message as we go. When the menu pops up. The message loop is established. Only if the message of the process, regardless of which form will come here, when you receive a keyboard class message. Regardless of which form is assigned to the menu form, when the mouse button is pressed, inference is not a menu form, only if the menu is destroyed, the message from the message queue is thrown back to the message queue, the loop exits. When the mouse button bounces, only if not the menu form, take out the message. Throw back the message queue (like a drifting bottle, fished up to find no need to throw it back again, in fact this is done in order to give the menu this time to destroy and the next time it pops up to do a transition. Otherwise the last time has not been destroyed, this time the pop-up. is a mess). When there is a MouseMove message, only if the menu form is blocked, because the menu pops up, other forms of the MouseMove event will be masked out. See if the Windows native menu has this effect, when the owner form switches from the foreground to the background, the menu is destroyed, the loop exits, and when MenuItem receives the Click event, gets the menu command ID and notifies the menu that the message loop ends, Returns the menu command ID and forwards to the owner form Wm_commad message.

What do you think. Such an analysis. is the implementation of the menu becoming more enlightened? When implementing cascading menus, there is no need to worry about the focus, and the increase in keyboard events becomes a breeze. It is important that the menu effect is well implemented. But the more important thing is to be useful.

The package is easy to use do not look at the duilib to give strength. After Skilla test duilib is still very strong. Haha, a joke.

The Ccontainerui inside the duilib is a control container. As a display, we use Ccontainerui as our menu container. Just don't show it directly, we use it as an ordinary array. Why is it? Of course, because the analysis is convenient.

Due to cascading requirements. The menu is not a natural one, we use Ccontainerui as our container, with Cdialogbuilder parse out. Nature is an array of menus.

This is the outermost tag of the menu parsing XML. In order to add two attributes to it, we inherit Ccontainerui. Get a menucontainer once again. Rewrite setattribute. Add two properties. One is the interval of the interval (Level two menu. If the hypothesis is unclear, try to change it yourself), and one is keyevent this is a bool property (whether keyboard is turned on).

Menucontainer inside is one of our menu, for the convenience of drawing, we use Clistui as a menu UI, to Clistui as the base class derivation Cmenuui, we can rewrite setattribute to add to it the properties we need. Here I still add two attributes to him. A major (bool type, whether the main menu), and a Bktrans (bool type. Whether transparent is turned on), the other attributes follow the properties of Clistui.

Cmenuui inside is one of the menu items, in order to meet a variety of needs. Skilla designed two menu items, one called MenuItem (General menu item), and one called StaticMenuItem (Static menu items), as the name implies, MenuItem is the real menu item. Mouse pointing up there will be suspended events, press the keyboard up and down. The menu items that can be selected, StaticMenuItem are the menu-independent controls, such as the menu divider, the play button on the cool Dog taskbar menu, the slider bar, and so on. Unbiased, the Skilla same gives the MenuItem two properties, a comand (string, the return value of the menu message when the loop exits.) This is the basis of the menu command response), and there is a Extendmenu (string, submenu of name, which is the key to each menu cascade).

Using this menuui only need to introduce two files, one MenuUI.h and one MenuUI.cpp.

There is a need to simply change the source code, 1. According to Skilla's previous article. Change the Cpaintmanagerui. Let IT support no-focus form 2. Change the Attachdialog, because the Cpaintmanagerui in the destruction of the number of controls bound to the above also destructor. Since all of the menu controls are created by our own call to Cdialogbuilder, we naturally want to destroy ourselves, so in order not to let Cpaintmanagerui interfere, we add a bool M_bautodeletecontrols attribute, and is initialized to false. Add a bool parameter to Attachdialog, and the default value is true. The function body is assigned a value to M_bautodeletecontrols, and finally the delete m_proot inside the Cpaintmanagerui destructor is added with an if (m_bautodeletecontrols) inference.

After the changes, the introduction of MenuUI.h and a MenuUI.cpp of the two files can be used.

Finally talk about Skilla on the Windows interface programming some ideas, now open-source interface library, despite the very many, casually come up with a can make a very good interface. But. We can't be too obsessed with whatever interface library. Since the play is Windows can not forggestting, you use Duilib or Soui. Need to be careful to try to figure out the Windows API, because our controls are simulated. Or that sentence, no interface library is fully in line with the needs of all, to perfect, you have to do it yourself.


Sorry, because there is no strict test before uploading, the release version number of the last upload has a bug (because. When adding the Setunfocuspaintwindow function. The function body is written in the header file, and after compiling it into the release library there is a problem. Now has changed and uploaded a copy, the need for a friend to download.

Source Code and demo download (if there is a suggestion or find a bug, please leave a message.) or contact qq:848861075 (skilla) Thank you!

Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.

New version menudemo--using Duilib to emulate Windows native menus

Related Article

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.