I have tried to create a custom border less form for my application. I decided that it had to be resizable, so I put 8 panels on its sides (4 corners, 4 sides actually) and created code which will resize my form when called. Like, for example:
private void E_MouseDown(object sender, MouseEventArgs e)
{
Active = true;
}
private void East_MouseMove(object sender, MouseEventArgs e)
{
if (Active)
{
this.Size = new Size(this.Width + e.Location.X, this.Height);
this.Refresh();
}
}
private void E_MouseUp(object sender, MouseEventArgs e)
{
Active = false;
}
Unfortunately, the resizing is slow, overloads the CPU and performs visual glitches even with double buffering for the form turned on. I have quite a bit of controls on my form. But what I have noticed is the fact that when I switch to a standard border (like Sizable), and DWM handles the window chrome, resizing is perfect. No glitches, stuttering and flicker. So I came to wonder, how does Windows manage to do? Is there a way to simulate what it is doing via the 8 panels? I hate when it flickers and it halts my project for no reason. The fact is that I worked all day long to mimic the Visual Studio 2013 window chrome and nearly suceeded, there is just this annoying problem... Can you help, please?
Thanks.
Related
I'm trying to make an animation for my C# program. There's a space rocket that ascends 8 pixels vertically with a timer interval of 25ms. I've managed to make the animation but since the picturebox's background (I've used for the rocket) is set to transparent it flickers the form's background image everytime it moves. What can I do to prevent it?
The code I've used for timer tick :
pictureBox1.Top -= 8;
P.S: I've tried to change the picturebox with panel, slow downed the rocket and timer but nothing seemed to change.
Well i haven't tried it myself now.
There needs to be a render event which you can hook to and make manipulations to your UI which would render smoothly.
Control.Paint
Try something like these :
private void Form1_Load(object sender, System.EventArgs e)
{
pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
}
private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
pictureBox1.Top -= 8;
}
Again this isn't tested and i haven't developed any thing in winforms for ages.
But that's the direction you should go for to render things smoothly.
That double buffered thing mentioned above is also a factor in some cases.
but this is mainly the way to do it.
Recently, I was learning OpenGL for C#. The basic structure I need is:
Computation in UI
=> Draw OpenGL in a separate window
=> More computation in a UI.
So far, the program always freeze up in the second step (make a window, draw some stuff, and that's it). I have tried:
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
//Draw the image on the window
Glut.glutIdleFunc(OnRenderFrame);
Glut.glutDisplayFunc(OnDisplay);
Glut.glutCloseFunc(OnClose);
Glut.glutMainLoop();
}
and call
public Form1()
{
InitializeComponent();
//initialize the window, the shapes, shader, and some other stuff
backgroundWorker1.RunWorkerAsync();
}
but it does not work. I have also tried to put the code for drawing in a button_Click and some other, but none works so far. Can anyone please help me with that?
PS: I learn OpenGL from GiawaVideos, in which I have also tried to ask this question, but consider their last video is 2 years ago, I don't have much hope.
It seem that BackgroundWorker can not be used to affect anything in the UI (which incidentally also include the OpenGL window). So I only have to find a way for the to drawing code to run separately while "technically" still in the same thread via Timer.Tick. The code now is:
public Form1()
{
InitializeComponent();
//initialize the window, the shapes, shader, and some other stuff
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
//Draw stuff, not affecting the main UI thread flow
}
Is there any method / API allow calling something like CopyFromScreenAtDepth
I try to capture a preview of GUI below active window
then blur it to achieve something like Aero glass / OS X frosted glass blur effect
I have tried many workaround
Set the Form opacity to 0 then capture and setting back to 1, this cause my form blinking.
Make the Form background Blue with same transparent key, this will work at first time but GUI won't updating, so if I call this.Update() it will update the GUI, but cause blinking too.
My code:
private void MyForm_Load(object sender, EventArgs e) {
Timer timer1 = new Timer();
timer1.Tick += new EventHandler(UpdateBackground);
timer1.Interval = 100; // in miliseconds
timer1.Start();
}
private void UpdateBackground(object sender, EventArgs e)
{
this.BackgroundImage = null;
Bitmap myImage = new Bitmap(this.Width, this.Height);
using (Graphics g = Graphics.FromImage(myImage))
{
this.Update();
g.CopyFromScreen(new Point(this.Location.X, this.Location.Y), Point.Empty, new Size(this.Width, this.Height));
}
ImageTools.FastBlur(myImage, 4);
this.BackgroundImage = myImage;
}
There is no such CopyFromScreenAtDepth() method call for Windows.
The best you can do is to use the Windows Magnification API for C++.
There are a TONs of drawback using it, like not having control over the Window position and size, limited capabilities, to none at all, at having both copy of screen below form and being able to have other controls, and the WOW64 problem when using a 32bits application with the API under 64bits OS...
I know it's an old question, but since it's a valid question with no answer so far, I thought it would be fair to answer it.
There are also other questions like this one around (which doesn't have answer either, and may be called duplicates...)
I am doing some image sampling. What my question is, is there a 'crosshair' tool in visual studio? I want to have several instances on a single form, be able to move them around and then sample those points, obviously returning the color of the pixel at the center of the crosshair, is there already a tool that will do this, before I go and write one?
Thanks, R.
I know of no crosshair, but the following procedure can be used twice to draw a crosshair. To remove it, simply draw it again as it uses XOR to make the procedure reversible.
ControlPaint.DrawReversibleLine().
You could just change the cursor:
private void btnSample_Click(object sender, EventArgs e) {
this.Cursor = Cursors.Cross;
}
protected override void OnMouseDown(MouseEventArgs e) {
if (this.Cursor == Cursors.Cross) {
this.Cursor = Cursors.Default;
// etc...
}
}
I would change the cursor to Cursor.cross. Then just paint indicators at the mousedown-points with GDI on the PictureBox's Graphic, sample the colors from those locations and then clear the PictureBox's Graphic when the operation is done.
I am facing a strange behavior when I apply a non-rectangular region to a Windows Form (lets say an ellipse). The issue is that the form seems to disappear for a moment (as if the region is empty) when initially resized. It looks like a slight flicker whereas the contents of the desktop behind the form become visible for a fraction of the second. After the first resize this flicker is no longer observable.
This can be reproduced by simply creating a Windows Forms project and applying an ellipse region to the form by using the size of the form as a bounds rectangle for the ellipse (in this way you will be able to resize the form hence its borders will not be completely "eaten" by the region).
Note: I am updating the region of the Form in the OnResize event.
The code that I am using looks the following way:
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
GraphicsPath path = new GraphicsPath();
path.AddEllipse(new Rectangle(Point.Empty, this.Size));
this.Region = new Region(path);
}
Any ideas what might be causing this?
Quick follow-up:
I noticed that when I put the same code snippet in the OnSizeChanged event the flicker disappears or seems to happen rarely.
Thanks!
Handles Paint event
private void Form1_Paint(object sender, PaintEventArgs e)
{
GraphicsPath path = new GraphicsPath();
path.AddEllipse(new Rectangle(Point.Empty, this.Size));
this.Region = new Region(path);
}
You've fixed a massive problem for me in the same area.
I'm using this:
private void BorderedPanel_SizeChanged(object sender, EventArgs e)
{
this.Region = new Region(RoundedRectangle.CreatePlusOne(this.ClientRectangle, this.cornerRadius, this.RectangleCorners));
Refresh();
}
and it works without flickering. So it's worth giving a shot!