#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