zoukankan      html  css  js  c++  java
  • 使用。net 2.0和WinAPI定制windows

    介绍 本文展示了如何使用GDI+创建自定义窗口。 背景 不久前,我有一个任务,为MS PPTViewer应用程序创建一个菜单,该菜单允许用户使用菜单项切换幻灯片。我决定使用User32.dll库中的WinAPI函数“UpdateLayeredWindow”创建一个菜单。这个函数允许在屏幕上绘制任何32位的图像。对于这个菜单,我实现了一个想要共享的库。 使用的代码 要创建自定义窗口,您应该继承TransparetWindow类并覆盖DrawPolygons方法。这个方法应该返回一个IPolygons的集合。这样做是为了在所有的计算之后绘制多边形。 隐藏,复制Code

    public interface IPolygon
    {
        void Draw(Graphics g);
    }

    transparent twindow类包含System.Windows中的一些事件和属性。表单名称: 隐藏,复制Code

    public event EventHandler LocationChanged;
    public event EventHandler Move;
    public event MouseEventHandler MouseDown;
    public event MouseEventHandler MouseUp;
    public event MouseEventHandler MouseMove;
    public event EventHandler MouseEnter;
    public event EventHandler MouseLeave;
    public Brush Background { get; set; }
    public CornerRadius CornerRadius{ get; set; }
    public int AlphaChannel{ get; set; }
    public Size Size{ get; set; }
    public Point Location{ get; set; }

    最有趣的性质是核半径。如果你设置了这个属性,你会得到一个圆角的窗口。代码如下: 隐藏,复制Code

    TransparentWindow window = new TransparentWindow();
    window.Border = new Pen(Brushes.Black);
    window.CornerRadius = new CornerRadius(15);
    window.Size = new Size(400,400);
    window.Background = Brushes.White;
    window.Location = new Point
                (
                    Screen.PrimaryScreen.WorkingArea.Left + 300,
                    Screen.PrimaryScreen.WorkingArea.Height / 2 - 140
                );
    window.Show();

    如果你运行这段代码,你会得到一个这样的窗口: 下面是菜单的代码(见第一张图片)实现: 隐藏,收缩,复制Code

    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using CustomMenuLibrary.CustomPolygons;
    using CustomMenuLibrary.Menu;
    
    namespace CustomMenuLibrary
    {
        /// <summary>
        /// There are three state of window:
        /// 1 - Collapsed: when mouse is not in menu window
        /// 2 - Expanded: when mouse is in window
        /// 3 - Select: Expnaded + submenu windows is shown
        /// This class displays all these states in one transparency window 
        /// The window size and location are fixed.
        /// Size and location claculated in constructor  
        /// in compliance with submenu window and menu widht.
        /// </summary>
        public class MainMenuWindow : TransparentWindow
        {
            private readonly MainMenu mainMenu;
            private Size expandedWindowSize;
            private Size selectWindowSize;
            private Size menuItemsSize;
    
            private bool isMouseIn;
    
            private Dictionary<Rectangle, SubMenuItem> positionOfSubMenuItems;
            private SelectedSubMenuItem lastSelectedSubMenuItem;
            private Dictionary<Rectangle, MenuItem> positionOfMenuItems;
            private SelectedMenuItem lastSelectedMenuItem;
    
            private readonly Brush itemTextColor;
            private readonly Font itemFont;
            private readonly Pen subMenuBorder;
            private readonly Brush subMenuBackground;
            private readonly CornerRadius submenuCornerRadius;
            private readonly Brush submenuTextColor;
            private readonly Font submenuFont;
    
            private Rectangle submenuRectangle;
     
            public MainMenuWindow(MainMenu mainMenu)
            {
                if (mainMenu == null)
                {
                    throw new ArgumentNullException();
                }
    
                this.mainMenu = mainMenu;
    
                submenuFont = new Font("Arial", 10);
                submenuCornerRadius = new CornerRadius(Constants.SubMenu.CORNER_RADIUS);
                subMenuBorder = Pens.Black;
                submenuTextColor = Brushes.Blue;
                subMenuBackground = Brushes.White;
                itemTextColor = Brushes.White;
                itemFont = new Font("Arial", 10);
    
                //Calculate window location and  windows size 
                //in compliance with submenu window and menu widht
                Border = null;
                Size = SelectWindowSize;
                Location = new Point(mainMenu.Position.X,
                                     mainMenu.Position.Y - Size.Height + mainMenu.Size.Height);
               
                MouseEnter += OnMouseEnter;
                MouseLeave += OnMouseLeave;
                MouseMove += OnMouseMove;
                MouseUp += OnMouseClick;
    
            }
    
            
            #region Mouse handlers
            void OnMouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                if (LastSelectedSubMenuItem != null && 
                    LastSelectedSubMenuItem.Rectangle.Contains(e.Location))
                {
                    RaiseSelectMenuClick(new SelectMenuEventArgs(
                      LastSelectedMenuItem.MenuItem,LastSelectedSubMenuItem.SubItem));
                }
            }
    
            void OnMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                Rectangle selectedRect = Rectangle.Empty;
                if (positionOfMenuItems == null) return;
    
                foreach (KeyValuePair<Rectangle, MenuItem> item in positionOfMenuItems)
                {
                    if (item.Key.Contains(e.Location))
                    {
                        selectedRect = item.Key;
                        break;
                    }
                }
    
                if (selectedRect == Rectangle.Empty)
                {
                    if (!submenuRectangle.Contains(e.Location))
                    {
                        LastSelectedMenuItem = null;
                        Invalidate();
                    }
                    else
                    {
                        if (positionOfSubMenuItems == null) return;
    
    
                        Rectangle selectedSubItemRect = Rectangle.Empty;
                        foreach (KeyValuePair<Rectangle, 
                                 SubMenuItem> item in positionOfSubMenuItems)
                        {
                            if (item.Key.Contains(e.Location))
                            {
                                selectedSubItemRect = item.Key;
                                break;
                            }
                        }
    
                        if (selectedSubItemRect != Rectangle.Empty)
                        {
                            SubMenuItem subMenuItem = positionOfSubMenuItems[selectedSubItemRect];
                            if (LastSelectedSubMenuItem != 
                                  new SelectedSubMenuItem(subMenuItem, selectedSubItemRect))
                            {
                                LastSelectedSubMenuItem = 
                                  new SelectedSubMenuItem(subMenuItem, selectedSubItemRect);
                                Invalidate();
                            }
                        }
                        else
                        {
                            LastSelectedSubMenuItem = null;
                            Invalidate();
                        }
    
                    }
                    return; //No menu items with such rectangle
                }
                MenuItem mouseSelectedItem = positionOfMenuItems[selectedRect];
                SelectedMenuItem selectedMenuItem = 
                    new SelectedMenuItem(mouseSelectedItem, selectedRect);
                if (LastSelectedMenuItem == selectedMenuItem) return; //this is the same item
                LastSelectedMenuItem = selectedMenuItem;
                Invalidate();
            }
    
            void OnMouseLeave(object sender, EventArgs e)
            {
                isMouseIn = false;
                Invalidate();
            }
    
            void OnMouseEnter(object sender, EventArgs e)
            {
                isMouseIn = true;
                Invalidate();
            } 
            #endregion
    
            public IEnumerable<IPolygon> Draw(Rectangle clientRect)
            {
                return isMouseIn ? DrawExpanded(clientRect) : DrawCollapsed(clientRect);
            }
            
            private IEnumerable<IPolygon> DrawCollapsed(Rectangle clientRect)
            {
                List<IPolygon> retValue = DrawMenuRectangle(clientRect);
                return retValue;
            }
    
            private List<IPolygon> DrawMenuRectangle(Rectangle clientRect)
            {
                List<IPolygon> retValue = new List<IPolygon>();
                Rectangle rect = new Rectangle(clientRect.X,
                                               SelectWindowSize.Height - MainMenu.Size.Height,
                                               MainMenu.Size.Width,
                                               MainMenu.Size.Height);
    
                ImagePolygon menuImage = new ImagePolygon(mainMenu.Image,rect);
                retValue.Add(menuImage);
                return retValue;
            }
    
            private IEnumerable<IPolygon> DrawExpanded(Rectangle clientRect)
            {
                List<IPolygon> retValue = new List<IPolygon>();
                int drawHeight = clientRect.Height - ExpandedWinwowSize.Height + 1;
    
                bool initializeMenuItemsPosition = false;
                if (positionOfMenuItems == null)
                {
                    initializeMenuItemsPosition = true;
                    positionOfMenuItems = new Dictionary<Rectangle, MenuItem>();
                }
                
                for (int i = MainMenu.Items.Count - 1; i >= 0; --i)
                {
                    MenuItem mi = MainMenu.Items[i];
                    //calculate rectangle for menu item
                    Rectangle rect = new Rectangle(clientRect.X, drawHeight, 
                                                   Constants.MainMenu.ITEM_WIDHT,
                                                   Constants.MainMenu.ITEM_HEIGH);
    
                    ImagePolygon menuItem = new ImagePolygon(mi.ImageOff,rect);
                    retValue.Add(menuItem);
    
                    if (initializeMenuItemsPosition) positionOfMenuItems.Add(rect, mi);
                    
                    //hight light selected item
                    if (LastSelectedMenuItem != null && 
                        LastSelectedMenuItem.MenuItem == mi)
                    {
                        ImagePolygon selectedItem = 
                          new ImagePolygon(LastSelectedMenuItem.MenuItem.ImageOn, rect);
                        retValue.Add(selectedItem);
    
                        positionOfSubMenuItems = null;
    
                        if (mi.SubItems.Count > 0)
                        {
                            //Draw subitems window
                            retValue.AddRange(DrawSubMenu(clientRect));    
                        }
                    }
    
                    //Draw menu item text
                    SizeF stringSize = Global.GetStringSize(mi.Text, itemFont);
                    StringPolygon menuItemText = new StringPolygon(
                        itemTextColor,
                        itemFont,
                        mi.Text,
                        new Point((int)((rect.Width - stringSize.Width) / 2),
                                  rect.Top + 5));
                    retValue.Add(menuItemText);
                    drawHeight += Constants.MainMenu.ITEM_HEIGH;
                }
                retValue.AddRange(DrawMenuRectangle(clientRect));
                return retValue;
            }
    
            private List<IPolygon> DrawSubMenu(Rectangle clientRect)
            {
                //calculate size of submenu window and draw it
                List<IPolygon> retValue = new List<IPolygon>();
    
                int stringHeigh = (int)Global.GetStringSize(@"Place here any string " + 
                  @"that you want, we should only calculate string heigh",submenuFont).Height;
                int heigh = Constants.SubMenu.START_HEIGH_SUBMENU_ITEMS * 2 + 
                            stringHeigh * LastSelectedMenuItem.MenuItem.SubItems.Count;
    
                int y = LastSelectedMenuItem.Rectangle.Y - heigh + 
                        Constants.MainMenu.ITEM_HEIGH * 2 - 10;
    
                int widht = GetSubmenuWindowWidth(LastSelectedMenuItem.MenuItem);
    
                submenuRectangle = new Rectangle(clientRect.X + Constants.MainMenu.ITEM_WIDHT,
                                                 y,
                                                 widht,
                                                 heigh
                    );
                retValue.Add(new FillRoundRectanglePolygon(subMenuBorder, 
                   subMenuBackground, submenuRectangle, submenuCornerRadius));
                int drawHeight = Constants.SubMenu.START_HEIGH_SUBMENU_ITEMS;
                positionOfSubMenuItems = new Dictionary<Rectangle, SubMenuItem>();
                foreach (SubMenuItem subitem in LastSelectedMenuItem.MenuItem.SubItems)
                {
                    SizeF stringSize = Global.GetStringSize(subitem.Text, submenuFont);
                    Rectangle rect = new Rectangle(new Point(submenuRectangle.Left + 
                      Constants.SubMenu.START_WIDTH_SUBMENU_ITEMS, 
                      submenuRectangle.Top + drawHeight),
                      new Size((int)stringSize.Width,(int)stringSize.Height));
                    positionOfSubMenuItems.Add(rect, subitem);
                    IPolygon subItemText = LastSelectedSubMenuItem != null && 
                         LastSelectedSubMenuItem.SubItem == subitem
                         ? (IPolygon)(new UnderlineStringPolygon(submenuTextColor, submenuFont, 
                                                                 subitem.Text, rect.Location))
                               : new StringPolygon(submenuTextColor, submenuFont, subitem.Text,
                                                   rect.Location);
                    retValue.Add(subItemText);
                    drawHeight += Constants.SubMenu.DELTA_HEIGH_SUBMENU_ITEMS;
                }
                return retValue;
            }
    
            protected SelectedSubMenuItem LastSelectedSubMenuItem
            {
                get { return lastSelectedSubMenuItem; }
                set { lastSelectedSubMenuItem = value; }
            }
    
    
            protected SelectedMenuItem LastSelectedMenuItem
            {
                get { return lastSelectedMenuItem; }
                set { lastSelectedMenuItem = value; }
            }
    
            /// <summary>
            /// Gets expanded menu size
            /// </summary>
            protected Size ExpandedWinwowSize
            {
                get
                {
                    if (expandedWindowSize == Size.Empty)
                    {
                        expandedWindowSize = new Size();
                        expandedWindowSize.Width = MenuItemsSize.Width > mainMenu.Size.Width ? 
                                                   MenuItemsSize.Width : mainMenu.Size.Width;
                        expandedWindowSize.Height = MenuItemsSize.Height + mainMenu.Size.Height;
                    }
                    return expandedWindowSize;
                }
            }
    
            /// <summary>
            /// Gets whole window size
            /// </summary>
            protected Size SelectWindowSize
            {
                get
                {
                    if (selectWindowSize == Size.Empty)
                    {
                        int maxWidht = 0;
                        foreach (MenuItem menuItem in mainMenu.Items)
                        {
                            int widht = GetSubmenuWindowWidth(menuItem);
                            if (maxWidht < widht)
                            {
                                maxWidht = widht;
                            }
                        }
    
                        selectWindowSize = new Size();
                        selectWindowSize.Width = 
                          ExpandedWinwowSize.Width + maxWidht + (int)subMenuBorder.Width;
                        selectWindowSize.Height = ExpandedWinwowSize.Height + 
                          Constants.SubMenu.MAX_HEIGH - Constants.MainMenu.ITEM_HEIGH + 2;
                    }
                    return selectWindowSize;
                }
            }
    
            protected int GetSubmenuWindowWidth(MenuItem menuItem)
            {
                int maxWidht = 0;
                foreach (SubMenuItem item in menuItem.SubItems)
                {
                    SizeF stringSize = Global.GetStringSize(item.Text, submenuFont);
                    if (maxWidht < stringSize.Width)
                    {
                        maxWidht = (int)stringSize.Width;
                    }
                }
    
                maxWidht += 2*Constants.SubMenu.START_WIDTH_SUBMENU_ITEMS;
    
                if (maxWidht < Constants.SubMenu.MIN_WIDHT)
                    maxWidht = Constants.SubMenu.MIN_WIDHT;
                return maxWidht;
            }
    
            /// <summary>
            /// Gets menu items size (without menu button)
            /// </summary>
            protected Size MenuItemsSize
            {
                get
                {
                    if (menuItemsSize == Size.Empty)
                    {
                        menuItemsSize = new Size();
                        menuItemsSize.Width = Constants.MainMenu.ITEM_WIDHT;
                        menuItemsSize.Height = 
                          mainMenu.Items.Count*Constants.MainMenu.ITEM_HEIGH;
                    }
                    return menuItemsSize;
                }
            }
    
            protected MainMenu MainMenu
            {
                get { return mainMenu; }
            }
    
            protected override List<IPolygon> DrawPolygons(Rectangle clientRect)
            {
                List<IPolygon> polygons = 
                  new List<IPolygon>(base.DrawPolygons(clientRect));
                polygons.AddRange(Draw(clientRect));
                return polygons;
            }
    
            public event SelectMenuEventHandler SelectMenuClick;
            protected void RaiseSelectMenuClick(SelectMenuEventArgs e)
            {
                if (SelectMenuClick != null)
                {
                    SelectMenuClick(this, e);
                }
            }
        }
    }

    本文转载于:http://www.diyabc.com/frontweb/news7056.html

  • 相关阅读:
    Java中Volatile关键字详解
    java hashmap&concurrentHashmap源理
    java CAS和AQS
    jvm内存模型
    springAop源码分析
    一个项目设置两个git地址,并最终实现一次性同时推送到到两个git地址上的方法总结
    H5实现横向滚动的方法总结
    tab吸顶的神奇-- css粘性属性
    H5制作显示轮播图的方法Swiper
    微信H5中禁止分享好友及分享到朋友圈的方法
  • 原文地址:https://www.cnblogs.com/Dincat/p/13467470.html
Copyright © 2011-2022 走看看