Is it possible to paint my child window that overflows outside its parent top-level window? I've seen combo-boxes can do this when their drop down is taller than the top-level window.
For example:
My window is a custom class with the style flags CS_HREDRAW | CS_VREDRAW. From what I understand I could use WS_EX_LAYERED? Or I could make the window taller and transparent to give the appearance of the window overflowing but those transparent areas either side of the red overflow are going to be Windows Message 'blackholes' that would really annoy the user if they click there expecting to be interacting with a different top-level window.
Is it possible to paint my child window that overflows outside its parent top-level window?
No. By definition, a child window
[...] is confined to the client area of its parent window.
But that's not what you need anyway. If you want to mimic the behavior of a combo box control, you need to create an owned pop-up window instead (see Owned Windows).
Related
I am trying to write an application that uses nested controls plus a Control.Paint event handler to draw a custom border. See the image below:
Notice how the "About ChocoTester" and "View version..." labels, as well as the PictureBox containing the icon, also draw the border (and, presumably, the background color as well, although that is not as immediately visible). I have added a Control.Paint event handler to the outermost box only. However, for some reason, the child controls are inheriting the Paint event code of the parent. I have never seen Windows Forms do this before until I started work on this project.
Note that the child controls have a BackColor of Transparent. This may or may not have anything to do with the symptoms described above. Also note that any child control of another control where the parent has a custom Paint event exhibits this behavior, be they standard Label instances or Panels with custom drawing code of their own.
Here is a sample Panel.Paint handler that exhibits this problem:
Rectangle r = e.ClipRectangle; r.Inflate(-1, -1);
e.Graphics.FillRectangle(Brushes.AliceBlue, r);
e.Graphics.DrawRectangle(Pens.DarkBlue, r);
I actually solved this on my own end. The problem was that I was using the PaintEventArgs.ClipRectangle to size the drawing. If I construct a Rectangle manually using Control.Width and Control.Height, and use that to draw to the screen, the behavior discussed above goes away.
In Winforms if the MDI child window is maximized it doesn't receive ResizeBegin (or ResizeEnd) events. It does receive Resize events - why the distinction? If the child isn't maximized it does get ResizeBegin/End events. Is there a nice way around this? There are plenty of ugly ways: calling directly from the MDI container ResizeBegin event to the child for example.
The ResizeBegin/End events are generated when the user starts and stops resizing a window. Implemented by a modal loop inside Windows itself, it keeps the window edge following the mouse cursor when the user moves it. ResizeBegin when he clicks a window edge, ResizeEnd when he releases the mouse button.
Clearly no user is involved when you change the Size or ClientSize property of an MDI child window in your code. So no Begin or End, just the Resize event. And just one Resize event trigger, there's no constant train of them like there will be when the user uses the mouse to resize. Which otherwise explains why Begin/End is important, if you do a lot of work in your Resize event handler then you'll bog down the UI pretty heavily. Common with automatic layout, the visible artifacts are not pretty.
If you really have to then you can simply generate the event yourself. Call OnResizeBegin() before, OnResizeEnd() after you change the window's Client/Size property value. That code needs to live inside the window you resize to get the correct event triggered. Pretty unlikely you should be doing this btw. Do beware that MDI automatically resizes an maximized MDI child window, it of course cannot be maximized anymore when you activate another one. You can't wrap that with OnResizeBegin/End() calls.
I'm writing a WPF application to control an industrial process. The main window class spawns child windows, each to control a separate piece of equipment. These child windows can be dragged but not resized.
The child windows are owned by the parent so they stay on top, but the problem this creates is that they can be dragged on top of the main window menu, which is considered aesthetically unacceptable by my client.
It would be OK if the child window goes under the menu or if it goes right up to the menu and stops but it's not OK to obscure the main menu. How can I achieve this? Can it be done within WPF without going into Win32 and unmanaged code?
Thanks in advance.
You could try to set Topmost=True on the parent window, and make it only contain the main menu. So, you'd basically have one window for the main menu and a couple of others for everything else. Or, if you can't do that, you can create a main menu window with Topmost=True as a child window of your parent, and move both of them together whenever one of them changes position.
I have WPF application with main window. I want to create child WPF window which always must be above ONLY parent window. If I set TopMost property for new window then window is above ALL nonTopMost windows on desktop. It's not what I want.
Set the Owner property of the child window so that it refers to the parent window.
child.Owner = parent;
Depending on the nature of the window, I often use a "Fake" window that is really just a layer in the parent along with a partailly transparent grey layer between that makes the parent look ghosted while the child is active. You can then keep the child window set to collapsed until it is needed.
I am trying to change the color of static controls that are child of a tab control. Now the thing is that, when I try to change it using WM_CTLCOLORSTATIC, it does not work.
When I define the main window as static's parent, it works fine. But how can I change the color while they are child of tab?
As David Heffernan says, when Visual Styles (themes) are enabled, the tab control has a fancy gradient-filled background. Since this only works when the child controls of the tab page have the same background, controls parented by tab controls actually have their backgrounds drawn by the parent.
Yep, it does not work with Themes. How do I make it work?
You don't, that's the whole point of Visual Styles. If you want this kind of fine-grained control over appearance, you should disable visual styles for your particular controls.
You can use the SetWindowTheme function to do this. Pass a handle to your control window as the first parameter and an empty string for the last two parameters:
SetWindowTheme(hwndCtrl, L" ", L" ");
Of course, you'll have to include uxtheme.h in order to call this function, and link to uxtheme.lib.
If you want your application to continue working on versions of Windows prior to XP (when the theming APIs were introduced), then you'll need to either use delay-loading or LoadLibrary and GetProcAddress to call the function dynamically.
You could also try calling the EnableThemeDialogTexture function and specifying the ETDT_DISABLE flag to disable the background texturing applied to tab dialogs.
Child controls send WM_CTLCOLORSTATIC to their parent. If you want the tab control to be parent of the static control, you need to subclass the tab control and handle WM_CTLCOLORSTATIC in there