Фактическая проблема, которую я пытаюсь решить, я хочу автоматически узнать размер полей вокруг окон. Если можно найти лучший путь, любой ценой ответить на это вместо этого.
Чтобы сделать это, я решил сделать снимок экрана тестового окна и измерить поля. Это достаточно просто, поскольку я ожидаю, что никакие поля никогда не будут ярким розовым, но я признаю, что это - взлом. Я использую GetWindowRect (py), чтобы заставить ограничительную рамку и PIL захватывать снимок экрана и обрезку к ограничительной рамке. Проблема состоит в том, что, в то время как обрезка работает правильно, ограничительная рамка не точна. Windows 7 "Отрезание Инструмента" получает корректные размеры. Как я могу сделать то же?
Мои первые мысли были перечислены ниже, но если, как вы утверждаете, вы уверены, что GetWindowRect
возвращает неверные значения, см. РЕШЕНИЕ ниже .
«Что не так с GetSystemMetrics (SM_CXBORDER)
и GetSystemMetrics (SM_CYBORDER)
?»
Метод, который вы используете, кажется очень окольным путем, и, если вы можно вызвать GetWindowRect ()
, я почти уверен, что вы также можете вызвать GetSystemMetrics ()
.
Еще одна возможность - использовать GetWindowRect
, чтобы получить весь ограничивающий прямоугольник для окна, и GetClientRect
, чтобы получить ограничивающий прямоугольник для клиентской (не граничной) области.
Это должно дать вам что-то вроде (100,200), (1000,900)
и (112,227), (988,888)
соответственно, и вы можете потренироваться верхняя граница как 227-200
, нижняя как 900-888
, слева как 112-100
и справа как 900-888
( 27,12,12,12).
РЕШЕНИЕ:
Небольшое расследование обнаруживает это . Это поток из 2006 года, в котором говорится, что вы можете не получить правильные значения из GetWindowsRect
. В ветке, которая указала мне на это, сказано:
Приложения под Vista, которые не связаны с WINVER = 6, получат здесь вводящий в заблуждение набор значений, которые не учитывают дополнительное заполнение «стеклянных» пикселей, которое Vista Aero применяет к окно. Похоже, это происходит даже с Aero Basic (без стекла), чтобы сохранить последовательность размеров. Обходной путь (если вы не хотите устанавливать WINVER = 6), похоже, заключается в динамическом связывании с dwmapi.dll и использовании GetProcAddress () для получения функции DwmGetWindowAttribute () и вызове ее с аргументом DWMWA_EXTENDED_FRAME_BOUNDS для запроса подлинного окна размеры рамы.
В общем, используйте что-то вроде (для этого вам, возможно, придется использовать ctypes из Python):
RECT r;
HRESULT stat = DwmGetWindowAttribute (
hwnd,
DWMWA_EXTENDED_FRAME_BOUNDS,
&r,
sizeof(r));
, и это должно дать вам правильный ограничивающий прямоугольник.
DwmGetWindowAttribute
http://msdn.microsoft.com/en-us/library/aa969515%28VS.85%29.aspx
сначала вы вызываете GetClientRect, чтобы получить клиентский прямоугольник R1, затем вызовите AdjustWindowRectEx, чтобы вычислить точные границы в соответствии с R1.