Jump to content

Fix for ToolStrip Arrows and Checkmarks in High DPI.


midora

Recommended Posts

Did a small fix for the high dpi issue regarding the arrow and checkmark symbols in ToolStrip.

Maybe it is usefull for someone else.

        class OptionToolStripMenuRenderer
            : ToolStripProfessionalRenderer
        {
            protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
            {
                Graphics g = e.Graphics;
                Rectangle dropDownRect = e.ArrowRectangle;
                using (Brush brush = new SolidBrush(e.ArrowColor))
                {

                    Point middle = new Point(dropDownRect.Left + dropDownRect.Width / 2, dropDownRect.Top + dropDownRect.Height / 2);

                    Point[] arrow;

                    int hor = Ui.ScaleWidth(2);
                    int ver = Ui.ScaleHeight(2);

                    switch (e.Direction)
                    {
                        case ArrowDirection.Up:
                            
                            arrow = new Point[] {
                                     new Point(middle.X - hor, middle.Y + 1),
                                     new Point(middle.X + hor + 1, middle.Y + 1),
                                     new Point(middle.X, middle.Y - ver)};

                            break;
                        case ArrowDirection.Left:
                            arrow = new Point[] {
                                     new Point(middle.X + hor, middle.Y - 2 * ver),
                                     new Point(middle.X + hor, middle.Y + 2 * ver),
                                     new Point(middle.X - hor, middle.Y)};

                            break;
                        case ArrowDirection.Right:
                            arrow = new Point[] {
                                     new Point(middle.X - hor, middle.Y - 2 * ver),
                                     new Point(middle.X - hor, middle.Y + 2 * ver),
                                     new Point(middle.X + hor, middle.Y)};

                            break;
                        case ArrowDirection.Down:
                        default:
                            arrow = new Point[] {
                                 new Point(middle.X - hor, middle.Y - 1),
                                 new Point(middle.X + hor + 1, middle.Y - 1),
                                 new Point(middle.X, middle.Y + ver) };
                            break;
                    }
                    g.FillPolygon(brush, arrow);
                }
            }

            protected override void OnRenderItemCheck(ToolStripItemImageRenderEventArgs e)
            {
                Rectangle imageRect = e.ImageRectangle;
                Image image = e.Image;
 
                if (imageRect != Rectangle.Empty && image != null)
                {
                    bool disposeImage = false;

                    if (!e.Item.Enabled)
                    {
                        image = CreateDisabledImage(image);
                        disposeImage = true;
                    }

                    // Draw the checkmark background (providing no image)
                    base.OnRenderItemCheck(new ToolStripItemImageRenderEventArgs(e.Graphics, e.Item, null, e.ImageRectangle));

                    // Draw the checkmark image scaled to the image rectangle
                    e.Graphics.DrawImage(image, imageRect, new Rectangle(Point.Empty, image.Size), GraphicsUnit.Pixel);

                    if (disposeImage)
                    {
                        image.Dispose();
                    }
                }
            }
        }


Edited by midora

midoras signature.gif

Link to comment
Share on other sites

Unfortunately this fix will only work if the menu does not contain enough items to require vertical scrolling.

 

When implementing High DPI support for the example application in my 8bf host library I learned that the MenuStrip overflow scroll buttons are an internal class (ToolStripScrollButton) with static 16x16 images, so while the submenu arrows scale the overflow arrows do not.

PdnSig.png

Plugin Pack | PSFilterPdn | Content Aware Fill | G'MICPaint Shop Pro Filetype | RAW Filetype | WebP Filetype

The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait

 

Link to comment
Share on other sites

Are you talking about the up down buttons in ToolStripDropDownMenu items? You are right they are extremly small on my screen (less than a millimeter) and not usable.

 

Thanks for the "StickyLabel" hint. I solved the issue by adding an Opening handler to these DropDown menus.

        void DropDown_Opening(object sender, CancelEventArgs e)
        {
            ToolStripDropDownMenu tsddm = (ToolStripDropDownMenu)sender;

            foreach (Control control in tsddm.Controls)
            {
                // If control is of type StickyLabel (which is hosted by ToolStripScrollButton)
                if (control.GetType().Name != "StickyLabel") continue;
                Label label = control as Label;
                if (label == null) continue;

                // Scale the label image if this is not done already
                if ((label.Image != null) && (label.Tag != label.Image))
                {
                    label.Image = Ui.ScaleImage(label.Image);
                    label.Tag = label.Image;
                }
            }
        }

       item.DropDown.Opening += new CancelEventHandler(DropDown_Opening);

midoras signature.gif

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...