Changing the window control buttons in WPF - c#

I see that many applications do not have a title bar, but still have the window controls in the upper right corner. These are also styled differently than the normal windows form controls. Is it possible to achieve this effect in WPF?
Here are some examples:
Zune Desktop software:
http://i548.photobucket.com/albums/ii356/elpedrogrande/btns2.gif
Photoshop:
http://i548.photobucket.com/albums/ii356/elpedrogrande/btns3.gif
GoTo Assist:
http://i548.photobucket.com/albums/ii356/elpedrogrande/btns1.gif

They do this by setting the window style bits so it is created without a title bar. And then draw their own, making it look like a custom one. Which is the main reason that all these programs have caption glyphs that are not identical.
You'd accomplish the same in WPF by setting the WindowStyle to None. And a whole bunch of code to get back the behavior that Windows implements automatically with the title bar. Google "WM_NCHITTEST" to find out more.

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).

Creating tabs in the Windows titlebar area in C#

Can someone tell me how to create tabs in the title bar area of a C# Winforms application? I'm looking for something similar to how Google Chrome looks. Each tab in Chrome is docked in the title bar of the main application window.
Try setting FormBorderStyle of your form to None. I think if you look around there are some articles on how to build a UI like this where you can still have the drag functionality you'd lose by hiding the title bar. Then you could build up the title bar area the way you wanted it to work.

Making a graphical element "dock-like"

Specifically, what I am try to is overlap my element on top of everything, including the desktop, similar to the taskbar in Windows. I have a Windows Form Control that looks kind of like a tab. its like 50px wide by like 150px in length. What I would like to do is have that control appear in front of all windows, including the desktop itself. I say "dock-like" because I belive docking pushes windows over (so if my tab was docked, it would push any full screen application window over 50px), which is not what I'm trying to do. I want my tab to overlay on top of everything. The closest example I can think of is Winamp. Winamp can dock to the top of the screen and it is always on top of any application.
how can do this in C#?
System.Windows.Forms.Form has a property, TopMost, which will cause the form to stay on top of other windows.
The "snapping" behavior of Winamp can be implemented by using the Move event of the form--when the form is moved close enough to the edge of the screen, programatically set the position so that it's on the edge.

Chrome Style C# Applications?

I'm not talking about the vista glass feature, I already know how to accomplish that. The feature that I'm talking about is add controls to the titlebar, like office 2007 does with the logo and toolbar.
You need to do some Win32 interop to achieve that effect. Depending on whether you are using Winforms or WPF, the way you hook to the message processing differs (I don't remember Winforms, so I'll give all examples for WPF). But in both cases, you need to:
Intercept the creation of the window and modify the window styles and extended styles. In WPF you need to inherit from HwndSource and modify the HwndSourceParameters in order to achieve this. You need WS_OVERLAPPEDWINDOW, WS_CLIPSIBLINGS and WS_VISIBLE for regular style and WS_EX_WINDOWEDGE and WS_EX_APPWINDOW extended styles.
Add a message handler throught he HwndSource parameters HwndSourceHook.
In the message proc added through the hook in step two, you need to process several messages:
WM_NCACTIVATE - to change the painting of the title when the app is activated or not
WM_NCCALCSIZE - to return to the OS that you don't have non-client areas
WM_NCPAINT - in general you need to invaldate the window rect only here, the WPF will take care of the actual painting)
WM_NCHITTEST - to process the moving of the window, minimizing and maximizing.
Once you do the above, your client area where WPF is going to paint your visual tree is going to span the whole area of the window. You will need to add the "non-cliet" visuals so that your application looks like a regular application to the user.
You might need several more messages:
WM_THEMECHANGED if you want to change your "non-client" area painting to be consistent with the OS theme
WM_DWMCOMPOSITIONCHANGED if you want to extend glass and get the standard OS NC-glass painting when glass is enabled and switch to your custom logic when glass is not.
You might want to look at the Win32 Theme APIs if you want go get the standard Win32 assets for borders, caption, close, mininmize and maximize buttons to use in your 'non-client" area.
If you want to extend Glass into your window, you can look at:
DwmExtendFrameIntoClientArea - to get the standard glass NC-area
DwmDefWindowProc - to get the desktop manager to paint Glass and the standard NC controls
DwmIsCompositionEnabled - to determine if Glass is enabled; you can use the above two APIs only when Glass is enabled. If Glass is not enabled, you need to do your own drawing of the NC area.
You can find the proper C# definitions of all messages, styles and corresponding Win32 APIs you need on P/Invoke.
You could also achieve similar effect by using standard WPF window with a WindowStyle=none. However, there will be some differences between the behavior of the desktop towards your app and other apps; most obvious of them is that you won't be able to stack or tile your window by right-clicking on the taskbar.
You can also look into some third-party components that enable some of this functionality. I have not used any (as you can see, I am not scared of Win32 interop :-)), so I can't recommend you any particular.
As Franci mentions, what you want is DwmExtendFrameIntoClientArea. Here's an example from Codeproject that shows how to do it.
http://www.codeproject.com/KB/dialog/AeroNonClientAreaButtons.aspx
Joe Castro, a WPF product team developer, has an MSDN code gallery project called "WPF Chrome" that can be used to create an office 2007-like UI (ie: controls that span both the client, and non-client areas of a window).
Find it here: http://code.msdn.microsoft.com/chrome
I've used the DotNetBar control suite with good success.

Display Form non-maximized with borders on Windows Mobile

I need to create a status dialog for a Windows Mobile application (C# 2.0) that needs to be updated, so MessageBox is out. I tried to just create a new Form class, change the size and call ShowDialog, but it always comes up full screen (minus the title bar of course). The only way I could figure out how to display it small is to set FormBorderStyle to None, but then it really does have no border or title bar at all!
I want it to still look like a message box (with title bar and borders) but, I need to actually use a Form so I can update it.
Any ideas of how to do this?
The challenge here is the WinMo shell itself. What's not apparent is that the caption on the form (at the top of the screen) is actually not the caption of the Form you see - it's a completely different application. So to get your Form to "float" requires subverting the way the shell handles Form display. A quick and dirty way is to set the Form BorderStyle to none, but then you lose your caption bar. An option then is to manually draw it in with a FillRect and DrawString in OnPaint. Not too difficult and doesn't require any P/Invoke shenanigans, but it does require that you take the new header into consideration when you layout your controls.
Another option is to use P/Invoke and manipulate the Form's style bits yourself. This works well, but take care that you do it in the right location in code, as some bits have to be set on Window creation. Also beware the shell, as it might want to change the bits back on you - so this mechanism requires more testing and attention to detail. IMO this is a better route, and I've blogged about it in more detail here. That blog entry isn't specifically about floating forms, but it covers style manipulation well. For more specifically on non-fullscreen Forms, see my other blog entry here.

Categories