Preparation of imitation OICQ menu with C Builder
Author: Maming Chen
Currently some avant-garde software uses self-drawing functions to beautify the program interface, such as QQ menus is an example. He uses the imitation WINDOS start interface, which is displayed on the left, then add a beautiful icon in front of each menu item. When the mouse is suspended on each menu item, the icon is convex, and the text portion of the menu item is concave, very beautiful. (The effect is as shown in Figure 1) Do you want to make such a menu in your program? So, let me make it. New project file, the form unit is set to CAPTION of the form with the CoolMenuprj.bpr store in the object browser in the object browser in the object browser in the object browser, and the Name property is set to COOLMENU in the Object Browser. Activate the Standard Component page Add a TMAINMENU component, set the name attribute as the coolMenu, the OwnerDDRAW property is true, the images property is Menuimage, activate the Win32 component page Add a TimageList component, set the name property to meimage. Double-click this imagelist Add as shown in Figure 1 The 9 icon files shown (the icon before the submenu) is displayed. Double-click the CoolMenu menu control to add the submenu shown in the figure. (Setting the imageIndex is 0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 7,8.
Open the COOLMENU.H file Add to the following code at its head: #include
Add the following code under Private: // User Declarations: graphics :: tbitmap * bmp1; void __fastcall drawbevel (TRECT & RECT, TCANVAS * CANVAS, BOOL BBEVEL)
Open the COOLMENU.CPP file Add a custom function as follows:
void __fastcall TCoolMenuForm :: DrawBevel (TRect & rect, TCanvas * Canvas, bool bBevel) {TColor c1, c2; if (bBevel == true) {c1 = clWhite; c2 = clGray;} else {c1 = clGray; c2 = clWhite; } Canvas-> pen-> color = c1; canvas-> moveto (rect.Left, Rect.top); canvas-> lineto (Rect.right, Rect.top); canvas-> Moveto (Rect.Left, RECT. TOP); canvas-> lineto (Rect.Left, Rect.Bottom); Canvas-> Pen-> Color = C2; Canvas-> Moveto (Rect.right, Rect.Bottom); Canvas-> Lineto (Rect.Left, Rect.bottom; canvas-> Moveto (Rect.right, Rect.Bottom); Canvas-> Lineto (Rect.right, Rect.top);
Then the activation window adds the following code during its oncreat event: void __fastcall tcoolmenuForm :: formCall (TOBJECT * Sender) {bmp1 = new graphics :: tbitmap (); / * bmp1.bmp file is a bitmap file on the left side of the menu. It is 21 * 190 pixels, which is stored in the current program directory * / bmp1-> loadFromFile (".//bmp1.bmp");} Then the activation window adds the following code during its OnDestroy event: void __fastcall TcoolMenuForm :: FormDestroy (Tobject * Sender) {delete bmp1;}
Then active "message management" sub-menu in the event that it is added in the course of OnDrawItem following code: void __fastcall TCoolMenuForm :: oicqDrawItem (TObject * Sender, TCanvas * ACanvas, TRect & ARect, bool Selected) {AnsiString str; TMenuItem * Item = dynamic_cast
if (SELECTED == True) {/ * If the user selects a menu item, then two bevel rectangles are drawn. One is convex, it is used to use it to the block bitmap, the other is concave, then write text to * / all; DrawBevel (Rect (all); exact.LEFT 1, Arect.top 1, Arect.Bott 18, Arect.Bottom - 1), Acanvas, True; Drawbevel (Rect (all 4, all, all, all, all, all, Bottom - 1), Acanvas, False;} else {// First to the menu item. I feel like a bitmap bitblt in the left side of the Start menu (acanvas-> handle, all, all, allt, all.right-all.top, all-> canvas-> handle, Arect.Left, all, indeft = all;
// The area below to draw the text and bitmap below in the background color of the system. / / Redraw menu item acanvas-> brush-> color = CLBTNFACE; acanvas-> fillRect (all); // Since there is no choice of state, this does not have to choose from State drawing.
Acanvas-> brush-> style = bsclear; str = item-> caption; // determine if the menu item is divided
IF (STR! = "-") {// Painting Figure 1 Menuimage-> DRAW (Acanvas, Arect.Left 2, Arect.top 4, Item-> ImageIndex, True);
Allt 24; all 24; all; all 5; distribution.right = all.right - 8; acanvas-> font-> color = CLBLACK; / / then text and shortcut strings Drawn to the second rectangular box above DrawText (Acanvas-> Handle, Str.c_Str (), Str.Length (), & all, DT_LEFT; Str = Shortcuttotext; DrawText (acanvas > Handle, str.c_str (), str.Length (), & all (), dt_right);} else {// If the menu split line is currently drawn, use the DrawBevel function to simulate a menu division line DrawBevel (Rect) Arect.Top 2, Arect.top 2, Arect.tight - 1, Arector (Top 3), Acanvas, False);}} The following code is added to the "Message Management" submenu on the "Message Management" submenu, add the following code: Void __fastcall tcoolmenuForm :: OICQmeasureItem (TOBJECT * SENDER, TCANVAS * Acanvas, Int & Width, INT & Height) {tMenuItem * Item = DYNAMIC_CAST
/ * This function is used to specify the wide and high of each menu item when drawing the OICQ menu. Please specify the onMeasure event that you want to draw into analog OICQ menu is specified as it * / width = 140; // The determination is a divided line, if it is a line cut line, then set the width of the divided line to 5 if (item-> caption == '-') height = 5; else height = 22;}
Finally, all the onDrawItem events of several submenu points to the OICQDrawItem code, point the ONMEASUREITEM event process to the OICQMeasureItem code. Press F9 to run, how is it good! (Note: There should be a BMP1.bpm file in the current directory of the program, which is a bitmap file on the left side of the menu. The size is 21 * 190 pixels)