/// <summary> /// Draws a top-level menu item. /// </summary> /// <param name="drawItemState">A DrawItemEventArgs that contains the event data.</param> private void DrawMainMenuItem(DrawItemEventArgs ea) { // record state DrawItemState drawItemState = ea.State; // Create graphics context on the offscreen bitmap and set the bounds for painting. //Graphics graphics = Graphics.FromImage(offscreenBitmap); Graphics graphics = ea.Graphics; BidiGraphics g = new BidiGraphics(graphics, new Size(GetMainMenu().GetForm().Width, 0)); //Rectangle bounds = new Rectangle(0, 0, offscreenBitmap.Width, offscreenBitmap.Height); Rectangle bounds = ea.Bounds; // get reference to colorized resources ColorizedResources cres = ColorizedResources.Instance; // Fill the menu item with the correct color Form containingForm = GetMainMenu().GetForm(); if ((containingForm is IMainMenuBackgroundPainter)) { (containingForm as IMainMenuBackgroundPainter).PaintBackground(g.Graphics, g.TranslateRectangle(ea.Bounds)); } else { g.FillRectangle(SystemBrushes.Control, bounds); } // Draw the hotlight or selection rectangle. if ((drawItemState & DrawItemState.HotLight) != 0 || (drawItemState & DrawItemState.Selected) != 0) { // Cheat some for the first top-level menu item. Provide a bit of "air" at the // left of the "HotLight" rectangle so it doesn't run into the frame. int xOffset = (Index == 0) ? 1 : 0; // Calculate the hotlight rectangle. Rectangle hotlightRectangle = new Rectangle(bounds.X + xOffset, bounds.Y + 1, bounds.Width - xOffset - 1, bounds.Height - 1); DrawHotlight(g, cres.MainMenuHighlightColor, hotlightRectangle, !cres.CustomMainMenuPainting); } // Calculate the text area rectangle. This area excludes an area at the right // edge of the menu item where the system draws the cascade indicator. It would // have been better if MenuItem let us draw the indicator (we did say "OwnerDraw" // after all), but this is just how it works. Rectangle textAreaRectangle = new Rectangle(bounds.X, bounds.Y + 1, bounds.Width, bounds.Height); // Determine which StringFormat to use when drawing the menu item text. TextFormatFlags textFormat; if ((drawItemState & DrawItemState.NoAccelerator) != 0) textFormat = mainMenuItemTextNoHotKeyStringFormat; else textFormat = mainMenuItemTextHotKeyStringFormat; //DisplayHelper.FixupGdiPlusLineCentering(graphics, menuFont, MenuText(), ref stringFormat, ref textAreaRectangle); // Draw the shortcut and the menu text. TextRenderer.DrawText(g.Graphics, MenuText(), menuFont, textAreaRectangle, cres.MainMenuTextColor, textFormat); // We're finished with the double buffered painting. Dispose of the graphics context // and draw the offscreen image. Cache the offscreen bitmap, though. graphics.Dispose(); }
private void DrawTabFace(BidiGraphics g, Color bgColor, Color borderColor, Color lineColor) { Rectangle borderRect = ClientRectangle; if (!Selected) borderRect.Height -= 2; // Remove one pixel for the bottom edge of the tab. // We don't want it filled in by the face color as // that would cause the corner pixels of the tab // to be filled in. borderRect.Height -= 1; using (Brush b = new SolidBrush(bgColor)) g.Graphics.FillRectangle(b, borderRect); borderRect.Width -= 1; if (Selected) borderRect.Y -= 1; else { borderRect.Height -= 1; } if (clipLeftBorder) { borderRect.X -= 1; borderRect.Width += 1; } if (clipRightBorder) borderRect.Width += 1; Region clip = g.Graphics.Clip; clip.Exclude(g.TranslateRectangle(new Rectangle(borderRect.X, borderRect.Bottom, 1, 1))); clip.Exclude(g.TranslateRectangle(new Rectangle(borderRect.Right, borderRect.Bottom, 1, 1))); g.Graphics.Clip = clip; using (Pen p = new Pen(borderColor)) g.DrawRectangle(p, borderRect); if (!Selected) using (Pen p = new Pen(lineColor)) g.DrawLine(p, 0, 0, ClientSize.Width, 0); }