the runtimes microsoft c# windows directx

c# - runtimes - DirectX Desktop



microsoft directx (3)

Me gustaría crear un fondo de escritorio animado para Windows 7 utilizando DirectX. Estoy usando C #, SlimDX y un par de importaciones P / Invoke de las funciones de la API de Windows. No soy brillante con la programación nativa de Windows, pero he tenido un empujón en línea y creo que lo que tengo que hacer es:

1) Encuentre el controlador de la ventana que contiene el fondo de escritorio dekstop, conéctelo a un dispositivo DirectX y dibuje en él.

2) Cree una nueva ventana de salida e insértela encima del fondo de escritorio pero debajo de los iconos del escritorio.

He intentado ambos, pero ninguno parece funcionar. Si navego por la jerarquía de Windows a partir del identificador devuelto por GetDesktopWindow (), puedo ir a Escritorio -> TrabajadorW -> SHELLDLL_DefView -> SysListView32. Si conecto un dispositivo DirectX a este identificador, puedo dibujar sobre todo el escritorio, pero también cubre los iconos. Si creo un formulario de Windows, configuro su padre a SHELLDLL_DefView usando SetParent () y luego uso SetWindowPos para jugar con su orden Z, parece que solo puedo ir detrás del fondo de pantalla del escritorio o delante del escritorio + los iconos.

Parece que el fondo de pantalla del escritorio es un fondo de la vista de carpeta que contiene los iconos, y por lo tanto, lo que estoy tratando de hacer no puede funcionar. La única solución entonces sería no usar el escritorio para los iconos, o buscar alguna alternativa, por ejemplo, sobrescribir el escritorio y luego superponer una ventana transparente que contiene una vista del contenido de alguna carpeta.

¿Alguien tiene alguna idea de lo que debería estar haciendo, o incluso si lo que quiero hacer es posible? Parece que puedes dibujar en el fondo del escritorio utilizando el GDI (como creo que hace el programa wxSnow), y he visto algo similar a lo que quiero que haga VLC Media Player en Windows XP con su modo de fondo de pantalla DirectX (curiosamente, Parece que no puedo activar esta opción en mi sistema).

¡Gracias!


He hecho algunas animaciones de ventanas combinadas alfa que siempre están en la parte superior de la Orden Z. Una idea sería ignorar el intento de modificar el mapa de bits del escritorio y simplemente dibujar sus cosas como una ventana en capas, pero administrar ZOrder de alguna manera, por lo que siempre es la ventana que no se encuentra más abajo (tal vez mediante una llamada estratégica a Form.SendToBack() o algo en los momentos correctos).

Dependiendo de lo que esté tratando de hacer, esto puede darle el mismo efecto de animar el escritorio.


Parece que esto podría no ser posible. Vea este enlace:

http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/69839cec-3424-4300-9ac3-486b8c2fe492

Si necesita dibujar algunos controles entre el fondo del escritorio y los iconos del escritorio, a continuación se detalla un paso alternativo:

  1. Crea tu control de usuario en una biblioteca de control de Windows.
  2. Incrustar el control de usuario en un control ActiveX.
  3. Incrustar el control ActiveX en una página web.
  4. Habilite el escritorio activo y configure la página web como fondo de escritorio.

Esto solo se puede hacer en XP ya que Vista no admite el escritorio activo.

Otra publicación allí sugiere que posiblemente podría hacer esto con el fondo de una ventana del explorador, si pudiera obtener el identificador de la ventana que lo constituye. Por supuesto, si eso es posible, también puede ser posible obtener el identificador de la ventana del escritorio detrás de los iconos.

Actualización: Bueno, hasta ahora, lo único que he encontrado que podría "funcionar" es simplemente crear archivos de mapa de bits y cambiar el fondo de pantalla una y otra vez (sospecho que esto sería lento, como mencionaste).

Esa imagen de pantalla completa debe residir en la memoria en algún lugar, pero es posible que no haya forma de acceder a ella sin un hackeo de memoria grave de bajo nivel. Voy a seguir buscando.

Actualización 2: Esto podría funcionar, pero no estoy seguro:

http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/4af734fb-d2c1-414b-a9f1-759b76692802

La carne de esto es esta:

HWND p = FindWindow("ProgMan", NULL); HWND s = FindWindowEx(p, NULL, "SHELLDLL_DefView", NULL); HWND dtw = FindWindowEx(s, NULL, "SysListView32", NULL); HDC hdc = GetDC(dtw);

Básicamente, estás comenzando con la ventana de ProgMan y profundizando desde allí hasta el fondo de escritorio ("SysListView32", supongo). Voy a probar esto

Actualización 3: No, el código anterior obtiene el DC del escritorio, pero está sobre los iconos, por lo que BitBlt dibuja sobre ellos. Sin embargo, no es dibujar en la pantalla, porque puedo dibujar debajo de una forma abierta sin cubrirla, así que al menos eso es progreso.

Supongo que hay otra ventana disponible que no sea "SysListView32" que es el escritorio detrás de los íconos, o que hay más de una ventana "SysListView32".

Actualización 4: Estoy bastante seguro de que algo con esto funcionaría:

http://msdn.microsoft.com/en-us/library/bb761155(v=VS.85).aspx http://msdn.microsoft.com/en-us/library/bb774742(v=VS.85).aspx

Básicamente, es un método API al que llama, pasando a una estructura que incluye un controlador de mapa de bits. Si la llamada es exitosa, ese mapa de bits se convierte en el escritorio.

¿DirectX expone los cuadros como controladores de mapa de bits (compatibles con GDI) o solo expone el DC? En mi caso, mi animación ya es una matriz de mapas de bits compatibles con GDI, por lo que no tendría ningún problema en utilizar este enfoque. Si esta es la única ruta, y DirectX no expone los manejadores de mapa de bits (y no creo que lo hagan), entonces para cada cuadro tendrías que crear un nuevo mapa de bits GDI, que ralentizaría un poco las cosas.

En realidad, podría haber una forma más fácil, aunque no estoy seguro de que funcione. Una vez que obtenga el identificador del mapa de bits real del fondo de pantalla, puede seleccionarlo en el contexto de un dispositivo usando SelectObject y luego usar ese contexto del dispositivo como el destino de BitBlt. Sin embargo, es posible que tenga que enviar una instrucción de repintado al escritorio, lo que podría provocar que los iconos se repinten cada vez.

¿Qué tal si haces algún trabajo aquí? :)


Supongo que podría obtener bastantes fotogramas por segundo generando dinámicamente mapas de bits y configurándolos constantemente como fondo de escritorio. Sin embargo, esto suena innecesariamente (casi estúpidamente) para la CPU. Actualización : Ahora que lo pienso (fue tarde cuando escribí esto), el principal problema con este enfoque es que necesita escribir y leer mapas de bits del disco duro cada vez que se muestre un nuevo marco. Esto no es factible.

¿Realmente estás usando el escritorio para los iconos? En Windows 7, la función de búsqueda del menú de inicio y la nueva barra de tareas me han impedido usar el escritorio para los iconos.

Solo una idea

Podría ser posible alterar la ventana del escritorio, mediante SendMessage (GetDesktopWindow, WM_SOME_MESSAGE, wParam, lParam), para que pueda lograr lo que desea. Podría investigar esto más mañana (actualmente a las 3 am, hora local).