I'm trying to rebuild the "Window Snip" functionality from the Microsoft "Snipping Tool"
I know how to get the boundaries of a window by first getting the window handle with p/invoke from the cursors point and after that getting the windows RECT also with a p/invoke method.
The problem I'm facing is that when I'm trying to implement an overlay like the snipping tool does I'm always getting my own applications handle.
I think the problem lies in the way I’m trying to implement that overlay. At the moment I am instancing a new form with the boundaries of the screen, Background is White with 50% opacity. I have a TransparencyKey with the color Fuchsia. My goal is that my overlay is completely transparent for the window where the mouse cursor is. (Like Snipping Tool does) For that I planning to draw a rectangle in Fuchsia with the boundaries of the underlying window to my overlay form (effectively making that spot transparent).
Is there a way to ignore my own window in the p/invoke method? Or is my idea to use a form for the overlay the wrong way to go and there is a simpler way to achieve the wanted behavior?
Related
I'm looking for a way to have images on invisible form that allow alpha transparency and allow to place and use buttons/labels etc.
I've tried this Transparent background on winforms?, layered window and many more, nothing fully successful. I've ended up with such failures http://imgur.com/a/t6nmF
Transparency key only makes one color transparent, which doesn't work on images that have smooth color gradients on the edges.
First of all, are you certain that your image has a transparent background?
Layered window is exactly what you should use to achieve the desired effect. Since you don't give much details, I don't know what's wrong with your implementation. Try to use the PerPixelAlphaForm from the following article: Per Pixel Alpha Blend in C#. When used correctly, it will work (even though the article is really old).
There are quite some topics available about GDI drawing and flickering issues, but I haven´t been able to find any regarding drawing in an other process.
The issue
Basically I´m trying to draw to a Hwnd using Graphics.FromHwnd. This works perfectly, but there is a lot of flickering involved. The application I´m trying to draw on is a game (not made by me) and has quite a high refresh rate, unlike forms.
Attempts
I´ve tried doing the drawing both using a GDI.Rectangle function that used the HDC to draw and using Graphics.DrawRectangle to draw to the Hwnd. I don't notice a difference in performance but 'Graphics' seems a bit easier in use since it doesn't need gdi32.dll to draw shapes, unlike GDI.
I've also tried doublebuffering but yet again I do not notice any difference.
To me it seems that the doublebuffering is not working because of the fact that I'm trying to draw in such a high refresh rate window.
Question
Is it possible to get the window's refresh rate and use that for a timer to update the graphic?
is it possible to make graphics 'stick' until updated so they don't automatically disappear?
If anyone knows how to do this, or knows other solutions to get rid of the flickering I would appreciate the help!
Thanks in advance.
After doing some research I've come to the conclusion that using a transparent window will suit my case best. Here's how I came to that conclusion:
I've used an application to read window events to check if there was any continuous event stream that could be the window invalidation, but there wasn't.
I did find out a way that should make it possible to actually read when the game invalidates the window, but it's kind of a hack: It's possible to replace the game's d3d9.dll file with your own, calling all the original functions, but catching the events. I don't have any details on how or even if it works since having to distribute a dll to end-users is not an option for me, not to mention that this is in fact hacking.
I'd like to implement a similar screen clipping functionality to that of OneNote. Basically it can draw a translucent overlay on top of the whole screen, and also freeze the screen so users can clip a portion of it.
I've done some research around and it seems that the easiest way is to create a translucent TopMost form with the size of the whole screen and then perform clipping on this form. This approach, however, is slow. I see some other suggestions about doing a Direct3D hook for drawing overlay, but this is probably too complicated and I'm not sure how stable it is with respect to different Direct3D version. Any ideas how OneNote does it?
I think instead of creating the transparent layer on top of the screen, just grab a screenshot of the whole screen and make it full screen. So users are drawing on a static image not a translucent layer. Since it is a screenshot already, it is already frozen. I think this is how they do it anyway, I doubt an application can simply freeze a screen, they take a photo of it and cover your screen with it, so its as if its frozen.
I have an application where, beyond my control, several Windows Forms have a TransparencyKey property set. When these windows cover (are in front of) another form which has a DirectDraw video surface, the foreground form flickers (partly showing the form and partly showing the video beneath). The thing is, the color of the TransparencyKey doesn't appear anywhere in the application, so NOTHING should be transparent... in other words, the result should be that the foreground form is completely opaque.
Does anyone have experience with DirectDraw surfaces flickering when combined with Windows Forms that are in some form or other set up to be transparent? I've worked on this for weeks, with no success. Thanks!
I'm sorry but I would suggest that you abandon that goal completely and try to do it some other way.
DirectDraw is one way of displaying stuff on the screen, and forms with regions (that are created on the fly as masks from so called 'transparent key color') are done with GDI. As I see it (and would like to be proven otherwise) - you won't be able to combine that two windows anyway.
And you will probably get different results on different Windows, depending on the version, graphics card used, and so on.
On the other side, can you hack those forms that you don't have the control over and remove TransparencyKey property from them? Even with Win32 API?
When you create a form in .Net it appears as a dialog box in a portrait layout.
No one normally likes to read sideways, or upside down, but I have a very valid reason to rotate the form.
Anyone knows how to do it on Windows Vista with C#?
Does it have to be in WinForms? This is very easy to do in WPF, using rotation transforms. Unfortunately, the WindowsFormsHost integration with WPF does not allow rotation transforms.
EDIT
I understand, now, that the form in question is out of the control of the poster. Writing the control in WPF won't fix the problem.
This would be a bit of extra work, but if you mainly just need the contents of the form to be rotated (and not the entire window including title bar, window controls etc., which I've never seen before), you could instead make an entirely owner-drawn usercontrol that was rotated 90 degrees, and drop it on an ordinary form. You wouldn't even have to adjust your drawing of everything, since you could do a RotateTransform on your Graphics object and then draw everything normally.
Or if you need the entire form rotated, you could make the form borderless and then do basically the same thing, drawing the title bar and windows controls yourself also.
Update: here's a link to an MSDN article that shows how to rotate the entire screen in C#:
http://msdn.microsoft.com/en-us/library/ms812499.aspx
This is for regular Windows (not Windows Mobile), so it should work for your porpoises, although it will rotate all of Windows and not just your application's form. Depending on how fast this works and your overall needs, you could rotate the screen 90 degrees when your application gets the focus, and then rotate it back to normal when your app loses focus.
Update 2: I just reread your question and comments. You're talking about rotating the window of a separate application in a separate process, so WPF will definitely not help you here. The MSDN link might be what you need. In your application, you would rotate the screen 90 degrees, then start the other application in a separate process. This would work best if you could force the separate application's window to be maximized, which you can do by P/Invoking the FindWindow and SendMessage APIs (you could also make the window always on top, which would put your computer into a sort of kiosk mode for this application). There's a version of the Process code that basically makes starting another application a blocking call, which means your app will wait for the shelled application to close before resuming. Once the app closes, you can put the screen back to its normal orientation.