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.
Related
There are some programs such as Google Chrome and this:
They have a windows forms border that is different than the default. How do these programs do this and still allow the user to drag the window around? Is it possible in C#?
There are plenty of component suites (DevExpress, Infragistics, Telerik, etc.) doing this but you can do it on your own as well. But prepare to get dirty - really dirty!
Basically you have to catch the windows messages (yes, native!) and handle them properly. To make the form draggable is the easiest thing in this chapter (you just have to tell windows that the mouse is over the titlebar area even if it is not >> see here on CodeProject).
Let me get back to the painting: Don't do it!
There are so many things to handle ...
is your form maximized, minimized, normal state
which of the buttons (min/max/close) are enabled?
is it a tool window or a sizeable one?
is there a help button?
is the form sizeable? if so, you have to draw that border as well ...
... and so many more.
In addition, painting in the non-client-area is not as easy as painting usercontrols with a Graphics object. And even if that does not scare you by now, you might probably find yourself breaking the layouting logic of your forms' controls because the forms' size is the same as its ClientSize.
So, please consider to use DevExpress or any other toolkit. Speaking of DevExpress - I knew there was a free set of their fantastic controls and I'm pretty sure that the XtraForm (which does all the titlebar painting) is included as well.
Save big parts of your life and skip that chapter.
(However, if you're brave enough, check this article to do it anyway).
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)
I'm writing a system tray app for Windows (with much info gleaned from this thread). I have the ContextMenu working - you can right click and execute functions that way.
I want to have a modern, rich interface pop up on a left click, however, much like most of the built in Windows 7 (and possibly Vista) tray icons have. By this I refer to the Aero lining, and apparent ability to add seemingly arbitrary controls (e.g. volume slider, network chooser).
I'm not really sure where to start. Is it a matter of creating a "normal" window and restricting it heavily? If so, how? (If it comes down to Windows Forms vs. WPF, the latter is preferable).
For what it's worth, you can display anything you like when you receive the mouse click on your notification icon. Usually it's a pop-up menu, but you could show a window instead.
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.
Our clients have fat fingers, and so do we. We take touchscreen netbooks apart to insert them into our custom hardware, and I write a software interface that shows up on the touchscreen. The problem is that it has about a 3/4" bezel over the screen, which means hitting that little red "X" becomes a challenge, especially considering reduced capacitive ability on the edges and corners.
Is there a way to make this standard close button larger? Of course in the application I can always make really nice 80x80 buttons that are perfectly usable, but there seems to be no way to override the default frame of the form. We have tried enabling Large Fonts and all the built-in accessibility features, but nothing seems to make it large enough to hit successfully.
Simply adding a toolbar button is also not much of an option. We prefer to utilize the standard look and feel of a normal Windows application.
Alternatively, should we be looking at making some sort of "kiosk mode" where we simply go fullscreen and do nothing involving the taskbar or title bar? How difficult is this to accomplish, if so?
Well, since you're setting up the hardware, I presume you're able to configure preinstalled software, including Windows. Can't you just go into Display Settings and make the title bar larger, so that the close button grows accordingly?
See MS Article about distributing windows themes: http://support.microsoft.com/kb/310514
Getting a large close button is fairly easy to do. It is hidden well since Vista, in Win7 it is Control Panel + Personalization + Window Color, Advanced appearance settings, Item = Caption buttons, change the Size. You probably won't like this much though, you'll get a rather large caption bar, lots of waste screen real estate.
Tackling this from the other end: your request is unusual. Most anybody that sets up a touch screen app wants to know how to prevent the user from closing the window. Windows Forms makes it too easy to design a bunch of forms and switch between them. That isn't much of a user interface on a regular desktop, especially not here. You can design your forms as user controls as well and switch them in and out of the main window as the user navigates through the UI. Not unlike, say, Microsoft Outlook. You can even turn your existing form into a control. Set its TopLevel property to False, FormBorderStyle to None, Visible to true.