Hittest transparency for an entire form - c#

Is it possible for the entire bounds of a form to be hittest transparent without adjusting the visibility of the form?
I am using a user32 api call to WindowFromPoint in order to find the control under the mouse. In some circumstances I would like to ignore the existance of a child form that floats in front of the main form (or another child form), but keep this form to ignore visible.
Setting the Opacity of the form to ignore to 0 will successfully cause the hittest to pass straight through it, but the form obviously is invisible, and I'd prefer it to remain visible.
Since this child form can have any arbitrary number of controls on it, is there a way for this form intercept all WM_NCHITTEST messages going to child controls on the form so that I can return hittest transparency for each control? The controls contained on the form are arbitrary so I am unable to modify them internally.

You are looking for the WS_EX_TRANSPARENT Windows Style.
This answer gives a good-enough explanation.

Related

Modify docking layout in WinForms

I have a SplitContainer on my form that has its Dock property set to Fill. It contains several child controls, many of which have event handlers attached to them. Later I decide to put a StatusStrip at the bottom of my form. Guess what, I can't set the StatusStrip to dock to the bottom of my form. The SplitContainer will continue to Fill the entire form. Even though the StatusStrip apparently gets docked to the bottom, it actually hides the bottom part of the SplitContainer behind it.
The only around it is to CUT the SplitContainer and then PASTE it back. Cutting the SplitContainer makes the StatusStrip the only control on my form and thus lets it capture the bottom docking. Afterwards, pasting the SplitContainer allows it to fill the remaining area. In short, docking uses First Come, First Serve method.
Now since my controls have lots of event handlers attached to them, cutting and pasting becomes a nightmare for me. Having my project in C# means I have to attach all those event handlers manually.
Is there a better work around?
This is a z-order issue between the splitter and the statusstrip. When you have a control you want to dock fill and one or more controls you want to dock top, left, right, or bottom, you have to have the fill control be the first in the z-order.
The better way is to open the Document Outline tool, select the SplitContainer and use the up or down buttons to change its z-order.
I should add that in Winforms the z-order is specified by the order in which you add controls to the Controls collection. That order determines the order the associated system controls are created, hence their z-order. Using the Document Outline tool to alter z-order simply causes the generated code to be re-ordered.

WS_EX_TRANSPARENT - What does it actually do?

In my project, I create a form with the opacity controlled by the user. If the form was fully transparent the mouse events 'fell through' (without my intervention), otherwise my form handled them.
After reading this question and overriding the CreateParams property to set the WS_EX_TRANSPARENT flag on my form, it now allows mouse events to fall through when the opacity is any value <255.
This is exactly what I want, but it concerns me that I don't understand why it works.
From what I've read, WS_EX_TRANSPARENT is meant to make the form appear transparent by 'stealing bits' from the form below it in its Paint method, therefore:
The Paint method of my form and all the controls in it should never be called, right? As WS_EX_TRANSPARENT should cause Windows to override them, so why does it affect input handling but not the drawing of my form?
The opacity should have no impact on the handling of mouse events, as if Paint is being overridden the 'local' opacity should not matter, no?
Could someone explain, what this flag really does? How does it work?
WS_EX_TRANSPARENT makes your events (like mouse clicks) fall through your window, amongst other things. Opacity is a separate concept, it instructs window manager to apply alphablending when drawing your form. Those two things are not related, but when you combine them you get the effect you need in your case.
So:
Paint method of your form is called normally as it should, opacity has nothing to do with it.
Opacity does not have anything to do with mouse events, as described in the first paragraph.
It makes the window invisible to mouse events, or -as Microsoft puts it- it doesn't obscure the windows below. I believe it doesn't actually steal pixels from the windows below, but Windows itself will probably blend those two pictures together, using the level of transparancy you supplied.
Transparent windows can be useful for showing some progress or a splash screen, but you'll have to program a way to close them, because just click the X won't work since the mouse click will pass through it.
So not only does it change the level of visual transparency, but it modifies the behaviour too. I wonder where you would have read otherwise.
[edit]
Don't Windows in C# just have an opacity property?

Usercontrol with sizable tool window

