GetWindowRect, слишком небольшой в Windows 7

Фактическая проблема, которую я пытаюсь решить, я хочу автоматически узнать размер полей вокруг окон. Если можно найти лучший путь, любой ценой ответить на это вместо этого.

Чтобы сделать это, я решил сделать снимок экрана тестового окна и измерить поля. Это достаточно просто, поскольку я ожидаю, что никакие поля никогда не будут ярким розовым, но я признаю, что это - взлом. Я использую GetWindowRect (py), чтобы заставить ограничительную рамку и PIL захватывать снимок экрана и обрезку к ограничительной рамке. Проблема состоит в том, что, в то время как обрезка работает правильно, ограничительная рамка не точна. Windows 7 "Отрезание Инструмента" получает корректные размеры. Как я могу сделать то же?

12
задан Devin Jeanpierre 7 July 2010 в 05:53
поделиться

3 ответа

Мои первые мысли были перечислены ниже, но если, как вы утверждаете, вы уверены, что 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));

, и это должно дать вам правильный ограничивающий прямоугольник.

18
ответ дан 2 December 2019 в 06:25
поделиться
1
ответ дан 2 December 2019 в 06:25
поделиться

сначала вы вызываете GetClientRect, чтобы получить клиентский прямоугольник R1, затем вызовите AdjustWindowRectEx, чтобы вычислить точные границы в соответствии с R1.

1
ответ дан 2 December 2019 в 06:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: