Как эффективно использовать на рабочем столе на С#?

Я хочу рисовать прямо на рабочем столе в С#. От поиска немного, я закончил использование объекта Graphics из Desktop HDC (null). Затем я нарисовал его с использованием этого объекта Graphics.

Проблема в том, что мои фигуры теряются, когда какая-либо часть экрана перерисовывается. Я пробовал цикл While, но на самом деле он заканчивается так же быстро, как и приложение, что не является скоростью обновления рабочего стола.

Как правило, мне нужно будет поместить мой код чертежа в событие "OnPaint", но этого не существует для рабочего стола.

Как мне это сделать?

Пример кода: qaru.site/info/327400/...

Ответы

Ответ 1

Когда вы рисуете на HDC (NULL), вы рисуете на экране неуправляемым способом. Как вы обнаружили, как только окна обновят эту часть экрана, ваши изменения будут перезаписаны.

Есть несколько вариантов, в зависимости от того, чего вы хотите достичь:

  • создать без полей, возможно непрямоугольное окно. (Использование SetWindowRgn сделать окно непрямоугольный.) Вы можете сделать это дочерним элементом окна рабочего стола.
  • подкласс рабочего окна. Это непросто и включает в себя инъекции DLL в Explorer.exe.

Ответ 2

Я разместил два решения для аналогичного требования здесь

В принципе у вас есть два варианта.

1- Получить графический объект для рабочего стола и начать рисовать его. Проблема в том, что вам нужно начать очищать то, что вы ранее нарисовали и т.д.

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- Второй вариант, который я предоставляю в приведенной выше ссылке, - это создать прозрачное верхнее окно и сделать весь ваш чертеж в этом окне. Это в основном обеспечивает прозрачный оверлей для рабочего стола, на который вы можете рисовать. Одним из возможных недостатков этого, как я уже упоминал в первоначальном ответе, является то, что другие окна, которые также являются самыми большими и создаются после запуска вашего приложения, затмевают ваше самое верхнее окно. Это можно решить, если это проблема.

Для варианта 2, делая прозрачную форму так же просто, как использование ключа прозрачности, это позволяет щелчкам мыши и т.д. попадать на основной рабочий стол.

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

Ответ 3

Чтобы получить OnPaint для рабочего стола, вам нужно подклассировать окно рабочего стола и использовать логику рисования, когда он получит сообщение WM_PAINT/WM_ERASEBKGND.

Как поток, с которым вы ссылаетесь, говорит, что вы можете перехватывать сообщения, отправленные в окно внешнего процесса, используя крючок (SetWindowsHookEx из DLL).

Как уже упоминалось, прозрачным окном является другой способ сделать это или (в зависимости от частоты обновления) копирование, рисование и установка временных обоев (в качестве bginfo).

Ответ 4

Это трудно сделать правильно.

Будет намного проще и надежнее создать вместо вас собственную форму без полей.