In C# WinForms I'd like to make a UserControl that mimics the look of a ToolWindow -- sizable, with room for a caption and a close button at the top right. This seems possible through overriding CreateParams(), using the relevant constants from WinUser.h, and adding custom handlers for the appropriate mouse events, but it seems like a lot of trouble for something that simple. Before I go to it, is there an easier way?
Really rather the easiest way is to just use a Form with FormBorderStyle = SizeableToolWindow. That's what it was made for. Display it with the Show(owner) overload so it is always on top of your main window. If you want to salvage the UserControl then just Dock = Fill in the form. Albeit that exposing its properties get harder to do cleanly.
Check out Weifenluo's DockPanel Suite for a windowing model that resembles Visual Studio's.
ToolWindow is a window, UserControl is a control that sits INSIDE a window (like a text box, button, etc.). If you want to have a UserControl that is sizable and has a caption and a close button, I think you'll have to create a caption bar and close button and size grips as parts of the control itself.
You'd need to remove the control from its parent on "close", and resize the control in its parent on "resizing" with size grips.

Form looks like a balloon

I am just trying to create a form control in winform in .net with custom shaped of balloon shape.
There is need of a balloon tooltip which is transparent and I can put buttons on tooltip,but
tooltip in .net does not provide facality that we can put the buttons on tooltip control so
I want to make a form control looks like a balloon tooltip and so I can put buttons on that form looking like a tooltip.But I cannot show window form control look like a balloon tooltip.
So what should I do??
I tried in one way that I create a image in powerpoint of balloon shape and set it to as background image of form property.But there is no solution with that.
The Control class supports a BackColor with an alpha < 255, it is automatic. It asks the Parent to draw itself to produce the background of the control, then draws itself on top of that. However, you'll want a top-level window for a balloon. That's a window type that can arbitrarily overlap another window and isn't confined by the client area of an underlying window. It has no Parent. A ToolTip is such a window.
The only control available in Windows Forms that can be an top-level window is a Form. Problem is: the transparency trick no longer works. Since a top-level window doesn't have a Parent, there isn't any obvious window to ask to draw the background. It could be many windows, belonging to other processes. You can get transparency in a Form with its TransparencyKey property. But that's a "hard" transparency, equivalent to an alpha of 0. You probably want a soft one. Another nasty problem is that drawing anti-aliased (ClearType) text no longer works since there is no reliable background pixel color anymore.
Long story short: you can't make this work well unless you confine the balloon to the client area of a form. A control, not a form.
You can try to hook on the Paint event of the control and draw the Visual of the button there.

Transparent Panel on top of another normal panel

I want to show a transparent panel on top of another panel, both the panels have child controls like labels, text boxes etc. Transparency works fine if the transparent panel is child control of the other panel but if not then the label and text box of the normal panel appears on top of the transparent panel. Transparency for rest of the area works fine.
Any ideas ???
I have tried bring the transparent panel to the front but did not help. Perhaps I need to specify the order in which the controls should be drawn ?? If yes how do I do that ?
Interestingly if I move the application below the task bar and bring it up. It achives the right result. ( Reprinting resolves the issue !! but why??). However when I minimize it and restore it does not fix it!
Thanks,
Transparency in Windows.Forms is implemented by relational hierarchy rather than visual hierarchy. When a transparent control is painted, .NET basically calls up the Parent tree asking each parent control to paint itself, then paints the actual control content itself.
Two siblings in the same control will paint over each other.
So to answer the question, the topmost panel/control needs to be a child of the control you want to paint on top of.
If you want a transparent control that won't obscure its siblings, according to Bob Powell you can do it by overriding the CreateParams method to add true transparency. Read the link for a full description.
If all your panels/labels/controls are part of a single UserControl then you are probably right that you just need to set the Z-order (the front-to-back order). You can do this using the Document Outline inside of Visual Studio's Designer under View > Other Windows > Document Outline.
If you're doing it programatically then you can play around with calling Control.BringToFront() or Control.SendToBack() to change their z-order. One possible way to do this is like (assuming ctl1 is intended to be at the back and ctl4 is intended to be front-mode.
SuspendLayout()
ctl1.BringToFront()
ctl2.BringToFront() ' Bring ctl2 in front of ctl1
ctl3.BringToFront() ' 3 in front of 2 (and in turn 1)
ctl4.BringToFront() ' 4 in front of the rest
ResumeLayout()
The Suspend/Resume Layout calls prevent the UI from updating while you rearrange things.

Categories