1

I've created a custom button control. Basically one button-rectangle, but with two areas inside the rectangle that have a different behavior. For that reason I want to draw the hot and pressed state ONLY for the specific areas, not the hole button.

My current approach is drawing the basic-button using ButtonRenderer.DrawButton(...) with an emtpy text, draw the hot or pressed state if required and finally drawing the text. So far so good, but how do I get the (gradient) colors for the hot/pressed state?

I've tried SystemColors, KnownColors and VisualStyleRenderer.GetColor(ColorProperty.XYZ) but none of them seems to match? How can I read those colors from the host system?

EDIT:
Sample picture below:

enter image description here

I want the colors of both the hot and the pressed button-state - (light) blue in case of this win7 screenshot. If you zoom in you can see that a slight color gradient in both the upper and the lower half is used.

The last button shows what I want to accomplish.

Sure, I could extract the colors from the screenshots and hardcode them or use images like suggested, but that would work only for this specific system, wouldn't it?

Michael
  • 1,931
  • 2
  • 8
  • 22
  • have you thought about making an independent user control? that will be rich in features! – Amit Jun 04 '18 at 11:26
  • @Amit what would be the benefit inheriting from `UserControl` instead of `Button`? And how would that solve my color problem? – Michael Jun 04 '18 at 12:48
  • you can have multiple layer of background colors (images) as you can add multiple container. that way you can have that effect of hot key on click or other action. making custom control is always tricky but sometimes it gives the best result – Amit Jun 04 '18 at 13:02
  • What do you mean by gradient colors? Can you elaborate more and add some description and pictures about desired behavior? – Reza Aghaei Jun 04 '18 at 16:18
  • @RezaAghaei example and more explanation added – Michael Jun 05 '18 at 04:53
  • [`ButtonRenderer.DrawButton()`](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/ButtonRenderer.cs,8d8bea73b4eb0182) calls [visualStyleRenderer.DrawBackground](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/ButtonRenderer.cs,95). You can see that the class [here](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/VisualStyles/VisualStyleRenderer.cs,271) uses the current Theme to read the button state color, referencing the Part and Bounds of the control to paint. – Jimi Jun 05 '18 at 08:33
  • See also this SO answer: [How do I draw a button with a nonstandard BackColor?](https://stackoverflow.com/questions/2296155/how-do-i-draw-a-button-with-a-nonstandard-backcolor) which references [ButtonStandardAdapter](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/ButtonInternal/ButtonStandardAdapter.cs,b8bb1ecc1e29e447,references) [`PaintThemedButtonBackground()`](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/ButtonInternal/ButtonStandardAdapter.cs,60) method. – Jimi Jun 05 '18 at 08:37

1 Answers1

0

Thanks for your answers, Jimi.

According to the accepted answer of your linked SO-question I checked ButtonBaseAdapter and ButtonStandardAdapter. As you also mentioned, ButtonRenderer.DrawButton calls VisualStyleRenderer.DrawBackground which calls the native API UxTheme.DrawThemedBackground to draw the button - the color determination happens inside. This native API call also draws the button-border and thats the reason why I can't use it.

But I was able to solve my Problem, an unusual way, but it works.

I render both relevant states (hot and pressed) to a bitmap and extract the colors using .GetPixel. In OnPaint I create LinearGradientBrush-instances from the extracted colors and draw the hot/pressed effect over the specific areas of the normal button.

It's not the exact same behavior like a normal button (for both states the border color also changes), but I think it would look really strange if I change the border color only for a part of the button (where the hot/pressed effect is displayed) to match the normal button behavior...

If no other answers or solutions come up I'll mark this post in a few days as an answer...

Michael
  • 1,931
  • 2
  • 8
  • 22