Как эффективно рисовать на рабочем столе в C #? - PullRequest
14 голосов
/ 25 мая 2010

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

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

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

Как бы я это сделал?

Пример кода: /1162912/kak-narisovat-pryamo-na-rabochem-stole-windows-c

Ответы [ 4 ]

15 голосов
/ 26 мая 2010

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

В основном у вас есть два варианта.

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; 
8 голосов
/ 25 мая 2010

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

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

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

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

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

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

1 голос
/ 25 мая 2010

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

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

...