flickering in dot plot on windows 7 aero theme - c#

We ported win-form application legacy code developed in c# .net framework 1.1 to c# .net 3.5.
There is functionality for drawing dot plot and apply different shapes(polygon,square etc.) on dots in plot.
You can change size of applied shape by dragging using mouse what happening is when dragging shape some part get invisible till we drop to new point and also draws very slow speed.
you can call it as flickering .
this functionality works fine in windows xp, in windows 7 works fine
with basic and classic theme
it flickers only when aero theme is applied in windows 7
i have tried
http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/aaed00ce-4bc9-424e-8c05-c30213171c2c
and
Flickering in a Windows Forms app
none of them helped.
after time stamping execution time i found that
for (int i=0; i < arraypnts.Length - 1; i++) {
g.DrawLine(Pens.Black, arraypnts[i], arraypnts[i+1]);
}
// draw the last line
g.DrawLine(Pens.Black, arraypnts[0], arraypnts[arraypnts.Length-1]);
takes hell lot of time when aero theme applied compared to basic theme applied

I had a similar problem long time ago and after a while finally found the solution by redrawing components only when setting the Object visibility to false first.
Object.Visible = false
//redraw your components
Object.Visible = true
I dont know if this is possible in your case but worth a try!

I think you need to use double buffer for you form object.
this.DoubleBuffered = true;

Well I found a workaround for the flickering problem. Just disable the desktop composition — you can do it either at application level or OS level.
For application level, go to exe file -> right click -> compatibility-> check disable desktop composition.
Foror OS level (and better visual appearance), start->right click
computer -> properties -> Advance system settings -> Advance tab ->
performance settings -> visual effects->custom-> uncheck Enable
desktop composition.

“works fine with Aero off” …sounds like a recourse issue to me…. Are you drawing in a paint event? If not where are you obtaining your graphics object from? You can programmatically disable desktop composition, I need it for some projects I do… but nothing related to drawing…
[DllImport("dwmapi.dll")]
private static extern int DwmIsCompositionEnabled(ref bool enabled);
const uint DWM_EC_DISABLECOMPOSITION = 0;
const uint DWM_EC_ENABLECOMPOSITION = 1;
[DllImport("dwmapi.dll", EntryPoint = "DwmEnableComposition")]
private static extern uint DwmEnableComposition(uint compositionAction);
usage:
DwmEnableComposition(DWM_EC_ENABLECOMPOSITION);

Related

How do I achieve desktop overlay blur on Windows?

When I was installing AMD graphics drivers on Windows 10, I noticed a blurred background look, which is a style I want to achieve in my application.
I have tried using UpdateLayeredWindow, but it does not apply a blur effect. I have tried using DwmExtendFrameIntoClientArea and DwmEnableBlurBehindWindow but I am unsure how to customize window coloring
and image overlays.
There is a DwmGetColorizationColor function, but there is no matching DwmSetColorizationColor function. There are ways to set system-wide coloring, but I would like colorization to affect solely my application window. Also, Aero Glass™ was removed from Windows 8 and 10.
How do I include these effects in my application using WinForms in a way that works on Windows 8/10? If WPF can render these effects, how does it do it and how do I achieve a similar effect on WinForms?
After months of searching, I have finally found the answer. To achieve the glass effect on Windows 10, one must use the undocumented SetWindowCompositionAttribute function in user32.dll.
BOOL WINAPI SetWindowCompositionAttribute(HWND hwnd, WINCOMPATTRDATA* pAttrData)
where the layout of the WINCOMPATTRDATA structure is:
struct WINCOMPATTRDATA {
DWORD attribute; // the attribute to query, see below
PVOID pData; //buffer to store the result
ULONG dataSize; //size of the pData buffer
};
and attribute can have values from the DWMWINDOWATTRIBUTE enum.

how to set startup wfp location according to windows display language c#

i need to start my WPF form in the right bottom corner
and i succeeded doing this.
but if the windows in Hebrew then my WPF windows need to pop in the left-bottom.
i have tried this so far:
var desktop = Screen.PrimaryScreen.WorkingArea;
Left = desktop.Left - Width;
Top = desktop.Bottom - Height;
and i tried stuff like:
detect os language from c#
but with on success.
how can i detect in c# if the task-bar icons on the right or the left?
thanks
Actually, I think you went in right direction with detect os language from c#
It should be enough to check if
System.Globalization.CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft
is set to true.

