Pregunta

Estoy escribiendo un programa que usa <= > para hacer agujeros transparentes en una ventana que pertenece a otro proceso. (Esto se hace solo cuando el usuario lo solicita explícitamente).

El programa debe suponer que la ventana de destino ya puede tener agujeros que deben conservarse, por lo que antes de llamar a SetWindowRgn, llama a GetWindowRgn para obtener la región actual, luego combina la región actual con la nueva y llama a SE_DEBUG_NAME:

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

Esto funciona bien en XP, pero la llamada a AdjustTokenPrivileges falla en Vista. Intenté apagar Aero y elevar el privilegio de mi hilo a <=> con <=> , pero ninguno ayuda.

GetLastError () no parece devolver un valor válido para GetWindowRgn: devuelve 0 en una máquina y 5 (acceso denegado) en otra.

¿Alguien puede decirme qué estoy haciendo mal o sugerir un enfoque diferente?

¿Fue útil?

Solución

¿Está seguro de que su ventana tiene una región? La mayoría de las ventanas de nivel superior en XP lo hacen, simplemente porque el tema predeterminado las usa para las esquinas redondeadas ... pero esto sigue siendo una mala suposición, y es muy posible que no se mantenga una vez que llegue a Vista.

Si aún no ha configurado una región y la llamada falla, use un valor predeterminado razonable (el rectificador de ventana) y no permita que arruine su vida. Ahora, si SetWindowRgn() falla ...

Otros consejos

En Vista, para que un proceso que no se ejecuta como administrador apunte a una ventana desde otro proceso, debe:

  • Incruste un archivo de manifiesto con uiAccess = " true " (ejemplo a continuación)
  • Firme digitalmente la aplicación
  • Instalarlo y ejecutarlo desde " safe " lugar, como " Archivos de programa "

Aquí hay un manifiesto de muestra:

<?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>

Menciona que está intentando obtener la región de la ventana de otro proceso . Vista reforzó la seguridad de muchas llamadas entre procesos de Win32. No puedo encontrar ninguna documentación de una manera u otra para GetWindowRgn(), pero podría probarla de manera simple. Haga un proyecto simple que establezca su propia región e intente usar su aplicación original para obtener la región de la aplicación simple. Si funciona, entonces será molesto y la gente no podrá usar su aplicación en cualquier cosa. Si no funciona, existe la posibilidad de que su aplicación no funcione en Vista.


Mi respuesta (basada en mi experiencia) con respecto a la función API de Windows :: GetWindowRgn (...)

Esta función falla en Vista y en Windows 7, es decir, devuelve ERROR.

Pero esta función funciona bien en Windows XP.

Por lo tanto, recomendaría la siguiente solución no compleja:   Si usa esta función dentro de una aplicación que se espera que se ejecute   bajo diferentes Windows, proporcione la prueba de esta manera:     int nResultOfRgnOperation = :: GetWindowRegion (...);     if (nResultOfRgnOperation! = ERROR)       < Utilice más toda la región de la ventana determinada por esta función & Gt;     más       < Encuentre el rectángulo delimitador para toda la ventana y use         más allá de ese rectángulo delimitador en lugar de la región de la ventana.         En necesario, puede crear una región rectangular que representa         El rectángulo delimitador. >

Utilice el código correspondiente en los lugares marcados anteriormente como < ... >

Gracias por su entusiasmo.


Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top