Получение центра экрана

#c# #winforms

#c# #winforms

Вопрос:

Примечание: использование c # windows form в Visual Studio 2017

Приведенный ниже код теперь корректен для дальнейшего использования.

Я пытаюсь разработать код, который поможет мне определить, в каком квадранте находится мышь каждые 0,5 секунды. Сначала я попробовал использовать 0, но обнаружил, что в c # нет отрицательного значения для положения мыши. Поэтому вместо этого я подумал, что буду использовать ширину и высоту, которые я рассчитал с:

  public void setScreenSize()
 {
    int W = Screen.PrimaryScreen.Bounds.Width;
    int H = Screen.PrimaryScreen.Bounds.Height;
    Console.WriteLine("Height is: "   H   "width is: "   W);
 }
  

полный код здесь:

 public partial class Recording : Form
{

    private System.Timers.Timer mousePositionTimer;

    int W, H;


    public Recording()
    {
        InitializeComponent();
    }

    private void Recording_Load(object sender, EventArgs e)
    {
        setScreenSize();
        SetTimer(mousePositionTimer, 250,OnTimedMousePositionEvent);

    }

    public void setScreenSize()
    {
        W = Screen.PrimaryScreen.Bounds.Width;
        H = Screen.PrimaryScreen.Bounds.Height;
        Console.WriteLine("Height is: "   H   "width is: "   W);

    }


    private void SetTimer(System.Timers.Timer t, int millis, ElapsedEventHandler f)
    {
        t = new System.Timers.Timer(millis);
        t.Elapsed  = f;
        t.AutoReset = true;
        t.Enabled = true;
    }

    private void OnTimedMousePositionEvent(Object source, ElapsedEventArgs e)
    {

        record.addMousePosition(W,H,MousePosition.X,MousePosition.Y);
    }



}
  

Затем я использовал следующее для определения квадранта:

 //getting position of mouse in a given quadrant
public static class record
{
     public static void addMousePosition(int w, int h, int x, int y)
     {
         if (x > w/2 amp;amp; y > h/2)
             mousePositions.Add(1);
         else if (x > w/2 amp;amp; y <= h/2)
             mousePositions.Add(2);
         else if (x <= w/2 amp;amp; y <= h/2)
             mousePositions.Add(3);
         else if (x <= w/2 amp;amp; y > h/2)
             mousePositions.Add(4);
     }
}
  

Однако, когда я печатаю свой список, я всегда получаю квадрант 1. Есть ли лучший способ получить центр экрана, чтобы я мог правильно выполнять свои условия?

Пожалуйста, помните, что я пытаюсь сделать это вне формы и не обязательно на ней.

Комментарии:

1. Пожалуйста, покажите нам, где вы используете addMousePosition() метод. Также похоже, что вы настроили свой ScreenCenter только на локальный W и H вашего setScreenSize() . Таким образом, может случиться так, что вы вызываете свою проверку с 0 по умолчанию в w и h , что приведет к квадранту 1.

2. Мне не хватает некоторых переменных в предоставленном коде. Первая функция setScreenSize заполняет две локальные переменные. addMousePosition использует четыре параметра, но неизвестно, откуда они берутся. Особенно интересен второй, поскольку он определяет if / else в подпрограмме

3. setScreenSize() вызывается при загрузке формы

4. Добавьте MousePosition внутри статического класса, и он получит значения W и H, заданные setScreenSize();

5. Правильные ли значения screensize вы получаете? Убедитесь, что приложение объявлено с поддержкой DPI. Как вы определяете положение мыши?

Ответ №1:

Проблема с областью действия?

 public void setScreenSize()
{
    int W = Screen.PrimaryScreen.Bounds.Width;
    int H = Screen.PrimaryScreen.Bounds.Height;
    Console.WriteLine("Height is: "   H   "width is: "   W);
}
  

Для

 public void setScreenSize()
{
    W = Screen.PrimaryScreen.Bounds.Width;
    H = Screen.PrimaryScreen.Bounds.Height;
    Console.WriteLine("Height is: "   H   "width is: "   W);
}
  

