Draw outside a window's bounds on windows API - c#

How, on Windows API, is it possible to draw outside the bounds of a window (not just outside the client area)?
I need to be able to draw a drop shadow, a color glow or any other custom design outside the bounds of a window, so I can implement a complete custom window theme design with outer glows or drop shadows. My question is about how to be able to achieve that on the Windows API.
On my searches, I found that some developers use to combine a "ghost" window behind the actual window, so it is possible to draw a shadow or anything on it, while for the user it seems that there is only one single window. Is it a good way of doing what I need?
Well, to accomplish that, I would like to know what functions on the Windows API I need to use to make that "ghost" window to not appear as a separate window when I click on Alt+Tab or Windows+Tab, and basically to make that "ghost" window really a ghost.
I will be doing that on WPF using C#, but the question is really more related to the Windows API, independently of the framework.
Thanks in advance!

Create a headless window (without the _ [] X), make it transparent, and inside create a fixed frame (a frame is a rectangle that can contain other things). So 1 window 1 frame and around that frame you can add more frames tha contain semi transparent stuff to create shadow effect.
The main headless window has to be big enough to draw all that inside. If you only create 1 window (all other things be frames or other widgets) there will be no problem with Alt Tab.
Inside the fixed frame you can create again the (_ [] X) buttons to give the illusion. The API exist for this and can then be bound to these buttons.
PS: There might me more than one solution

Related

How to make a window manager?

I tried writing code several different times, but I came to an error with each one.
Basically, I'm trying to make "windows" similar to say Explorer, Paint, MediaPlayer, where you could drag then around, interact with them, minimize and close. Of course, if you clicked on a window, the one below it (they can overlap) shouldn't get affected.
I know how to do this, I have a list of the class I call Window, loop through it, and I only interact with the first window to contain the location of the mouse-click. This way, other windows overlap won't get affected.[1]
Next, I had to make it so that two buttons that are overlapping don't get activated when the user clicks in the "intersection of both buttons." I handled this by using the same method I used above.[2]
But the problem I'm facing now is that, if I hold the left click, but then I decide not to click a button, I drag the mouse away from the button, and release the left click, so that the button-click event won't be activated. But, when I remove the mouse from the boundaries of the button, and say, into another.. the new button get activated. Which it should not.[3]
My set up is like this:
I have a class called Window.
In Window, I have a list of the class called Interface (similar to the Control class in WinForms).
And each Interface has a struct in it that contains 4 bools, if the left/right is currently down, and if they were down in the previous processing. (prevLeft, prevRight, currLeft, currRight)
So, I'm ready to discard that (I have not yet, so I still have the source code), but I need a good structure for making an object-oriented type of application. However, I am not using WinForms. I need help with the structure alone, so no actual code is necessary, description is enough. I need to avoid the 3 problems I mentioned above.
Creating your own Window Manager is not an easy task. I know it because I'm making one too ;)
You can use an existing, though maybe not the best solution, like for example Nuclex.UI, which I personally rejected when I first saw it, but if you're not dead set on making your own WM, I suggest to use that or hybrid WinForms-XNA approach.
But if you're really dead set on implementing a custom Window Manager, you have to understand how any other WM works. Since we're talking about XNA, it means Windows, and that means Windows Explorer, which is a great thing to learn from.
You have to recognize how the simplest things work, and it's really not so hard. The hard part is figuring out what logic is updated when, and how to not spend all the CPU on only UI updates. Let me just give you a few hints on how to solve the problems you mention in your question.
To keep track of all windows, I'm using a Dictionary<string, Window>, where Window is a custom class, and the string is its unique name for rare cases where I have to call windows by name. Think of it as a window GUID or Handle. But you can just make it so that a "Form" can only appear once, and store all references in static variables.
To make WM understand what control you're clicking I use rectangles and check if they contain a Point which is at Cursor coordinates and has {1; 1} pixel size, which is probably about the same way it's done in Windows Explorer. To do that your WM needs to know in which order to update the active windows. Usually you'd want to start from the topmost window and continue towards the end of the list of active windows. For that you can just iterate through the list with a foreach loop.
But that's not all, because every window itself is a Container, which means it contains other controls, some of which may even be Containers themselves, like WinForms Panel class. This means you have to iterate through each of the Windows' Children controls. The update order should make sense too - update from the topmost child to the bottommost, recursively for Container controls, in case they also have Containers in them. This basically means you'd want to implement a recursive GetAllControls() method for your WindowManager class that would iterate through all Containers and return a list of all Controls.
Drawing all those Controls should be done in reverse order of updating them, so you can just GetAllControls().Reverse() and iterate through that in a foreach loop.
Where to draw and what to update depends on all the parent containers the current container has and their combined offset from the top-left corner of the game window. I solve this by storing a ParentContainer reference in all children controls to get the appropriate DrawRectangles and update areas via recursive properties.
When you click somewhere on the screen and a click is registered on a Control, make the WindowManager remember that (bool clickRegistered) and not run any OnClick events on any underlying Controls.
Windows Explorer remembers the control you clicked and will activate its OnRelease event if the cursor is then released in the update area of the very same control. So basically Windows Manager only does something when you release the mouse button. You can make your WindowManager and Controls to handle click events differently, like firing an event right after you press the mouse button, i.e. OnMouseDown. But remember that Microsoft aren't noobs and there's a reason for that behavior in Windows Explorer, and it's because if you accidentally press a mouse button somewhere you didn't intend, you can still fix it by moving the cursor outside the pressed control's update area and not run its action.
At this point you might be thinking "Is it really worth implementing all this?" For me the answer was "maybe", because I was a total noob in both C# and XNA at the time I started, and now I know my game, which was originally supposed to use some Window Manager, is going to benefit from my own WM implementation far more than from ready third-party solutions. And besides, it's a great exercise in logic and programming.
But if you'd like to think of yourself as a game developer, you should think in terms of reaching your goal as quickly as possible, i.e. actually making a game, and not the game engine. So in this case, better make use of existing solutions and start selling your product.
Instead of having the structure with the 4 booleans (similar to xna), how about you make a way to tell where the mouse "is." So in a sense, the mouse is in Window number 5 which is Paint, and the user is holding the mouse down on interface/control number 2 which is a button.
That sounds like it could work.