Switched to VS 2012 and now form doesnt resize properly?

I switched to VS 2012 yesterday from VS 2010 and all seemed to go well except this.
I have a button on my form that when pressed extends the width of the form to show additional controls. Press the button again and it reduces the width to hide those controls. Now all of this worked great in VS 2010 and also works fine when I debug in VS 2012 but as soon as I publish or compile the project and open the .exe when you click on the button it adds like 5 to the width instead of the 100+ it needs to. I click it again and it will then change it to 372 like it should and shows all my controls. I click it again to hide the controls and it hides the controls partially (goes to the 188 + the mysterious 5) I hope all of this makes sense and am hoping there is a better way to run the process I need to.
Here is the code I am currently working with and I didn't change anything between switching from 2010 to 2012. In fact, if I open this same solution in 2010 and publish everything works fine.
private void button1_Click(object sender, EventArgs e)
{
if (this.Width == 188)
{
this.Width = 372;
this.Height = 540;
progressBar.Value = 100;
copied_status.Text = ("Output View Enabled");
}
else
{
progressBar.Value = 100;
copied_status.Text = ("Output View Disabled");
this.Width = 188;
this.Height = 540;
}
if (this.Width == 372)
{
button1.Text = "<<";
}
else
button1.Text = ">>";
}
The width of your form hasn't been 188 pixels in a long time. Now with VS2012, Windows finally stops lying about it.
At issue are the fat window borders in Aero. They were an extreme appcompat problem when the feature was introduced in Vista. Very necessary because those two pixels where getting hard to hit with a mouse. But drastically incompatible with the way an application creates a window. It asks for a specific window size, the outer size, the nWidth and nHeight arguments of the CreateWindow() function. But what really matters is the size of the client area, the part of the window inside the borders. If Microsoft wouldn't have done something about it, old applications would have ended up with a client area that was too small. Which looks very bad, the window content would not fit anymore. A control towards the bottom or right side of the form would not be completely displayed for example.
So, sneakily, Aero makes the window larger by the extra width of the fat borders. And when the app asks for the window size, it sneakily says that it is smaller by the same added width. The app doesn't know any better than it is still running with the same window size it had on XP. This works pretty well, but is not exactly ideal. Hard to get window edges to align properly with that lie for example.
Whether or not Aero will lie about the window size is based on the target operating system recorded in the EXE header. When it sees a version older then 6.00, the Vista version number, then it will assume that your EXE is a legacy program that doesn't know about the fat border feature. So needs to be lied to. You've been running with that target version number set to 4.00 for a long time, it is written by the .NET compiler when it builds your program. You can see it with dumpbin.exe /headers yourapp.exe.
This finally changed in VS2012 and .NET 4.5. Which is a .NET version that is not available in XP. The compiler can finally make the hard assumption that XP is history and you are going to run on a version of Windows that supports Aero. So it sets the target Windows version in the EXE header to 6.00. Correspondingly, Aero will now stop lying about the window size. You get the real one, not the faked one.
So a quick fix is to change the target .NET framework version to 4.0. That's available on XP so you'll get lied to again.
Of course it is better to fix your code. Never use the Size, Width or Height property, they'll inevitably depend on the border and caption size. Use the ClientSize property instead, that's the stable one and the one you really care about. But be careful with that property as well, a form may rescale when it runs on a machine that has its video adapter set to more than 96 dots per inch. Another feature that's very accessible in Vista and up. Rescaling changes the ClientSize proportionally by the DPI setting.
The real fix is to use a bool field instead that keeps track of the window state. And set the ClientSize property based on the position of a control you want to hide or reveal. So roughly:
private bool enlarged;
private void button1_Click(object sender, EventArgs e)
{
enlarged = !enlarged;
int width = someControl.Left - 5;
if (enlarged) width = someControl.Right + 5;
this.ClientSize = new Size(width, this.ClientSize.Height);
}
Replace someControl in this code with the name of your controls.

Changing where the .exe window appears when debugging?

