C# Setting cursor position - different results with WinForms and WPF - c#

I have a strange problem. I am trying to set the cursor position with WPF. So far so good. The problem is the following:
On my computer screen (1920x1080, 100% windows scaling) everything works fine, but on my surface laptop (3000x2000, 200% windows scaling) I have run into some problems. Because of the scaling factor the "new resolution" is 1500x1000 (because of the 200% every pixel is "twice as big").
When I set the cursor to 750, 500 with WinForms the cursor appears in the exact middle of the screen but when I set the cursor position to the same point with WPF the cursor appears in the upper left section.
So apparently WinForms uses the resolution 1500x1000 and WPF uses the resolution 3000x2000 when setting the cursor position...
Why are they using different resolutions here? This doesn't make sense to me. Because when I am reading the ScreenWidth and Height with
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width // and Height, WinForms
and
System.Windows.SystemParameters.PrimaryScreenWidth // and Heigth, WPF
both are showing 1500x1000.
Can anyone help me? Maybe it is just a WPF/WinForms difference?
Code to set cursor:
Cursor.Position = p; // with imported System.Windows.Forms;
// or (tryed both)
[DllImport("User32.dll")]
private static extern bool SetCursorPos(int X, int Y);
SetCursorPos(p.X, p.Y);
First post so please don't kill me!

I am not an expert in this topic, but maybe:
WPF uses vector graphics to render things, and has a native support for scaling. If you change font size in Windows to 200%, every WPF application will be 2x bigger.
But in WinForms, if you didn't write your application correctly, scaling can ruin your UI.
To avoid this, if you run WinForms app (in Windows 10) it will just use 100% font size and it will stretch rendered image to 200% size. So you can see for example blurry text. If image is stretched - screen coordinates must be stretched too.
But that's just my guess, I'm not an expert at this.

Related

RectangleToScreen and Windows Zoom Factor

I use this (C# .NET) call to quickly get an image of a control.
Rectangle rectToCapture = myControl.RectangleToScreen(myControl.Bounds);
However, this only works if my Windows display scaling is set to 100%. If I set the display scaling to 125% this rectangle is totally wrong. How can I capture the correct rectangle regardless of scaling?
Per #Jimi I had to make the form DPIAware.
https://social.msdn.microsoft.com/Forums/windows/en-US/4d3979d4-88df-44af-8b66-16b1d4d41d57/issue-with-vs2015-windows-form-dpi-and-screen-resolution?forum=winforms

Problem with Fullscreen Resolution in Mono Game

a couple days ago I started game developing in MonoGame with Visual Studio 2017 and porting my code which i wrote in WinForms to MonoGame. Now I have a problem with the fullscreen mode. I searched the internet and the only thing I found out is that it depends on the resolution the monitor has.
In the default window mode of the application the screen looks like follows:
Now when I switch to fullscreen mode - this happens:
Now my problems are:
One can not see it on the picture because I used the print button and pasted in to paint but the image is largely strechted.
The right part of the screen is cut off
the sprites are moved to the top.
I'm using
graphics.ToggleFullScreen();
Is there a way to keep the original status like it is in window mode? Maybe to put flexible bars for a 4:3 mode and keep the sprite positions? My positions are fixed. So use something like
spriteBatch.Draw(Params.CUR_SPRITE_P1, new Rectangle(Convert.ToInt32(POSITION_P1.X), Convert.ToInt32(POSITION_P1.Y), 750, 476), Color.White); for the player position and the screen (to implement scrolling).
Or maybe adjust everything in full screen mode bu keep the positions of the sprites on different screen resolutions...
Thank you a lot!
Ok after searching and searching I finally found an answer:
var scaleX = (float)ActualWidth / VirtualWidth;
var scaleY = (float)ActualHeight / VirtualHeight;
var matrix = Matrix.CreateScale(scaleX, scaleY, 1.0f);
spriteBatch.Begin(transformMatrix: matrix);
This has to be put in the Draw()-Method.
My virtual screensize was 800x480. I tested it with my Monitor size 1920x1080 and this did the job.

Windows desktop coordinate system is off for certain windows

I've run into an issue when developing some software for windows, an issue related around moving windows on the screen.
Basically, I've found that specific windows will consitantly not follow the coordinate system. I have a function that takes a window and a ratio, then scales up the window to the max size it can be (in that ratio) and still be within the working area of the monitor (not going over the edges or the taskbar).
Example 1: The function works as intended, sizes the window (VSCode) to be the max size it can be in 4:3, and puts it in the corner of the screen (using SetWindowPos and passing in 0,0 for the coords).
Example 2: The exact same function is run on a different window (Firefox) and it is again resized to 4:3 and set to 0,0. However, this time you can see the window isn't quite in the corner, off by 8 pixels to be exact. If I fetch the window position with the api call for that, it returns 0,0, even though it clearly is not. If I manually snap it into the corner myself, then it returns -8,0.
I have no idea what's wrong or how to fix it. It always happens on the same windows, not exactly sure but I think it has something to do with the type of titlebar the window has.
The only other person I've ever seen with this problem is here: https://answers.microsoft.com/en-us/insider/forum/insider_wintp-insider_desktop/desktop-coordinate-system-is-broken/9e6fd9ab-6d27-45e0-bb55-4c868cd6ac45
Unfortunately, he never got a real answer, so I'm back to square one.
So, any ideas of some way to consistently set windows to actually be in the corner? I've come up with some janky solutions by like trying to dynamically find how much a window offsets from the corner but it's not really something I want to be relying on. Is this just a bug with windows and I'm stuck?
Thanks, let me know if you have any questions!
This is the design of windows system.
I saw similar questions long ago.
Windows 10 has thin invisible borders on left, right, and bottom, it is used to grip the mouse for resizing. The borders might look like this: 7,0,7,7 (left, top, right, bottom).
The borders are invisible in Windows 10, so it appears that the window is in the wrong place. Visual Studio IDE has its own tool-windows, when tool-window is docked, it uses no borders or custom NC_PAINT; and when its tool-window is floating, it uses default borders.
A workaroud:
RECT rect, frame;
GetWindowRect(hwnd, &rect);
DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame, sizeof(RECT));
//rect should be `0, 0, 1280, 1024`
//frame should be `7, 0, 1273, 1017`
RECT border;
border.left = frame.left - rect.left;
border.top = frame.top - rect.top;
border.right = rect.right - frame.right;
border.bottom = rect.bottom - frame.bottom;
//border should be `7, 0, 7, 7`
Then offset the rectangle like so:
rect.left -= border.left;
rect.top -= border.top;
rect.right += border.left + border.right;
rect.bottom += border.top + border.bottom;
//new rect should be `-7, 0, 1287, 1031`
For more information, please refer #Barmak Shemirani's answer.
Similar case:
Retrieve Window Size without Windows Shadows
GetWindowRect returns a size including “invisible” borders
Note: DwmGetWindowAttribute() returns physical coordinates, but GetWindowRect() returns logical coordinates. So the border width will be wrong for a non-DPI aware application on a screen scaled to anything other than 100%.

