Почему GetWindowRgn не работает в Vista?

Я пишу программу, которая использует SetWindowRgn для создания прозрачных отверстий в окне, принадлежащем другому процессу. (Это делается только тогда, когда пользователь явно запрашивает это.)

Программа должна предположить, что в целевом окне уже могут быть дыры, которые необходимо сохранить, поэтому перед вызовом SetWindowRgn она вызывает GetWindowRgn, чтобы получить текущую область, затем объединяет текущую область с новой и вызывает SetWindowRgn:

HRGN rgnOld = CreateRectRgn ( 0, 0, 0, 0 );
int regionType = GetWindowRgn ( hwnd, rgnOld ); 

Это нормально работает в XP, но вызов GetWindowRgn не работает в Vista. Я попытался отключить Aero и повысить привилегию моего потока до SE_DEBUG_NAME с помощью AdjustTokenPrivileges, но ничего не помогает.

GetLastError (), похоже, не возвращает допустимое значение для GetWindowRgn - он возвращает 0 на одном компьютере и 5 (доступ запрещен) на другом.

Может ли кто-нибудь сказать мне, что я делаю не так, или предложить другой подход?

Если в MSDN явно не указано, что вы можете вызвать GetLastError () для получения дополнительных сведений об ошибке, GetLastError () вернет случайное значение. Вы можете вызвать SetLastError (1234) до того, как GetWindowRgn (), и GetLastError () после этого всегда будет возвращать 1234.

Elmue 27.11.2014 17:40
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
1 761
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вы уверены, что ваше окно имеет это регион? Большинство окон верхнего уровня в XP работают просто потому, что тема по умолчанию использует их для закругления углов ... но это все еще плохое предположение, и оно вполне может потерпеть неудачу, когда вы перейдете в Vista.

Если вы еще не установили регион и вызов не работает, используйте разумное значение по умолчанию (прямоугольник окна) и не позволяйте ему разрушать вашу жизнь. Теперь, если SetWindowRgn() выйдет из строя ...

Спасибо, Шог. Ты сделал это. Я предполагал (не осознавая этого), что окна всегда имеют области. Переписал. Теперь, когда GetWindowRgn не работает, он устанавливает область на основе прямоугольника окна. Прекрасно работает. Это лучший ответ, который я получил на форуме за долгое время. /отдать честь

FreddieHKN 28.09.2008 07:53

Вы упоминаете, что пытаетесь получить область окна другой процесс. Vista повысила безопасность многих межпроцессных вызовов Win32. Я не могу найти какую-либо документацию для GetWindowRgn(), но вы можете достаточно просто протестировать ее. Создайте простой проект, который устанавливает собственный регион, и попробуйте использовать свое исходное приложение, чтобы получить регион простого приложения. Если это сработает, то это будет просто раздражать, и люди не смогут использовать ваше приложение ни на чем. Если это не сработает, есть вероятность, что ваше приложение вообще не будет работать в Vista.

Я тестировал собственное приложение. Это было первое, что я сделал. Кроме того, как я уже упоминал (с досадной опечаткой), я повысил уровень привилегий для отладки. Кроме того, когда я писал ранее, я знал, что SetWindowRgn отлично работает в Vista. Я думал маловероятно, что Vista разрешает установку, но запрещает получение.

FreddieHKN 28.09.2008 08:01

В Vista, чтобы процесс, который не запускается от имени администратора, нацелился на окно другого процесса, он должен:

  • Вставьте файл манифеста с uiAccess = "true" (пример ниже)
  • Подпишите заявку цифровой подписью
  • Установите и запустите его из "безопасного" места, например "Program Files"

Вот образец манифеста:

<?xml version = "1.0" encoding = "UTF-8" standalone = "yes"?>
<assembly xmlns = "urn:schemas-microsoft-com:asm.v1" manifestVersion = "1.0">
  <assemblyIdentity version = "1.0.0.0" processorArchitecture = "X86" name = "yourAssemblyNameWithoutExtension" type = "win32"/>
  <trustInfo xmlns = "urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level = "asInvoker" uiAccess = "true" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

Как так хорошо заметил Фредди, это не решает ЕГО проблему. Этот манифест требуется, если вы нацелены на процессы с повышенными или изолированными (например, IE7) от процесса без повышенных прав.

Martin Plante 14.11.2008 22:47


Мой ответ (основанный на моем опыте) относительно функции Windows API :: GetWindowRgn (...)

Эта функция не работает в Vista и Windows 7, то есть возвращает ERROR.

Но эта функция хорошо работает в Windows XP.

Поэтому я бы посоветовал следующее несложное решение: Если вы используете эту функцию в приложении, которое должно быть запущено под другой Windows выполните такой тест: int nResultOfRgnOperation = :: GetWindowRegion (...); если (nResultOfRgnOperation! = ОШИБКА) <Далее использовать всю область окна, определенную этой функцией> еще <Найдите ограничивающий прямоугольник для всего окна и используйте далее этот ограничивающий прямоугольник вместо области окна. При необходимости вы можете создать прямоугольную область, представляющую ограничивающий прямоугольник. >

Используйте соответствующий код в местах, отмеченных выше как <...>

Спасибо за энтузиазм.


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