¿Cómo dibujar efectivamente en el escritorio en C #?

Quiero dibujar directamente en el escritorio en C #. Después de buscar un poco, terminé usando un objeto Graphics del Desktop HDC (nulo). Luego, pinté normalmente usando este objeto Graphics.

El problema es que mis formas se pierden cuando se vuelve a dibujar cualquier parte de la pantalla. Probé un ciclo While, pero en realidad termina dibujando tan rápido como la aplicación puede, que no es la tasa de actualización del escritorio.

Normalmente, necesitaría poner mi código de dibujo en un evento “OnPaint”, pero tal cosa no existe para el escritorio.

¿Cómo lo haría?

Código de ejemplo: https://stackoverflow.com/questions/1536141/how-to-draw-directly-on-the-windows-desktop-c

Cuando dibuja en HDC (NULO) dibuja en la pantalla, de una manera no administrada. Como ha descubierto, tan pronto como Windows actualiza esa parte de la pantalla, sus cambios se sobrescriben.

Hay un par de opciones, dependiendo de lo que quiere lograr:

  1. crea una ventana sin bordes, posiblemente no rectangular. (Use SetWindowRgn para hacer que una ventana no sea rectangular.) Puede hacer que esto sea un elemento secundario de la ventana del escritorio.
  2. subclase de la ventana del escritorio. Esto no es sencillo e implica inyectar una DLL en el proceso Explorer.exe.

Publiqué dos soluciones para un requisito similar aquí

Básicamente tienes dos opciones.

1- Obtenga un objeto gráfico para el escritorio y comience a dibujarlo. El problema es si necesita comenzar a borrar lo que ha dibujado previamente, etc.

Point pt = Cursor.Position; // Get the mouse cursor in screen coordinates using (Graphics g = Graphics.FromHwnd(IntPtr.Zero)) { g.DrawEllipse(Pens.Black, pt.X - 10, pt.Y - 10, 20, 20); } 

2- La segunda opción que proporciono en el enlace anterior es crear una ventana superior transparente y hacer todo el dibujo en esa ventana. Esto básicamente proporciona una superposición transparente para el escritorio que puede dibujar. Una posible desventaja de esto, como menciono en la respuesta original, es que otras ventanas que también son de primerísima calidad y que se crean después de que se inicie la aplicación oscurecerán su ventana superior. Esto se puede resolver si es un problema.

Para la opción 2, hacer que el formulario sea transparente es tan simple como usar una clave de transparencia, esto permite que los clics del mouse, etc. caigan al escritorio subyacente.

 BackColor = Color.LightGreen; TransparencyKey = Color.LightGreen; 

Para obtener un OnPaint para el escritorio, necesitaría subclasificar la ventana del escritorio y usar su lógica de dibujo cuando reciba un mensaje WM_PAINT/WM_ERASEBKGND .

Como dice el hilo al que vinculó, solo puede interceptar mensajes enviados a una ventana de un proceso externo utilizando un SetWindowsHookEx ( SetWindowsHookEx desde una DLL).

Como se mencionó, una ventana transparente es otra forma de hacerlo, o (dependiendo de la frecuencia de actualización) copiar, dibujar y establecer un fondo de pantalla temporal (como lo hace bginfo ).

Esto es difícil de hacer correctamente.

Será mucho más fácil y más confiable hacer su propia forma sin bordes.