C# Desktop App Bar (Somewhat Like a taskbar)

I've been googling a lot for this one and I can't seem to find anything. Maybe it's the way that I'm wording it. So basically what I'm looking to do in C# using Windows Forms, is create a form and have it essentially take the shape of the taskbar and do the same functions as the taskbar, but it will sit above the task bar or at the top of the screen.
It can't be "ON TOP" (I'm not trying to block user buttons like the close button of a program they are using).
Autohide would be a plus.
This is the main thing I'm after:
It needs to act just like the task bar. When you maximize any other window, the taskbar does not go over the top of the window, even though it is set to "on top".
You'll want to use an Appbar to do this:
http://msdn.microsoft.com/en-us/library/cc144177.aspx
For more information, check out here and here and here.
If you don't want to deal with C++ and Native Code (as #FKunecke correctly proposed) then you'll not find anything predefined for this. What you can do is create a form for your bar and make the visualization calculations by hand, then you can set the screen location of it. That's all. Not forcing the bar form to stay on top will not hide the other app forms so you'll get that for free.
Now, to fully implement what you want there are some problems you need to deal with, such as Taskbar location and height. Then you'll need to use some native code tricks.

Create a dock like application using C# and wpf

I need to create a application which is similar to those we will get when we buy a laptop. It will be visible only when the mouse pointer reaches the top of the window. So how can I able to do this using C# 4.0 ?
http://www.notebookcheck.net/uploads/pics/win2_12.jpg
this link u can see the application. I need to create such type
Any idea pls share. Thanks
I suppose there are several different ways to achieve this effect:
You can place part of the window of your application above the visible screen, so only a part of it is visible (let's say you can see only it's bottom). Then you need to handle events when mouse enters (MouseEnter) and leaves (MouseLeave) the form to move the form up and down.
You can use a background thread to call GetCursorPos method at a set interval (i.e. each 500ms) second to check where currently the mouse is. See this link for more information about it and a sample code: http://www.pinvoke.net/default.aspx/user32.getcursorpos.
(If you need only to check the mouse position, you can use a timer to simplify you application.)
When you hit what's possible with C#, you can always start invoking native code - such as the windows API. Since you don't ask a specific question, I'll leave you with:
Position your app where you want it to appear and hide it.
Capture mouse position with windows api (see this SO answer)
When mouse is at screen corner / top, etc; make your app visible.
Now make sure all this works with dual screen setup, and you are done.

