I am looking to create a custom shaped form in c#.
I have a background image (png) that has is transparent in some places.
Is there anyway of making the form shape to be the shape of this image instead of the 'usual' rectangle?
I am only asking this as I wish to design a custom skin for my PC (a bit like rainmeter/rocketdock combined, but in a 'compressed' way).
I have heard of using a 'transparency key', but this would remove a colour from the background (I will be using a colour picker in a later stage, and so if the user chose that specific colour, it would not show).
As always, any help would be much appreciated.
The TransparencyKey approach, discussed here on MSDN is the simplest way to do this. You set your form's
BackgroundImage
to an image mask. The image mask has the regions to be transparent filled with a certain color—fuchsia is a popular choice, since no one actually uses this horrible color. Then you set your form'sTransparencyKey
property to this color, and it is essentially masked out, rendering those portions as transparent.But I guess in a color picker, you want fuchsia to be available as an option, even if no one ever selects it. So you'll have to create custom-shaped forms the other way—by setting a custom region. Basically, you create a
Region
object (which is basically just a polygon) to describe the desired shape of your form, and then assign that to the form'sRegion
property.Do note that you are changing the shape of the entire window when you do this, not just the client area, so your design needs to account for that. Also, regions cannot be anti-aliased, so the result tends to be pretty ugly if you're using a shape that does not have straight edges.
And another caveat…I strongly recommend not doing this. It takes quite a bit of work to get it right, and even once you get finished, the result is usually gaudy and user-hostile. Even when everything goes just right, you'll end up with something that looks like this—and no one wants that. Users are quite accustomed to boring old rectangular application windows. Applications shouldn't try to be exact digital replicas of real-world widgets. It seems like that would make them intuitive or easy to use, but it really doesn't. The key to good design is identifying the user's mental model for your application and figuring out a good way of meshing that with the standards set by your target windowing environment.
I noticed this tab still open and had a few spare moments, so I tried to bang out a quick sample. I made the "form" consist of two randomly-sized circles, just to emphasize the custom shape effect and the transparency—don't read anything into the design or get any crazy ideas! Here's what I came up with:
Here it is running on Windows XP and 7, side-by-side:
Whew! It does work, but it's a long way from complete. There are lots of little things that still need to be done. For example:
DrawCaptionButton
method, but you need to either force a redraw when one of the buttons is clicked, or do the repaint directly on the form right then and there.ControlPaint
class; it was written before Visual Styles were invented. Implementing support for this will be a lot more work, but there is a WinForms wrapper. You will have to make sure that you write fallback code to handle the case where Visual Styles are disabled, too.WM_NCLBUTTONUP
(instead ofWM_NCLBUTTONDOWN
), you have to double-click the caption buttons to make them work. This is because the non-client area is capturing the mouse. I'm sure there's a solution, but I ran out of patience before I discovered what it was.HTTRANSPARENT
in response to theWM_NCHITTEST
message, so the message doesn't get passed on to the parent form. You can subclassLabel
to do so and use your subclass instead.You can also see that, like I cautioned above, the circular border is not anti-aliased, so it looks jagged. Unfortunately, that is unfixable.