I am writing a C# solution where I have one pc with keyboard and mouse and other two with screen only. I can control them remotely with the peripherals on the main pc.
What I would like to do is to have a colored border (Skype shared desktop like) when I control one of the remote screens, to notify which one i am using.
I've tried with the graphics and DrawRectangle but it is not fixed and part of it goes away if i move the form window over it, since it refreshes the graphics.
I would like to know if there is a way to add the border and then remove it when i switch the remote control.
Is there any solution?
Thank you!
As you've discovered, your form may repaint at any time.
Instead of drawing directly, you need to handle the Paint event and draw whatever is necessary.
When you want to change what is drawn, just call Invalidate() to trigger another Paint event.
Related
I have a desktop application built on MONO. The Application has a button and a drawing area, on-click of the button it draws a house in the drawing area.. till here i don't have any problem but once i re size the window or minimize the window the drawing disappears.
Please let me know if any one came across this problem or if any one knows about it.
Thanks,
Best Regards,
Veeresh
This is a common "issue". It's not really an issue though, it's just the way things work. When you draw something to the screen it's just there in video card ram. When you minimise or move another window over it, something needs to redraw the image. In your case you have nothing to redraw it. You probably need to move your code to draw it to the paint event so that it paints it every time the window needs painting.
Another option would be to draw to a bitmap and display the bitmap in a image control but this is wasteful of memory. It can be the right choice in the correct situation.
I'm pretty much out of ideas here... for everything else, setting the background color to Color.Transparent or setting the TransparencyKey works fine...
I have an mp4 Video which I need to play as a "background" of my form. To do this, I'm currently using the WMP control. My problem: I can't add any controls on top of it, since they always render a background. Which looks ** on the video...
Any suggestions?
A hack I've used successfully in a similar situation:
Create a separate, borderless, transparent form (transparency works best at the Form level)
Host button controls on that form
Launch the control form when your video form launches
Wire event handling such that the floating form always moves, resizes etc. whenever the main form changes
Calculate position of the floating for based on parent form's specs
Always push the floating form to the top, above the parent form
Told you it was a hack. But if you get all the events and calculations wired up it should work fine.
P.S. I also recall having to do a poll timer with a function that made sure every 250 millis or so that the Z-order of the two forms was what you wanted. (Switching apps and windows changed the z-order unexpectedly and w/o events, thus the polling solution.)
P.S. II It is very easy to prototype the feasibility of this solution. Just create a separate app with the above-mentioned specs and move it over your video. (You will need to retain the Form border to be able to move/resize the window easily.)
Try rendering your labels using GDI+:
You can see sample here: (the Using GDI+ for drawing images with transparency part):
http://www.broculos.net/en/article/how-use-transparent-images-and-labels-windows-forms
I have a form with a Transparency-key color, where I'm doing a global mouse hook for the right click.
Until there everything is okay, but since the form is transparent, the mouse cursor is changing according to what is behind the form.
Is there any way to change the global mouse cursor?
Yup, that's how transparency works. Not just to the eye of the user, also to what the mouse sees from its left eye. Has to work that way, major user confusion if it didn't, no option to change it.
The workaround is to show a fake version of the desktop. A screen shot. Just what the ever popular Windows Snipping Tool does. Sample code is in this thread.
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.
I'm drawing directly to the screen using BitBlt and GetDC(IntPtr.Zero). Is there some way to call Refresh or Invalidate on the whole screen when I'm done, so that I don't leave big chunks of paint everywhere (digitally speaking)?
Update: when you draw directly to the screen like I'm doing, whatever you draw remains there until the window underneath it repaints itself (and in so doing, repaints the portion of the screen it's covering).
The problem is that some portions of the windows desktop don't repaint themselves for long periods. For example, if I draw over top of the task bar, the actual tasks repaint themselves fairly quickly (along with the Start button etc.), but the taskbar itself retains what I've drawn for as long as a couple of minutes.
If my app had a window that covered the entire screen, I would just call Invalidate() on that form which would cause it to repaint itself and thus the entire screen. What I need is some way of calling Invalidate or Refresh on the whole screen itself.
InvalidateRect(NULL, NULL, TRUE) should invalidate and redraw all windows. Though it will be expensive operation.
An alternative approach would be to remember where you've drawn and try to enumerate any windows in that rectangle and invalidate only them.
You can also try creating a transparent window over the area you've painted when you want to invalidate the windows there. Note that you want to do alpha-blended layered window, not an WS_TRANSPARENT window. If you do it with 99% transparency, the DWM should repaint all the windows below it once it's destroyed. Of course, this could lead to barely perceptible flicker over the target region due to the alphablending of the window before you destroy it.
The "screen" is made up of a set of windows that are parented to the Desktop Window. I would imagine that you could simply invalidate the desktop window, though you may need to recurse through its child windows (the top-level application windows) and invalidate them too. (There may also be issues with mutliple monitors, but this should give you a starting point)
See GetDesktopWindow().
Alternatively, create a form that covers the entire screen, and use transparent drawing. Then simply close the fom when you're done.