Build android app as a unity stand-alone (for use on a PC) while maintaining correct aspect ratio

I am attempting to build my Unity Android app (1080 x 1920 res) so that it can also run on PC (1920 x 1050 res). To do this, I need to fit vertically to the computer screen while maintaining the correct aspect ratio. I'm nearly there.
I'm using the following code to scale my app resolution down to fit the vertical 1080 of the monitor (android vertical 1920 down to monitor vertical 1080):
#if UNITY_STANDALONE
Screen.SetResolution(608, 1080, false);
Screen.fullScreen = false;
#endif
popUpConfirmRemove.enabled = false;
This works for the most part (after I manually set the pivots of each gameObject corners of the that transform). However, I have a scroll rect UI element, that doesn't scale correctly! That is because there is a vertical layout group on the scroll content that automatically adjusts the pivots.
When I build scale my app to fit on PC, the scroll content doesn't adjust properly.
I would love some help with this!
How do I scale my Scroll Rect - Vertical layout group contents?
Thank you
Have you stretched anchors to full?
Use cntrl key on anchor selection and try the last option.
Try setting the CanvasScaler to "Scale With Screen Size" and set your reference resolution to match your Android app (1080 x 1920) so all UI layout calculations are done to that target resolution. If the aspect ratio is the same it shouldn't matter what you set the Screen Match settings too.

creating resolution independent winform,set resolution for C# winform, get the screen resolution on which the winform is running

I made an application on 1366x768 resolution which is my laptop's current resolution, being a beginner, i din't care about the resolution issues.
When i took that application and executed it on a lower resolution PC , then all was messed up. The form was going somewhere else, most of its part hidden.
So, please help me to how to make my winform resolution independent, or how to get the current screen resolution and set it into my winform so that it changes itself accordingly.
The property
Screen.PrimaryScreen.WorkingArea
is very useful for form sizing and positioning.
For example this code:
this.Width = Screen.PrimaryScreen.WorkingArea.Width/2;
this.Height = Screen.PrimaryScreen.WorkingArea.Height/2;
this.Top = (Screen.PrimaryScreen.WorkingArea.Top + Screen.PrimaryScreen.WorkingArea.Height)/4;
this.Left = (Screen.PrimaryScreen.WorkingArea.Left + Screen.PrimaryScreen.WorkingArea.Width)/4;
(The Screen class is a member of System.Windows.Forms namespace)
will place the form in which it is executed in the middle of the screen and size it to half the screen.
The WorkingArea var is used to exclude stuff like the task bar and other docked items on the desktop when calculating the size of the screen.
Hope this helps.
See here: http://social.msdn.microsoft.com/forums/en-US/vbgeneral/thread/1be40692-80fa-42ba-b316-9fe13a935b4f/ and here: http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/d5f2cd8d-d24d-4574-ba3a-96e22e3d1b56/
General approach is to start with the min resolution you'll be working with. Then you can scale your forms up (using proper docking and anchors).

Categories

Resources