2014-07-01 12 views
15

Ustawienie suwaka "Zmień rozmiar wszystkich elementów" z Control Panel\Appearance and Personalization\Display na Większy (zmieniający ten wpis rejestru: HKEY_CURRENT_USER\Control Panel\Desktop\DesktopDPIOverride) powoduje, że metoda Control.PointToScreen() jest nieprawidłowo obliczana. To może być powielana używając następującej Klasa1 w Windows Form:Nieprawidłowa metoda PointToScreen przy użyciu DesktopDPIOverride

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(); 
    } 
} 

Stosując tę ​​kontrolę w WinForm i klikając na to działa zgodnie z oczekiwaniami. Teraz zmień "Zmień rozmiar wszystkich elementów" na "Większy" i ponownie uruchom kod - kod nie działa już zgodnie z oczekiwaniami, metoda PointToScreen zwraca błędną wartość dla (0, 0).

Czy ktoś wie, jak rozwiązać ten problem? Wielkie dzięki.

+2

Rysowanie PaintEventArgs.ClipRectangle nigdy nie ma sensu. –

+0

Widzę to samo zachowanie. Czy kiedykolwiek znalazłeś rozwiązanie? – adv12

+0

@HansPassant, interesującym bitem nie jest 'Draw (e.ClipRectangle, e.Graphics)' ale wyniki 'Control.PointToScreen' na wyświetlaczu innym niż 100% -DPI, jak narysowane przez wywołanie' DrawReversibleFrame' . Obserwowałem to samo zachowanie: PointToScreen wydaje się być uszkodzony, gdy działa automatyczne skalowanie. Jakieś wrażenia z tego/myśli? – adv12

Odpowiedz

1

Wygląda na to, że musisz zdać sobie sprawę z DPI. Możesz to zrobić tak, aby

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

static void Main() 
{ 
    SetProcessDPIAware(); 

} 
Powiązane problemy