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

  • 相关阅读:
    PAT 解题报告 1009. Product of Polynomials (25)
    PAT 解题报告 1007. Maximum Subsequence Sum (25)
    PAT 解题报告 1003. Emergency (25)
    PAT 解题报告 1004. Counting Leaves (30)
    【转】DataSource高级应用
    tomcat下jndi配置
    java中DriverManager跟DataSource获取getConnection有什么不同?
    理解JDBC和JNDI
    JDBC
    Dive into python 实例学python (2) —— 自省,apihelper
  • 原文地址:https://www.cnblogs.com/Dincat/p/13467470.html
Copyright © 2011-2022 走看看