First of all I'm not sure if ".exe window" is the proper term. It's the window that pops up when you start the application.
I'm a game programmer, and when I'm debugging, I very rapidly start it up, look at the problem, then close it down again to make minor changes in the code, then start it again etc. I do this like once per minute, so it happens a lot. My problem is that the .exe window always appears at the middle of my main screen (where I'm coding), and I'm running double monitors, and I'd like the game window to appear on my second screen instead of my main screen (obscuring my code).
Can I change where the exe window appears in VS2010? I've looked around everywhere, it feels like. Or is it something that will have to be managed by a 3rd party program? If so, what program?
Edit:
OK, OK, I found the solution. I did a really dumb mistake where I didn't mention that I am using XNA, and not using winforms. Sorry for misleading you guys. Here's how I solved it:
First off I had to include:
using System.Runtime.InteropServices;
Then at the top of my main class I created a tiny class:
public static class User32
{
[DllImport("user32.dll")] public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
}
Then in my Initialize function I simply call:
#if DEBUG
User32.MoveWindow(Game.Window.Handle, 2000, 400, 600, 480, true);
#endif
It's a little ugly, but it's only for debugging and only called once, so psh.
Original solution found here: http://social.msdn.microsoft.com/forums/en-US/xnagamestudioexpress/thread/bc9588a9-542f-425b-9025-d69fe2b0b182/
You can set the Form.StartPosition property, or just manually write to the Left and Top properties of the form you want to move.
Option 1: You could set the appropriate properties on the window/form if a debugger is attached.
if (System.Diagnostics.Debugger.IsAttached)
{
// Set the window/form's top/left properties.
}
Option 2: Add a command line switch, use that as startup parameter (Properties->Debug->Commandline arguments), and then set the appropriate properties in the window/form:
private void Application_Startup(object sender, StartupEventArgs e)
{
if (e.Args.Any(arg => arg.Equals("/debugmode", StringComparison.OrdinalIgnoreCase))
// Set some value which you check in your main window.
}
Although you are not using winforms, you still change it in Xna by using winforms objects. I know you found a solution but here is how to change it without using interop.
Add a reference to System.Windows.Forms and System.Drawing to the References in the game project.
Resist the temptation to add using statements for these as it can cause ambiguity with some Xna objects (Point, for instance, which in Xna uses floats).
In the Game.Initialize method:
System.Drawing.Point p = new System.Drawing.Point(2000, 400);// or wherever you want
System.Windows.Forms.Control c = Control.FromHandle(this.Window.Handle);
c.Location = p;
the game window will now start at the screen 2000,400 location.
I would just call it the "main application window". Anyway, assuming you're using WinForms, this would put the window in the top left corner of the first screen that isn't your primary screen:
void Form1_Load(object sender, EventArgs e)
{
#if DEBUG
Location = Screen.AllScreens.First(s => !s.Primary).Bounds.Location;
#endif
}
If you've only got two monitors hooked up, it'll work fine. You could also get more creative and center the application window on the other monitor, maximize it, whatever. The #if could be substituted with if (System.Diagnostics.Debugger.IsAttached) as suggested by #Daniel if you wanted. I used the former just to present another alternative.

set Cursor to desired point c#

Im trying to move my cursor according to my hand point in kinect, I can get the real coordinates I mean I can move an image on screen but I want real cursor to be settled according to my hand coordinates. I tried Console.SetCursor(x,y) but it gives exception I also tried to download windows forms dll but I cant find the version 4.00 . Is there any simple way to set cursor in a desired position? (which is working by the way and as I said Console.SetcursorPosition is not wodking?)
You didn't provide very much information about you app but I suspect that you just need to assign to Cursor.Position from System.Windows.Forms. You may need to add a reference to System.Windows.Forms in order to gain access to this, depending on exactly what type of project you have.
If you want to keep it lightweight and avoid taking a reference to WinForms then you could just pinvoke to SetCursorPos.
[DllImport("user32.dll")]
static extern bool SetCursorPos(int X, int Y);
Just use
Cursor.Position = new Point();
You can find more information's here
Thank you for question and answer.
I found strange and unobvious behavior.
Let you use multi-monitor (two or three monitor) configuration, and use two windows in your application.
One window is active, and you set cursor position for second windows.
And this two windows located on different monitors.
Then, you need call SetCursorPos TWICE!
TWICE, who would have thought?
Firs call move cursor to virtual borderline between monitors.
And only second call move cursor to required position second window!
Example of code (after 6 hours of experiments):
SetForegroundWindow(this.Handle); // set second window active
SendMessage(this.Handle, 0x20, this.Handle, (IntPtr)1); // Send WM_SETCURSOR
SetCursorPos(400, 600);
Thread.Sleep(50);
SetCursorPos(400, 600);

Categories

Resources