2010-04-15 3 views
1

Я хочу, чтобы имитировать функциональность Google Chrome/Firefox, например, при их перемещении закладок, когда вы тянете пункт меню, он создает черную линию в предлагаемой точке падения, как это:Как создать линии вывода при перетаскивании элемента меню в WinForm?

alt text http://www.freeimagehosting.net/uploads/977900a13a.jpg

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

Есть ли способ сделать это в .NET Framework (3.5) или мне нужно прибегать к вызовам Win32 api? Просто хотел спросить, прежде чем я пошел по этому пути.

+0

Я * думаю * это то, о чем вы просите - можете откатиться, если это не так. – MusiGenesis

+0

@Bryan: вам не нужно указывать язык в названии, так как он находится в тегах. –

ответ

0

Общим способом сделать это в чистом .NET-коде является создание формы без полей, которая имеет цвет и размер, чтобы выглядеть как линия точки падения. Также установите для свойства TopMost значение True в этой форме.

Затем используйте события MouseDown/MouseUp/MouseMove, чтобы определить, когда и где отображать линию вывода в ответ на действия пользователя.

Чтобы правильно позиционировать форму линии сбрасывания, вам нужно будет изучить методы Control.PointToScreen и/или Control.RectangleToScreen (и, возможно, Control.PointToClient).

0

Я думаю, что самый простой способ сделать это - получить ручку всплывающего меню, которое вы перетаскиваете. Когда у вас есть ручка, вы можете нарисовать ее непосредственно с помощью объекта Graphics.

Для получения рукоятки, вероятно, потребуется некоторый API mojo. Я ищу его.

Обновление: не очень много, хотя есть иронический улов (см. Ниже). Для этого добавьте

using System.Runtime.InteropServices; 

в верхней части вашей формы или класса или что угодно. Добавить это объявление где-то:

[DllImport("user32.dll", EntryPoint = "FindWindow")] 
    private static extern IntPtr FindWindowA(string lpClassName, 
    string lpWindowName); 

окно всплывающего меню (то есть часть, которую вы обычно не видите) является верхним окном с именем класса «# 32768». Этот код показывает, как получить окна в меню для ручки и рисовать прямо на него:

IntPtr hWnd = FindWindowA("#32768", null); 
if (hWnd != IntPtr.Zero) 
{ 
    using (Graphics g = Graphics.FromHwnd(hWnd)) 
    { 
     g.FillRectangle(Brushes.Red, 
      new Rectangle(0, 0, 20, 20)); 
    } 
} 

Этот пример просто рисует 20х20 красный квадрат в верхнем левом углу меню. Чтобы отобразить линию вывода, вам нужно будет немного поработать, чтобы выяснить, где именно это должно быть, и затем нарисовать все, что вы хотите. Мне кажется, что это всего лишь двухпиксельная черная линия с небольшими частичными стрелками на каждом конце, поэтому ее не должно быть трудно подражать.

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

Он работает, даже если у вас открыто несколько вложенных меню (все предположительно имеют имя класса «# 32768»). FindWindow всегда возвращает самый верхний номер в z-порядке. Еще одна хорошая вещь - потому что вы рисуете на самом окне меню, линия будет находиться под полупрозрачным курсором, который вы хотите.

Иронический улов: я проверил это на множестве различных программ и меню. Он работал над всеми ними и всеми меню, кроме меню «Избранное» в Internet Explorer. Я предполагаю, что в этом конкретном меню используется нечто иное, чем встроенные меню Windows. Если вы делаете это с помощью обычных меню .Net, он должен работать нормально.

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