Non client painting on aero glass window

Now Im customizing title bar of my application. My aim is to add one extra button on title bar. Im my previous question people have adviced me the way I can customize non client area. Thats works perfectly except one small thing - glowing! I can draw glowing in nonclient area but I cannot make it spreads out of the window. I also cant find any resource about this subj.
I looked into this sample and made my own test app for investigating non client drawing facilities. Screen shot of my app's window:
So you can see that system button glows out of the windows when my is clipped by borderframe.
For example, Skype's window have four custom buttons in title bar and they can "glow" out of the window frame:
Can anybody advise me to find out the way to draw button's glowing out of the window?
Thanks in advance!
[EDIT]
Thank you everybody for answers!
Skype cheats it, and has a little sliver along the top of their window; where they can draw it.
You can see it with Process Explorer to SpyXX:
See also
MSDN: Custom Window Frame Using DWM
I don't think it's possible to draw beyond your NC area, and I kind of doubt they are drawing the whole UI to exactly match DWM Aero effects.
Given how this looks, I wonder if they did some tricks with either the help or restore button of a CustomBorderForm, which would then get the DWM blur highlight effect "for free".
Here's the most relevant article I could find to this: http://geekswithblogs.net/kobush/articles/CustomBorderForms3.aspx
Followup - I think this custom chrome thread has more pointers to the same techniques (although different goal): Custom titlebars/chrome in a WinForms app
AFAIK, this is not possible, because the area outside your window's border simply does not belong to you.
The Skype screenshot is from a custom-drawn frame that most likely extends a bit beyond the visible borders, not from an Aero Glass frame. You can tell the difference if you look carefully.

How that overlay(?) form works in JING

OK, anyone can explain how Jing take screen shots with that overlay form? It appears that it take a full screen shot and records all visible window handles and let you select within the form a specific hwnd. could be true? if is, what are the big steps to achieve this? could be a simple picturebox or without a custom control i don't have a chance to freeze the screen while taking a screen shot?
Thank you!
I'm not familiar enough with Jing to know exactly what it uses. But there are two basic techniques. One is as you mention, capture the screen and display it in a topmost borderless form. The Vista/Win7 Snipping tool works that way. You'll find the code you need to get this started it in my answer in this thread.
The other, perhaps more likely to be used by Jing, is similar to what Spy++ does, allowing the user to move the mouse and draw a selection rectangle around the window. Its advantage is that it can deal with windows resizing or disappearing while you've got the tool running. You implement it by using a topmost form the size of the screen that has its TransparencyKey property set to the value of the BackColor. Fuchsia is a popular choice. You can draw on this form with the OnPaint() method, the drawing appears on top of all the windows. You'd need some P/Invoke (GetWindow) to iterate the underlying windows in their Z-order to know which window the user is pointing at. GetWindowRect() to get the window rectangle. Plus some hassle to deal with Aero lying about the border size.
You can find sample code to get you started on that technique in my answer in this thread.

Categories

Resources