2009-03-30 3 views
4

Я использую следующий код, чтобы нарисовать на одном мониторе:Рисование поверх всех окон на нескольких мониторах

Point cursorLocation; 
NativeMethods.GetCursorPos(out cursorLocation); 
Screen screen = Screen.FromPoint(cursorLocation); 

Point h1 = new Point(screen.Bounds.Left, cursorLocation.Y); 
Point h2 = new Point(screen.Bounds.Right, cursorLocation.Y); 
Point v1 = new Point(cursorLocation.X, screen.Bounds.Top); 
Point v2 = new Point(cursorLocation.X, screen.Bounds.Bottom); 

using (Graphics graphics = Graphics.FromHwnd(NativeMethods.GetDesktopWindow())) { 
    NativeMethods.SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero); 
    graphics.DrawLine(Pens.Red, h1, h2); 
    graphics.DrawLine(Pens.Red, v1, v2); 
} 

нативно, этот должентеоретически отрисовки на любом мониторе. Однако он использует только первичный. Итак, чтобы исправить это, я получаю DC всех дисплеев и пытаюсь сделать это таким образом.

IntPtr hdc = NativeMethods.CreateDC("DISPLAY", IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); 
Graphics graphics = Graphics.FromHdc(hdc); 
graphics.DrawLine(Pens.Red, h1, h2); 
graphics.DrawLine(Pens.Red, v1, v2); 
graphics.Dispose(); 
NativeMethods.ReleaseDC(IntPtr.Zero, hdc); 

Идите, это даже не рисует на экране. Я пробовал различные перегрузки для CreateDC, а также искал SO и другие ресурсы, и я в тупике.


После того, как это решается, кто знает, как избавиться от мерцания, обновив рабочий стол с помощью SHCHangeNotify? Я рисую только две линии, и это мерцает, как сумасшедший ..)

ответ

3

Это не ответ на ваш вопрос, но если у вас нет проблем с этим, я бы попытался использовать WPF для решения этой проблемы. Я играл с другим видом взаимодействия с рабочим столом, таким как прозрачность, и WPF молниеносно по сравнению с альтернативой GDI.

Вы размещаете приложение wpf и изменяете его по размеру, чтобы оно соответствовало всей области, в которой вы должны рисовать. Затем установите его прозрачным и убедитесь, что его клик (я думаю, что по умолчанию используется 100% прозрачность). Таким образом, пока у вас нет ничего на этом большом холсте WPF/форме, все события мыши перейдут на рабочий стол.

Тогда просто начните рисовать на нем. (мне понравилось, потому что было очень легко добавлять эффекты к линиям и изображениям). Гарантировано отсутствие мерцания.

Альтернативно, вы можете использовать ту же схему в обычных Windows Forms.

Таким образом, вам не придется обращаться к GDI, чтобы выполнять свою работу.

Я думаю, что единственный способ, с помощью которого вы могли бы сделать это без мерцания, когда вы приближаетесь к нему сейчас, - это подключиться к окошкам сообщений на настольных компьютерах WM_PAINT и выполнять свою работу там.

-1

Не может помочь в первой части. Я предполагаю, что вы рисуете строки в событии Paint. Используйте двойную буферизацию, чтобы избавиться от мерцания.

1

К сожалению, ни ответ какой-либо помощи по следующим причинам:

я ограничен Windows Forms, так как это базовая структура построена для WF. Я пробовал трюк TransparencyKey/Form, все еще слишком мерцающий.

Я серьезно пробовал почти десять различных методов, и даже мои результаты поиска в Google для DirectX/Direct3D, C# Desktop Hooks и другие привели меня к нулю.

Все, что я пытаюсь сделать, это нарисовать перекрестие, охватывающее весь рабочий стол, 1px x 1px .. наверняка у кого-то должен быть какой-то пример того, как это сделать без мерцания и хорошей производительности :? D3D, DX, GDI или иначе? : \

0

это сработало для меня. Я использовал EnumDisplayDevices для получения имен.

[DllImport("gdi32.dll")] 
public static extern IntPtr CreateDC(string lpszDriver, string lpszDevice, string lpszOutput, IntPtr lpInitData); 

var hdc = CreateDC(@"\\.\DISPLAY1", "", "", IntPtr.Zero); 
Graphics graphics = Graphics.FromHdc(hdc); 
var pt = Cursor.Position; 
g.DrawEllipse(Pens.BlueViolet, pt.X - 100, pt.Y - 100, 200, 200); 

подробнее здесь: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145179(v=vs.85).aspx

+0

Ваш код не компилируется как есть - ваш графический объект называется «Графика», но позже использовать его как «г». – BrainSlugs83

+0

Graphics.FromHwnd (hdc) генерирует исключение OutOfMemoryException для меня - как для hdc, созданного из «\\. DISPLAY1», так и для всех ненулевых dcs, созданных строками, возвращаемыми EnumDisplayDevices ... – BrainSlugs83

Смежные вопросы