void ProcessItemHit(int index, Point pt)
{
bool itemPressed = true;
Capture = true;
using (Graphics g = Graphics.FromHwnd(Handle))
{
Rectangle itemRect = GetItemRect(g, bands[currentBandIndex], index, Rectangle.Empty);
DrawItem(g, index, itemRect, true, true, Rectangle.Empty, null);
bool dragging = false;
int deltaX = 0;
int deltaY = 0;
bool itemHighlighted = false;
int dragItemIndex = -1;
bool doLoop = true;
while (doLoop)
{
// Check messages until we find a condition to break out of the loop
Win32.MSG msg = new Win32.MSG();
WindowsAPI.GetMessage(ref msg, 0, 0, 0);
Point point = new Point(0, 0);
if (msg.message == (int)Msg.WM_MOUSEMOVE || msg.message == (int)Msg.WM_LBUTTONUP)
{
point = WindowsAPI.GetPointFromLPARAM((int)msg.lParam);
if (msg.message == (int)Msg.WM_MOUSEMOVE)
{
deltaX = pt.X - point.X;
deltaY = pt.Y - point.Y;
}
}
switch (msg.message)
{
case (int)Msg.WM_MOUSEMOVE:
{
int currentIndex;
HitTestType hit = HitTest(point, out currentIndex, dragging);
if (dragging)
{
if (hit == HitTestType.DropLine || hit == HitTestType.DropLineLastItem)
{
Cursor.Current = dragCursor;
// Draw the Dragline
DrawDropLine(g, currentIndex, true, hit);
}
else
{
Cursor.Current = Cursors.No;
// Erase the Dragline
DrawDropLine(g, index, false, hit);
}
if (hit == HitTestType.Item && currentIndex == index)
{
if (itemHighlighted == false)
{
DrawItem(g, index, itemRect,
true, false, Rectangle.Empty, null);
itemHighlighted = true;
}
}
else
{
if (hit == HitTestType.Item)
{
// Erase previous highlighting first
if (itemHighlighted)
{
DrawItem(g, index, itemRect,
false, false, Rectangle.Empty, null);
}
// Highlight new item
itemRect = GetItemRect(g, bands[currentBandIndex], currentIndex, Rectangle.Empty);
index = currentIndex;
DrawItem(g, index, itemRect,
true, false, Rectangle.Empty, null);
}
else
{
// the mouse did not hit an item
if (itemHighlighted)
{
DrawItem(g, index, itemRect,
false, false, Rectangle.Empty, null);
itemHighlighted = false;
}
}
}
}
else
{
if (hit == HitTestType.Item && currentIndex == index)
{
// Set no drag cursor if there have been at least
// a 5 pixel movement
int pixelmov = 5;
if (bands[currentBandIndex].IconView == IconView.Small)
pixelmov = 2;
bool unpressed = false;
if (Math.Abs(deltaX) >= pixelmov || Math.Abs(deltaY) >= pixelmov)
{
unpressed = true;
Cursor.Current = Cursors.No;
dragging = true;
dragItemIndex = index;
}
if (itemPressed && unpressed)
{
DrawItem(g, index, itemRect,
true, false, Rectangle.Empty, null);
itemPressed = false;
itemHighlighted = true;
}
}
}
break;
}
case (int)Msg.WM_LBUTTONUP:
{
// Highlight the item
if (itemPressed)
{
DrawItem(g, index, itemRect, true, false, Rectangle.Empty, null);
itemPressed = false;
}
int newIndex;
HitTestType ht = HitTest(point, out newIndex, true);
bool doDrop = false;
if (dragging && (ht == HitTestType.DropLine || ht == HitTestType.DropLineLastItem))
{
// Delete dropline
Cursor.Current = Cursors.Default;
// Erase the Dragline
DrawDropLine(g, index, false, ht);
// Move the dragged item to the new location
// only if the new location is not contiguous to its
// own location
if (dragItemIndex > droppedPosition
&& Math.Abs(dragItemIndex - droppedPosition) > 0)
doDrop = true;
else if (dragItemIndex < droppedPosition
&& Math.Abs(dragItemIndex - droppedPosition) > 1)
doDrop = true;
if (doDrop)
{
// Remove item from its old location
OutlookBarItem dragItem = bands[currentBandIndex].Items[dragItemIndex];
bands[currentBandIndex].Items.RemoveAt(dragItemIndex);
// Insert item in its new location
if (dragItemIndex < droppedPosition)
droppedPosition--;
bands[currentBandIndex].Items.Insert(droppedPosition, dragItem);
}
}
// Repaint the bar just in case we had a dropline painted
Invalidate();
// Highlight item
if (!dragging)
{
// do not highlight if we are dropping
forceHightlight = true;
forceHightlightIndex = index;
// Fire item clicked property
FireItemClicked(index);
}
else
{
// Fire item dropped event
if (droppedPosition != -1 && doDrop)
FireItemDropped(droppedPosition);
}
doLoop = false;
break;
}
case (int)Msg.WM_KEYDOWN:
{
if ((int)msg.wParam == (int)VirtualKeys.VK_ESCAPE)
doLoop = false;
break;
}
default:
WindowsAPI.DispatchMessage(ref msg);
break;
}
}
}
Capture = false;
}