Ответ №2:

Я бы создал 4 Rectangle секунды, а затем использовал Rectangle.Contains , чтобы проверить, где находится мышь:

 Rectangle topLeft, topRight, bottomLeft, bottomRight;

void CalculateQuadrants(Form mainForm)
{
     Screen myScreen = Screen.FromControl(mainForm);
     Rectangle area = myScreen.WorkingArea;
     topLeft = new Rectangle(area.Left, area.Top, area.Right/2, area.Bottom/2);
     topRight = new Rectangle(area.Right/2, area.Top, area.Right/2, area.Bottom/2);
     bottomLeft = new Rectangle(area.Left, area.Bottom/2, area.Right/2, area.Bottom/2);
     bottomRight = new Rectangle(area.Right/2, area.Bottom/2, area.Right/2, area.Bottom/2);
}
  

Затем вы можете сделать простой .Содержит для проверки указателя мыши:

 public static void addMousePosition(Point mousePosition)
{
    if (topLeft.Contains(mousePosition))
        mousePositions.Add(1);
    else if (topRight.Contains(mousePosition))
        mousePositions.Add(2);
    else if (bottomLeft.Contains(mousePosition))
        mousePositions.Add(3);
    else if (bottomRight.Contains(mousePosition))
        mousePositions.Add(4);
}
  

Комментарии:

1. Мне нужно, чтобы это работало в зависимости от размера экрана, форма будет свернута при их обнаружении

2. Экран. FromControl получит границы экрана, на котором выполняется «большая часть» формы, независимо от того, сколько экранов подключено.

Ответ №3:

Подводя итог моим комментариям выше:

При вызове setScreenSize() из OnFormLoad() вы будете устанавливать только локальные переменные, W и H которые вы определили в своих методах.

 public void setScreenSize()
{
    int W = Screen.PrimaryScreen.Bounds.Width;
    int H = Screen.PrimaryScreen.Bounds.Height;
    Console.WriteLine("Height is: "   H   "width is: "   W);
}
  

Таким образом, эти переменные скроют ваши поля, которые вы объявили в

 public partial class Recording : Form
{
    private System.Timers.Timer mousePositionTimer;

    int W, H;

    ...
}
  

Итак, поскольку поля класса не инициализированы, они имеют свое default(int) значение 0 .

Когда вы теперь вызываете свой addMousePosition() , вы всегда будете использовать значения по умолчанию 0 вместо реальных значений, которые вы сохранили в локальном int H и int W

 private void OnTimedMousePositionEvent(Object source, ElapsedEventArgs e)
{
    record.addMousePosition(W,H,MousePosition.X,MousePosition.Y);
}

public static void addMousePosition(int w, int h, int x, int y)
{
    if (x > w/2 amp;amp; y > h/2)
        mousePositions.Add(1);
     else if (x > w/2 amp;amp; y <= h/2)
         mousePositions.Add(2);
     else if (x <= w/2 amp;amp; y <= h/2)
         mousePositions.Add(3);
     else if (x <= w/2 amp;amp; y > h/2)
         mousePositions.Add(4);
 }
  

и так ваш код будет Add(1) большую часть времени. Только в верхнем левом углу вашего экрана вы должны попасть в Add(3) ветку.

Таким образом, удаление int перед локальным W и H устранит проблему.

 public void setScreenSize()
{
    W = Screen.PrimaryScreen.Bounds.Width;
    H = Screen.PrimaryScreen.Bounds.Height;
    Console.WriteLine("Height is: "   H   "width is: "   W);
}
  

Для пояснения я рекомендую использовать this. :

 public void setScreenSize()
{
    this.W = Screen.PrimaryScreen.Bounds.Width;
    this.H = Screen.PrimaryScreen.Bounds.Height;
    Console.WriteLine("Height is: "   this.H   "width is: "   this.W);
}
  

Узел сайта:

упс, вы правы! Интересно, почему он не жаловался на это

Я также думал, что VS2017 даст подсказку об этом, но этого не произошло. Resharper предоставляет подсказку:

Локальная переменная H скрывает поле int Recording.H