Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PointToScreen incorrect using DesktopDPIOverride

Setting the "Change the size of all items" slider of Control Panel\Appearance and Personalization\Display to Larger (which changes this registry entry: HKEY_CURRENT_USER\Control Panel\Desktop\DesktopDPIOverride) causes the Control.PointToScreen() method to miscalculate. This can be reproduced using the following Class1 in a Windows Form:

public class Class1 : Control
{
  protected override void OnPaint(PaintEventArgs e)
  {
    base.OnPaint(e);

    Draw(e.ClipRectangle, e.Graphics);
  }

  private void Draw(Rectangle rect, Graphics graphics)
  {
    Pen pen = new Pen(Color.Red);
    pen.Width = 2;

    graphics.DrawRectangle(pen, rect);
  }

  protected override void OnMouseDown(MouseEventArgs e)
  {
    base.OnMouseDown(e);

    Point p = this.PointToScreen(new Point(0, 0));

    ControlPaint.DrawReversibleFrame(new Rectangle(p, new Size(e.X, e.Y)), Color.Yellow, FrameStyle.Dashed);
  }

  protected override void OnMouseUp(MouseEventArgs e)
  {
    base.OnMouseUp(e);
    this.Invalidate();
  }
}

Using this control in a WinForm and clicking on it works as expected. Now change "Change the size of all items" to "Larger" and run the code again - the code no longer runs as expected, the PointToScreen method is returning an erroneous value for (0, 0).

Does anybody know how to resolve this issue? Many thanks.

like image 412
Shunyata Kharg Avatar asked Jul 01 '14 14:07

Shunyata Kharg


1 Answers

Sounds like you need to make it DPI aware. You can do it like so

[DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();

static void Main()
{
    SetProcessDPIAware();

}
like image 71
Alex Avatar answered Nov 10 '22 19:11

Alex