Adding components to a transparent form - c#

I used this code from the code project in order to display a .png image (with transparency). At line 87 I tried to add a label in which I succeeded but somehow It won't appear on the form. I tried Refresh, Invalidate but none of them worked. Maybe someone can point me into the right direction.

I think, since you're using UpdateLayeredWindow the "normal" painting mechanism is disabled, i.e. no WM_PAINT messages are sent to the window, and the WinForms library has no chance to render the Label Controls.
I found this article about using layered windows on MSDN stating:
Note that when using UpdateLayeredWindow the application doesn't need to respond to WM_PAINT or other painting messages, because it has already provided the visual representation for the window and the system will take care of storing that image, composing it, and rendering it on the screen. UpdateLayeredWindow is quite powerful, but it often requires modifying the way an existing Win32 application draws.
So I'm afraid that WinForms isn't able to work together with your approach. Even if it would, you would likely get unpleasant results since "real" transparency is not easily done with winforms (i.e. the labels wouldn't show up transparently but would be drawn the parent forms background color)

Related

How to have different opacity for multiple controls?

I have a problem with the opacity of some controls.
So I set the form opacity to 0.3, when the form is loaded, and the problem is that it makes the other controls as tranparent as the form. Here is the code.
private void Form1_Load(object sender, EventArgs e)
{
this.Opacity = 0.3;
}
By doing this, all my controls are as transparent as the form. Is there any way to have different opacity for the controls inside the form ? I don't want the other to be transparent at all.
My first recommandation would be to avoid that. Having a semi-transparent background with opaque controls will look somewhat weird. Instead, consider changing the opacity when the form is active say from 0.3 to 0.7 so that it is easier to read.
Also another problem if some controls are opaque and the background is almost transparent, then your UI might not work well on some background. For example, if the background is really dark, then dark text (control) will be hard to see. If the background is white, then white controls like edit box would be the same color as the background.
You can get a few idea from other people comments. Even though some comment are for WPF, you might be able to take some idea for WinForms. And if you don't get the expected result, you might also consider using WPF for that part of the UI.
Having said that, a possible workaround to get what you want is to create two top-level windows at the same position (and move/resize them as appropriate). That way, you can have one window with a transparency key and the desired background for opaque area that will be used to have opaque and semi-transparent area. The other window will use the opacity so that it would be semi-transparent. This is the window that will contain your UI controls (and the one that would be on the top).
I have used that technic in the past to have a semi-transparent client area with a fully opaque frame in one application where I want to be able to see through client area (adjustable opacity) so that I could "draw" in my window using the image in another application as a reference.
Another comment is that you might need actual control with windows handle and direct Win32 API access for some customization that are not available in WinForms and/or WPF. In my application, I was handling activation in a way that if I click on the bottom level windows, the top-level window still appears as the active one (caption bar color). If one has no standard caption bar (either the frame is custom or no frame at all), then you would not have that problem.
As suggested by some links in the comment section, it might also be possible to get what you want using a single top-level windows. I have not tried that. In fact, when I try the above solution, I think that my application was still supported on Windows XP and as such you are more limited in options and the behavior is somewhat different essentially because XP more or less write directly to screen while Vista and later use bitmaps (buffers) for each windows.
I have also used combined transparency key and opacity for splash screen (on a single window) and it works on most system but sometime I got black background instead of desired background on some system (probably some XP machine with specific configuration).

Windows Message Pump pausing when clicking a Scrollbar control

I've set my XNA game's DeviceWindowHandle to a PictureBox with Dock set to Fill on a Form, effectively providing the powerful array of .NET controls to my game. I'm aware this comes with a handful of niggly things to clean up, one of which is my problem explained below.
I'm trying to figure out if it's possible to avoid the WM pump pausing when doing things like clicking to drag a ScrollBar control, or right clicking in a TextBox control, this ultimately causes my renderSurface (the dock filled pictureBox) to stop being drawn to temporarily. Information on this seems sparse, though it's likely i'm not looking in the right places.
I could tie in some custom drawn XNA ScrollBars and set ShortcutsEnabled on the .NET TextBox's to false, but i would rather fix the root of this problem if possible.
Thanks in advance.
XNA works by having a game loop. WinForms and native c++ Windows GUI apps work by having a message pump. Sounds like you have fused the two somehow.
Perhaps you need to call the base Game.Update() somehow from within your forms's Control.WndProc

WPF - Resizing chromeless windows using attached behaviors,..Any suggestions?

Who fancies a challenge?
I'm currently working on the ControlTemplate for a chromeless Window which will be a part of a reusable theme assembly. I want the behaviors for moving, closing, minimizing and restoring to be implicit so I've written attached behaviors for this functionality which I've then included in the template.
Now,..I've come to resizing and I've come to a junction. For better or worse I'm handling the mouse move in the behavior and finding whether the cursor is inside the resizing 'zones'. I'm far enough to change the cursor appropriately but now I've gotten to actually resizing the window there are three options I've come across.
I could hand-ball the affair and adjust the Left & Top and Width & Height as needed. This is the simplest option and is easily achievable using attached behaviors but it seems like moderately heavy lifting and I understand that WPF will continue to render as the window is adjusted causing flickering,..which sucks.
The second option is to get a message hook and listen for WM_NCHITTEST and the like but the solutions I've found so far involve me sub-classing Window and I don't want to force consumers of the theme to use any controls that aren't framework provided.
The last option is to somehow draw a rectangle on the screen showing the are the Window will take up as the mouse is dragged and then resize on MouseUp,..which seems doable but it's not something I've done before so some pointers on that would be cool.
So,..what should I do? The Win32 route seems like my best option so far but I'd rather not if someone has a 'purer' solution that works. I'm happy to get suggestions with option 3 and anything right up to .Net 4 in case some dynamic magic might be possible.
Thanks in advance.

Winforms WPF Interop - Wpf controls rendered inactive

I have a similar problem to this question regarding painting of wpf controls
The application I work on is a rather large Windows forms threaded application with several wpf user controls throughout the application. The problem occurs in a plugin of the application where a third party c++ library is called on a separate thread, WndProc is overriden to get the progress updates from the third party library. I have yet to determine the exact scenario that causes the problem but similar to the above mentioned question, after a few runs the wpf controls fails to paint and update.
Setting the width of the elementhosts does solve the painting issue for most of the controls but after this all the wpf controls in the application seems to become 'unresponsive' - visually... the progress bars fails to show progress (though the value does change), scrollbars does not respond, selecting an item in the listview does not highlight it(it does get highlighted after resizing and it does actually get selected - you just can see it is selected) the treeviews does not paint after the resizing, it only shows a black background where the treeview should be (though when I click on the items where they should be in the treeview, the events does get trigerred)
I know I should probably find out the root of the problems that causes this first (its hapening rather randomely and is hard to trap) - allthough putting a breakpoint in the WndProc method does seem to cause it to fail on a regualar base...
What I was hoping for is a way to 'reactivate'/refresh all the other controls throughout the application... I am an intermediate wpf, c# developer and dont really know enough yet about the messaging and events that happens in the background to use them effectively ... my thought is that some event or message that tells wpf to redraw must be broken or interrupted or something - how can I determine what is broken and maybe reactivate it??
Any advice will be much appreciated...
Thank You
It could be that the event that causes the WPF control graph render is never being processed because of that WndProc override.
Since you are inter-oping with WinForms, you can force the events to process by performing a call to Application.DoEvents(); somewhere. Perhaps after you update the progress bar.

Prevent controls from being redrawn in C#?

I have a form that contains a lot of runtime generated controls (image, button, panel,...), about 100 controls (I'm making a card matching game so there is a lot of controls in the form).
I place the generating code into the constructor and each time the app starts, it took about 3-5s to load all the controls completely.
If I bring another window on top and then back to my app, the controls will be redrawn again.
How can I prevent the controls from being redrawn? If you don't mind, please give me a simple example in C#.
Any help is appreciated!
I found this article that explains how to do this in .NET by calling the WIN API SET_MESSAGE function to set the WM_SETREDRAW flag for the control you do not want updated. Although you can stop certain controls from updating, are you sure you can't approach this issue by reducing the number of controls on the page? 100 Controls seems like a lot and may be an indication that you need to have multiple views.
Enjoy!
My suggestion is to use the form as a drawing surface and draw your card bitmaps directly onto the form. Its not hard to do.
You can add a handler to the form Paint event which will give you parameters with a Graphics object. Use graphics.DrawImageUnscaled to draw each card at the location you want.
This will make the app much much faster.
Preventing a control from redrawing is fairly pointless. You'll get a hole where a control was supposed to appear, your user won't have any use for that hole.
It redraws slowly simply because you have too many controls. You can only get it to redraw faster by using less controls. Or by using controls that can display multiple items in one window, like ListBox, ListView, TreeView, DataGridView.
Note that your specific issue is fixed in Vista and Windows 7. The Aero theme uses off-screen buffering for windows. Which means that windows don't need to repaint themselves anymore when they are obscured by another window. You will however still get slow redraws when the user minimizes the window and restores it.
You might want to consider using a single data table control. A ListView (or something like ObjectListView) may be a good option.
If your data isn't really a list/table, you should split the controls into separate tab pages, which would improve both performance and usability.

Categories