Zt: Some menu tips in Delphi

Source: Internet
Author: User

I learned how to use Delphi and encountered some menu programming problems, some of which are representative or practical. I first sorted them out from my notes and shared them with you, please kindly advise.

-- 1 move the menu item to the rightmost of the menu bar

In some applications, some special menu items are usually placed on the rightmost side of the menu bar (such as the "Custom interface" menu in wps2000 and the Help menu of some applications ), it is better to place these menu items on the right of the menu bar. Although not provided directly in Delphi (haha, maybe I did not find it), the function that places the menu on the right of the menu bar, however, the Windows unit of Delphi encapsulates the Windows API functions (modifymenu and getmenuiteminfo) that can achieve this effect ). Therefore, we can directly use these functions in Delphi to achieve this effect.
You can use modifymenu and getmenuiteminfo to move the menu item to the rightmost of the menu bar. Which one is better? According to the Windows SDK documentation:
The modifymenu function can change the settings of an existing menu item. This function is used to specify a menu title, display appearance, and other items. However, the modifymenu function is now replaced by the more powerful setmenuiteminfo function. However, if your program does not need the extended functions provided by the setmenuiteminfo function, you can continue to use the modifymenu function.
The modifymenu function supports windows 32, 9x, and NT/2000.
The setmenuiteminfo function supports Windows 9x, NT/2000, and Windows 32 (earlier versions do not support NT/2000 ).
In addition, the setmenuiteminfo function is more powerful than the modifymenu function, but using the setmenuiteminfo function requires more complex parameters than the modifymenu function. So here I still use the relatively simple modifymenu function.
The modifymenu function is prototype:
Bool modifymenu (
Hmenu hmnu, // handle of menu
Uint uposition, // menu item to modify
Uint uflags, // menu item flags
Uint uidnewitem, // menu item identifier or handle of drop-down menu or submenu
Lptstr lpnewitem // menu item content
);
The first hmenu parameter indicates the handle of the menu to be modified (for example, mainmenu1.handle );
The second uposition parameter refers to the index value of the menu item to be modified (the first value on the left of the menu bar is zero, increasing from left to right, and the maximum value is one minus the total number of menu items );
The third parameter uflags indicates the status of the new menu item (after the menu item referred to by the second parameter is modified;
The fourth parameter uidnewitem is the handle pointing to the new menu;
The fifth parameter lpnewitem indicates the title of the new menu.
Example:
Create a new project with a menu and set its mainmenu component name to mainmenu1. The name of the menu to be moved to the rightmost of the menu bar is help1.
Add the following code to the oncreate time handler of the form
Procedure tform1.formcreate (Sender: tobject );
Begin
Modifymenu (mainmenu1.handle, 2,
Mf_byposition or mf_help,
Help1.Handle, Pchar (Help1.Caption ));
// The MF_HELP parameter determines that the menu item (Help1) is displayed at the rightmost end of the window.
End;
Run the command to see how it works.

-- 2. Customize the System Menu

In the main form of a common application, you can click the icon in the upper left corner to bring up a system menu. This menu is very convenient to some extent, the problem is that these are all default system menu commands, which is of little help to us. Of course, we can customize the system menu and add what we need. in Delphi, the form component does not provide the corresponding components of the system menu, therefore, we can use Windows API functions to customize the system menu. Windows API functions are commonly used for menu operations:
AppendMenu inserts a new menu item at the end of the existing menu item;
DeleteMenu: delete an existing menu item from the menu and clear the item;
RemoveMenu deletes an item from an existing menu item;
InsertMenu inserts a new item into the existing menu item;
ModifyMenu: modify an existing menu item;
The usage of these functions is similar to the usage of the ModifyMenu function. In the following example, only the AppendMenu function is used to add a menu to the system menu, although it is meaningless, however, we hope that it will play a leading role.
AppendMenu function prototype:
BOOL AppendMenu (
HMENU hMenu, // The menu handle to be customized
UINT uFlags, // how to customize menu items
UINT uIDNewItem, // The menu item identifier or sub-menu handle to be customized
Lptstr lpNewItem // The menu item to be customized (string)
);
In the AppendMenu function, the lpNewItem and uIDNewItem parameters vary depending on different uFlags.
Unique restriction: The uIDNewItem value must be less than $ F000 (decimal: 61440 ); otherwise, it will conflict with the ID value used by the Windows System menu command. Remember that when you process the WM_SYSCOMMAND message for these new menus during the window, you must send other WM_SYSCOMMAND messages to DefWindowsProc (add an Inherited; sentence at the end of the event handler in Delphi). Otherwise, you can try again.
First, create a new project. To use the content in the Menus unit, add Menus to the uses statement in the Unit1.pas file.
Uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, Menus;
Then add the following code to the OnCreate event processing process of form Form1:
Procedure TForm1.FormCreate (Sender: TObject );
Var hSysMenu: hMENU;
Begin
HSysMenu: = GetSystemMenu (Handle, False); // obtain the system menu Handle.
AppendMenu (hSysMenu, MF_SEPARATOR, 0, ''); // Add a separator
AppendMenu (hSysMenu, MF_STRING, 3, 'about (& )');
End;
In the TForm1 type definition, add the statement for processing the OnClick event of the new menu item in the System menu (that is, the statement for processing the message WM_SYSCOMMAND ):
Type
TForm1 = class (TForm)
Procedure FormCreate (Sender: TObject );
Private
Procedure SysMenuCommand (var Msg: TWMMENUSELECT );
Message WM_SYSCOMMAND;
{Private declarations}
Public
{Public declarations}
End;
Then press Shift + Ctrl + C to complete the class declaration. Enter the following code:
Procedure TForm1.SysMenuCommand (var Msg: TWMMENUSELECT );
Begin
If Msg. IDItem = 3 then
MessageBox (0, 'A Poor-Person's Menu Program '+ #13 +
'Copyright Skyey, 100', 'skyine ',
MB_ OK + MB_ICONINFORMATION );
Inherited;
End;
Compile and run the program to test its effect.
Appendix: Some uflags definition values: // select windows SDK help from Delphi 5
Mf_bitmap indicates that the menu item is a bitmap, And the lpnewitem parameter indicates the bitmap handle.
Mf_checked put a "selected" mark in front of the menu item
Mf_disabled shields this menu item, but does not make it gray
Mf_enabled makes this menu item valid, opposite to mf_disabled
In addition to mf_disabled, mf_grayed also dimmed the menu item.
Mf_menubreak puts the menu side by side with the existing menu
Mf_menubarbreak is the same as mf_menubreak, except for a vertical line in the middle
Mf_ownerdraw indicates that the menu item is a self-painted menu item, and all display and update problems must be handled.
Mf_popup this menu item is a sub menu, and the uidnewitem parameter represents its handle
Mf_separator draws a split line on the menu item
Mf_string this menu item is a text string and lpnewitem is its content
Mf_unchecked: deselect the "selected" mark before this menu item.
The following groups of logos cannot be used at the same time:
<1> mf_disabled, mf_enabled, and mf_grayed
<2> mf_bitmap, mf_string, and mf_ownerdraw
<3> mf_menubarbreak and mf_menubreak
<4> mf_checked and mf_unchecked

-- 3 dynamically define shortcut keys for menus

In fact, it is to change the shortcut Cut attribute of the menu, add a hotkey component to the program, and then assign the hotkey attribute to the shortcut Cut attribute of the menu. For example:
Procedure tform1.btnchange1click (Sender: tobject );
Begin
New1.shortcut: = hotkey1.hotkey;
End;
If you only need the program to change a limited number of shortcut keys without changing them, you can also directly assign a value of the tshortcut type to the shortcut Cut attribute of the menu without using the hotkey component. For example:
Procedure tform1.btnchange1click (Sender: tobject );
Begin
New1.shortcut: = 32833; // Alt +
End;
The value of a shortcut key can be obtained at design by following the method below: First, you need to change the shortcut Cut attribute of the menu during design, right-click the form and choose view as text. Find the component in the DFM file. For example, CTRL + ALT + N is required.
Object new1: tmenuitem
Caption = '& new'
Export cut = 49230 // This is
Onclick = new1click
End

-- 4 dynamically change the menu

Is to change the Enabled attribute and Visible attribute of the menu item. These two attributes can be changed at design or runtime.
If the Enabled attribute is set to False, the menu item is dimmed and unavailable. If it is set to True, the menu item is in the normal usable state.
If the Visible attribute is set to False, this menu item is not displayed at run time. If it is set to True, this menu item is displayed.
For example, New1.Enabled: = False; // The New menu item turns gray and the menu is unavailable now.
New1.Enabled: = True; // The New menu item can now be used
New1.Visible: = False // The New menu item is not displayed now.
New1.Visible: = True; // The New menu item is displayed now.
The only thing to note is that the Visible and Enabled attributes are independent of each other. They do not affect each other. If a menu has a shortcut key and Its Enabled attribute is True, even if its Visible attribute is False (that is, it is invisible during runtime), you can still access it with a shortcut key.
During the running of the program, you can modify the two attributes of the menu item to dynamically change the menu display.

-- 5. Obtain the user error key information

If you press Alt and a character that does not match the menu item, or when the pop-up menu is displayed and the user presses a character key that does not match the item in the pop-up menu. How do we know that the user presses the wrong key and the user presses the key?
In fact, when the above assumption occurs, Windows will send a WM_MENUCHAR message. Generally, we do not need to process this message. Windows programs usually send it to DefWindowProc, it usually returns 0 to Windows, even if Windows sends a short beep. If we need to handle the above assumptions, we only need to intercept the message.
Let's take a look at the parameters of this message:
Wm_menuchar
Loword (wparam); // the ASCII code of the user's key
Hiword (wparam); // selection code
Lparam; // menu handle
Meaning of selection code:
0: no pop-up menu is displayed;
Mf_popup: displays drop-down menus, submenus, and shortcut menus (pop-up menus)
Mf_sysmenu: displays the system pop-up menu.
Message return value:
0: notifies windows to discard the character pressed by the user and send a short beep;
1: windows should be notified to close the current active menu;
2: Windows is notified to return a low-level word with a zero base point relative to the menu item, which is determined by windows.
After understanding this, let's take a look:
Create a new project with a menu, put a memo component (Name: memo1) on the form, and add the message declaration part after the public variable of the form:
Public
Procedure mmenuchar (var msg: tmessage); message wm_menuchar;
{Public declarations}
End;
Press SHIFT + Ctrl + C to complete the class declaration. Enter the following code:
Procedure tform1.mmenuchar (var msg: tmessage );
Begin
Memo1.Lines. Add (Chr (LOWORD (Msg. WParam )));
Memo1.Lines. Add (IntToStr (HIWORD (Msg. WParam )));
Msg. Result: = 0;
End;
Compile, link, and run the program to test its effect.

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.