GetWindowRect возвращает неправильное значение, если окно находится справа внизу

Я пытаюсь получить положение окна с помощью его дескриптора. Затем я хочу нарисовать крест в позиции Windows 0, 0 так (блокнот находится в левом верхнем углу дисплея):

how it should look

но если я перемещаю блокнот в правый нижний угол, это выглядит так:

enter image description here

Это совершенно странно для меня. Я записал значения rect.Left и rect.Top и сравнил их со значениями Spy++, они были одинаковыми.

Что я пробовал: из user32.dll:

GetWindowRect(handle, out var rect);

из dwmapi.dll:

DwmGetWindowAttribute(handle, DWMWINDOWATTRIBUTE.ExtendedFrameBounds, out var rect, size);

Это работало немного лучше, но все еще то же поведение.

Кто-нибудь знает способ найти окна 0, 0 самостоятельно, где находится окно?

Можем ли мы увидеть код, где вы рисуете крест? И показаны фактические числовые значения из прямоугольника в обоих случаях?

15ee8f99-57ff-4f92-890c-b56153 22.05.2019 16:45

Каков уровень осведомленности о DPI в вашей программе?

Raymond Chen 22.05.2019 17:08

Вот весь код pastebin.com/pzrufqaR (извините, он немного неструктурирован, но я думаю, вы можете видеть, как он нарисован). Важная часть находится в методе Render. Он нарисован в прозрачной форме окна (настройки: BackColor: Black, FormBorderStyle: None, ShowIcon: false, ShowInTaskBar: false, TopMost: true, WindowState: Maximized)

Markus Gauwatz 22.05.2019 17:11

GetWindowRect() говорит много лжи о совместимости приложений. Начните с объявления вашего приложения быть в курсе. Рассмотрим GetClientRect(). И считайте, что никогда не нужно этого делать.

Hans Passant 22.05.2019 17:14

Хорошо, похоже, это не имеет ничего общего с GetWindowRect. когда я рисую с помощью GDI на рабочем столе (GetDC(IntPtr.Zero)) крест идеально помещается в верхнем левом углу. Так что это как-то связано с рисованием DirectX в прозрачной полноэкранной форме.

Markus Gauwatz 22.05.2019 23:45
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
2
5
390
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Direct3D использует мировую систему координат, а GetWindowRect получает координату экрана. Это проблема.

Вместо этого нарисуйте линию другим методом, например, классом Graphics:

Graphics g;
g = this.CreateGraphics();
Pen myPen = new Pen(Color.Red);
myPen.Width = 1;
g.DrawLine(myPen, point1x, point1y, point2x, point2y);

Кроме того, независимо от проблемы, строка кода в вашей ссылке:

SetWindowLong(this.Handle, GWL_EXSTYLE,(IntPtr)(GetWindowLong(this.Handle, GWL_EXSTYLE) ^ WS_EX_LAYERED ^ WS_EX_TRANSPARENT));

если вам нужны дополнения стиля, вам следует:

SetWindowLong(this.Handle, GWL_EXSTYLE,(IntPtr)(GetWindowLong(this.Handle, GWL_EXSTYLE) | WS_EX_LAYERED | WS_EX_TRANSPARENT));
Ответ принят как подходящий

наконец, я нашел проблему сам. мне пришлось снова установить для FormWindowState значение Normal, а для FormBorderStyle — None, но не в конструкторе, а в методе InitDevice вверху. После этого я установил границы формы на границы экрана, и все. Теперь он работает именно так, как ожидалось.

Другие вопросы по теме