Implement VS.NET or Office XP-style menu with C # and VB.NET
The god of the small gas 2001.08.18
2. "Owner-Drawn Menus" technology
This example is VB.NET syntax. I removed the Class of Menu, the reason is that there are too many errors, you will encounter the graft of class library and namespace:
The most is the namespace problem of Beta1 System.WinForms and Beta 2 System.Windows.froms;
Then, BitA1, Bitxxx, Bitxxx, is then removed in Beta2 and the VB is the same. (It is said that this change in Beta1 has been complained in the total VB Fans, saying that VB is also C # What is BIT is Dongdong) so you need to change this type of function;
Then NameObjectCollectionBase is removed from the original System.Collections, and Beta2 is placed in system.collections.specialized, which is really fainted, and I also thought that this class was deleted in Beta2.
Finally, some Overrides and OverLoads issues, specifically see the prompt when compiled by VS.NET or Framework SDK Beta 2, this, MS is doing well, Task List tells you that it is good.
For details, you can find these two files in the DOC directory of the Framework SDK Beta 2 installation directory, which is ported from Beta1 to Beta2, good guidance file: APICHANGESBETA1TOBETA2.HTM and Change List - Beta1 to beta2.doc, especially this DOC The file is slid more than 90 pages, but it is very helpful.
I hope you can also keep awake after exclude all errors, find the core useful code, to analyze. Mainly CACTIONMENU.vb, focus on two functions or event handles on ONMEASureItem and OnDrawItem. OnMeasureItem is mainly to process MenuItem's itemHeight and ItemWidth, you know from the number of MeasureIthMeventargs parameters it passed. OnDrawItem is mainly how to draw a menu problem. Keyword Overrides indicates that we have to redefine these two methods in the MenuItem in subclasses.
From 56 lines to 58 lines are onMeasureItem functions:
Protected Overrides Sub onMeasureItem (Byval e as system.windows.forms.measureItemgs)
If me.action.caption = "-" THEN
E.ItemHeight = 5
Else
E.ItemHeight = 20
END IF
DIM FS AS FONTSTYLELELELELELELE
If me.defaultItem = true kils = fs or fontstyle.bold
DIM FNT AS New Font ("Tahoma", 8, FS)
DIM sf as sizef = E.Graphics.MeasureString (Me.Action.caption, fnt)
FNT.Dispose ()
E.ItemWidth = CINT (sf.width) 20
End Sub
MeasureITeventArgs offers 4 properties Graphis, Index, ItemHeight, and ItemWidth. ME is equivalent to the key of the THIS of C # or Java. FNT.Dispose () Dispose is a very interesting function call, in the past Windows programming interconnect font, brush and other resources, you want to use it quickly, this statement is used to control Garbage Collection, meaning I have used this device or resource, and you can recover. From 70 to 146 lines are on the onitemdraw function:
Protected Overrides Sub OnDrawItem (Byval E As System.Windows.Forms.DrawItemgs)
'Colors, Fonts
DIM CLRBGICON, CLRBGTEXT, CLRText As Color, FS AS FontStyle, FNT AS FONT
DIM B As Solidbrush, P as Pen
DIM FENABLED As Boolean = NOT CTYPE (E.State and DrawItemState.disabled, Boolean)
Dim fselected as boolean = ctype (E.State and DrawItemState.selected, Boolean)
Dim fdefault as boolean = ctype (E.State and DrawIrymstate.default, boolean)
Dim fbreak as boolean = (me.action.caption = "-")
IF fenabled and fselected and not fbreak kil
CLRBGICON = Color.silver
CLRBGTEXT = Color.White
CLRText = color.blue
FS = fs or fontstyle.underline
Else
CLRBGICON = Color.gray
CLRBGTEXT = color.silver
CLRText = color.black
END IF
IF not fenabled
CLRText = color.White
END IF
IF fdefault then
FS = fs or fontstyle.bold
END IF
FNT = New Font ("Tahoma", 8, FS)
'Total Background (Partly to Remain for icon)
B = New Solidbrush (CLRBGICON)
E.Graphics.FillRegion (B, New [Region] (E.BOUNDS))
b.dispose ()
'icon?
If not me.action.Actionlist is nothingin
DIM IL as imagelist = me.action.ActionList.imagelist
IF not il is nothing then
DIM index as integer = me.action.image
IF index> -1 and index Dim Rect As Rectangle = E.Bounds WITH RECT .X = 2 .Y = 2 .Width = 16 .Height = 16nd with E.Graphics.drawImage (Il.images.Item (Index), Rect) END IF END IF END IF 'Text Background DIM RF As Rectanglef With RF .X = 18 .Y = e.bounds.y .Width = E.Bounds.width - .x .Height = E.Bounds.height End with B = New Solidbrush (CLRBGText) E.Graphics.FillRegion (B, New [Region] (RF)) b.dispose () 'Text / Line RF.Y = 3: rf.height - = 3 IF not fbreak then B = New Solidbrush (CLRText) E.Graphics.drawstring (Me.Action.caption, FNT, B, RF) FNT.Dispose () b.dispose () Else P = new pen (color.ble) Rf.y - = 1 E.Graphics.drawline (p, rf.x, rf.y, rf.right, rf.y) p.dispose () END IF 'border IF fenabled and fselected and not fbreak kil P = new pen (color.ble) E.Graphics.drawRectangle (P, E.Bounds) p.dispose () END IF End Sub The DrawiteMeventArgs parameter gives you all the environments and information related to the menu, including 6 properties: Bounds, Font, Forecolor, Graphics, Index, State. If you have used the GDI function under Windows, it must be familiar with these functions. It is not very complicated to only need a little arithmetic knowledge and artistic point of view. If you are the first time you draw a few rectangular blocks It is possible to understand and do it, which is much easier than the menu programming under TC. Mainly how the author is how to draw the ICON on the menu, then the Forecolor of the menu is based on different states, Bounds is the most prequight block of the menu item. The second part involves most of the technical details. Here you need to pay attention, how to draw it, the next part we look at how to draw, like vs.net or office XP.