Infinite
来源: BlogBus 原始链接: http://www.blogbus.com:80/blogbus/blog/?blogid=39016 存档链接: https://web.archive.org/web/20050121171140id_/http://www.blogbus.com:80/blogbus/blog/?blogid=39016
首页 Medicine (6) Biology (3) Computer (8) Astronomy (3) History (0) Geography (0) Archeology (1) Infinite my knowledge base 日历 2005 年 1 月 Sun Mon Tue Wen Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 最后更新 Icons on Menus in the .NET Framework Scripting with Flash Player and ActiveX 科学家找到火山喷发可能引起地球生命的证据 科学家研究发现染色体不稳定可能是癌症根源 什么蚊子传播登革热 软件测试基础 美两科学家分享04年度诺贝尔医学奖 利用google制作最酷的站内搜索引擎 禁止Windows Messenger随OE启动 ASP.net Forums V2.0中文技术白皮书 最新评论 冰雪凝�m : 不喜�g自己的blog. naoko : 登上排行榜还不好. 冰雪凝�m : 8月的�r候在Donew. naoko : 呵呵,你什么时候. 我的链接 Greenarea �G野幽境 我的存档 2004/08/01/-2004/09/01 2004/09/01/-2004/10/01 分页: [1] [2] [3] [4] [5] Icons on Menus in the .NET Framework -[Computer] 时间: 2004-10-19 22:41 �碓矗�MSDN Dear Dr. GUI, Microsoft has always kept the art of attaching an icon to a menu item to itself. I had solutions that worked with Visual Basic 6.0, but I need some insight on a Visual Basic .NET solution. Could you shed some light on this? Thanks in advance, Patrick Wimberley Dr. GUI replies: Luckily, the good doctor got plenty of rest last night and is full of energy to tackle the challenge you're offering. So let's take off our cardigan sweaters and get to work in the .NET lab, neighbor! Unfortunately, the MenuItem class does not provide a built-in way of displaying an icon. For example, there is no Icon property you set to display an icon automatically. But don't despair; the .NET Framework is remarkably extensible, so if a Framework class doesn't provide a feature you want, then you can usually extend that class through inheritance and a virtual function override or two, and provide the feature yourself―without having to write the whole class from scratch. This is old hat to C++ and Java programmers, but this kind of easy extensibility is a new feature of Microsoft® Visual Basic® .NET. In this case, the MenuItem class, like many Windows Forms visible objects, provides the capability for non-standard drawing, called "owner-draw." It does this by providing two virtual methods called OnMeasureItem and OnDrawItem . So let's create an owner-drawn menu item, which gives you (the owner) the right (and responsibility) of drawing or painting the MenuItem on the screen. First, we create a new class and indicate that it inherits from the old class: Public Class MyIconMenuItem Inherits MenuItem ' ... When you inherit from MenuItem , you inherit ALL of its properties, methods, and events. You want to override the behavior of two of the methods that you inherit so you can do your own drawing for your menu item class. These two methods are OnMeasureItem and OnDrawItem . Before examining the code for these methods, you'll want to declare some private fields within your class to hold an Icon object and a Font object. You need a Font object because you want your menu item to be able to contain text as well as icons. You also need a way for developers using your class to initialize your private fields. You can do this through your class's constructor. A Visual Basic .NET constructor is a special method called New that gets called by the runtime when an object of your class is created. (You can think of it as being similar to the Class_Initialize event in Visual Basic 6.0.) With Visual Basic .NET, you can actually pass parameters to your constructor! So let's take the concept of constructors and use it in your class to allow the developers who use your class to initialize your class's private fields. Your custom menu item class should now look something like this: Public Class MyIconMenuItem Inherits MenuItem Private font As Font Private icon As Icon Sub New(ByVal menuText As String, ByVal handler As EventHandler, _ ByVal shortcut As Shortcut, ByVal ico As icon) MyBase.New(menuText, handler, shortcut) Me.icon = ico Me.font = SystemInformation.MenuFont Me.OwnerDraw = True End Sub ' ... What if you don't want to have an icon? Just use a MenuItem rather than a MyIconMenuItem . Since our class is derived from MenuItem , we can use it polymorphically wherever we can use a MenuItem . Note that, in addition to overriding the appropriate methods (as described below), you also need to set the OwnerDraw property of your class to TRUE . This is an important step, because you won't see your icon displayed on your menu item if this isn't done, since the standard Framework code will draw the menu item rather than your overridden methods. When a menu is pulled down, the Framework first calls OnMeasureItem for each owner-drawn menu item to determine how big the menu needs to be (the sum of the heights and the largest of the widths), then calls OnDrawItem for each owner-drawn menu item to actually do the drawing. That's why we need to override two methods rather than one. Note also that these methods are the methods that raise the MeasureItem and DrawItem events. Since other objects may be listening to these events, we need to make sure the events get raised properly by calling the base class's implementation of our methods. Now let's examine the two methods that need to be overridden. OnMeasureItem gets called when the menu needs to be drawn. It allows you to specify the size of your menu by setting some properties of MeasureItemEventArgs , which is passed in as a parameter to this method. The properties you need to set are ItemHeight and ItemWidth . You'll need the height of the menu item, which is the greater of the icon height or the font height plus a few pixels, and the width of the menu. You can use the StringFormat object (in the System.Drawing namespace) to retrieve the width. And don't forget: When measuring the width of the menu item, you need to account for the icon also. OnMeasureItem should look something like this: Protected Overrides Sub OnMeasureItem(ByVal e As MeasureItemEventArgs) MyBase.OnMeasureItem(e) ' MUST be called, best to call first Dim sf As StringFormat = New StringFormat()
sf.HotkeyPrefix = HotkeyPrefix.Show sf.SetTabStops(50, New Single() {0})
If Me.icon.Height > Me.font.Height Then e.ItemHeight = Me.icon.Height + 6 Else e.ItemHeight = Me.font.Height + 6 End If e.ItemWidth = CInt(e.Graphics.MeasureString(AppendShortcut(), _ Me.font, 1000, sf).Width) + Me.icon.Width + 5 sf.Dispose() End Sub With the size of your menu specified, you need to draw it in your class's OnDrawItem method. This method gets passed a DrawItemEventArgs object. Use this object to obtain a Graphics object for your menu item. This allows you to draw directly on the surface of your menu using the powerful GDI+ features available in the .NET Framework. First, draw a background color, then draw your icon, and finally draw the text of our menu item using the following code: Protected Overrides Sub OnDrawItem(ByVal e As DrawItemEventArgs) Dim br As Brush Dim sf As StringFormat
MyBase.OnDrawItem(e) e.Graphics.FillRectangle(SystemBrushes.Control, e.Bounds) If Not (Me.icon Is Nothing) Then e.Graphics.DrawIcon(Me.icon, e.Bounds.Left + 3, e.Bounds.Top + 3) End If
sf = New StringFormat() sf.HotkeyPrefix = HotkeyPrefix.Show sf.SetTabStops(50, New Single() {0}) br = New SolidBrush(SystemColors.WindowText) e.Graphics.DrawString(AppendShortcut(), Me.font, br, e.Bounds.Left _
- Me.icon.Width + 10, e.Bounds.Top + 2, sf) 'Clean up resources br.Dispose() sf.Dispose() End Sub If you have been paying attention (and the good doctor is sure you have), you are probably wondering about the call to AppendShortcut in both OnMeasureItem and OnDrawItem . Why is this call being made? Well, you could just measure and draw your string based on your menu item's Text property, which would not take into account that your menu item might have a shortcut key. If it does have a shortcut key, you need to display it and increase the width of the menu item. You need a way to do this. AppendShortcut represents the shortcut key as a string, and appends that string to your existing menu item text. Here is the code for AppendShortcut : Private Function AppendShortcut() As String Dim s As String s = Me.Text ' Check to see if you have a shortcut ' If so, append it to your existing text If Me.ShowShortcut And Me.Shortcut <> Shortcut.None Then Dim k As Keys = CType(Shortcut, Keys) s = s & Convert.ToChar(9) & _ TypeDescriptor.GetConverter(GetType(Keys)).ConvertToString(k) End If Return s End Function There you go. The good doctor only had to tap into a small percentage of his energy reserves, so he is rewarding himself with cookies and milk. Now, let's put our cardigans back on and get ready to go. As soon as the .NET Framework ships (Real Soon Now), we'll all be able to do this for real, and leave the Land of Make Believe. Good luck, neighbor! 冰雪凝�m 发表于 22:41 | 阅读全文 | 评论(0) | 引用Trackback(0) | 编辑 Scripting with Flash Player and ActiveX -[Computer] 时间: 2004-10-19 21:19 �碓矗�Macromedia The documentation below describes the scripting interface for the Flash Player ActiveX control. This control handles playback of Flash content on Windows machines which support ActiveX (all 32-bit versions of Windows, beginning with Windows 95.) These methods may also be available to PocketPC Devices using the Flash Player for PocketPC (see the Flash Player for PocketPC FAQ for details.) Experienced scripters should first read the article Scripting with Flash for an overview of JavaScript methods which can control the Flash Player. Beginning scripters may benefit more from the example based TechNotes " An example of communication between JavaScript and Flash " (TechNote 15683) and " An example of communication between Flash movies " (TechNote 15692). Note: Most of these methods, properties and events are not available in the Netscape Navigator plug-in version of the Macromedia Flash Player, only the Flash Player ActiveX control for Windows. Properties ReadyState (get only) - 0=Loading, 1=Uninitialized, 2=Loaded, 3=Interactive, 4=Complete. TotalFrames (get only) - Returns the total number of frames in the movie. This is not available until the movie has loaded. Wait for ReadyState = 4. FrameNum (get or set) - The currently displayed frame of the movie. Setting this will advance or rewind the movie. Playing (get or set) - True if the movie is currently playing, false if it is paused. Quality (get or set) - The current rendering quality (0=Low, 1=High, 2=AutoLow, 3=AutoHigh). This is the same as the QUALITY parameter. ScaleMode (get or set) - Scale mode (0=ShowAll, 1= NoBorder, 2 = ExactFit). This is the same as the SCALE parameter. AlignMode (get or set) - The align mode consists of bit flags. (Left=+1, Right=+2, Top=+4, Bottom=+8). This is the same as the SALIGN parameter. BackgroundColor (get or set) - Override the background color of a movie. An integer of the form red65536+green256+blue use -1 for the default movie color. Loop (get or set) - True if the animation loops, false to play once. Same as the MOVIE parameter. Movie (get or set) - The URL source for the Flash Player movie file. Setting this will load a new movie into the control. Same as the MOVIE parameter. Methods Play () - Start playing the animation. Stop () - Stop playing the animation. Back () - Go to the previous frame. Forward () - Go to the next frame. Rewind () - Go to the first frame. SetZoomRect (int left, int top, int right, int bottom) - Zoom in on a rectangular area of the movie. Note that the units of the coordinates are in twips (1440 units per inch). To calculate a rectangle in Flash, set the ruler units to Points and multiply the coordinates by 20 to get TWIPS. Zoom (int percent) - Zoom the view by a relative scale factor. Zoom(50) will double the size of the objects in the view. Zoom(200) will reduce the size of objects in the view by one half. Pan (int x, int y, int mode) - Pan a zoomed in movie. The mode can be: 0 = pixels, 1 = % of window. Events OnProgress (int percent) - Generated as the Flash Player movie is downloading. OnReadyStateChange (int state) - Generated when the ready state of the control changes. The possible states are 0=Loading, 1=Uninitialized, 2=Loaded, 3=Interactive, 4=Complete. FSCommand (string command, string args) - This event is generated when a GetURL action is performed in the movie with a URL and the URL starts with "FSCommand:". The portion of the URL after the : is provided in command and the target is provided in args. This can be used to create a response to a frame or button action in the Shockwave Flash movie. HTML The HTML to insert the Flash Player ActiveX control and a movie in a page is: