Tôi nghĩ mình nên quay lại và tự trả lời câu hỏi này, vì cuối cùng tôi đã làm nó hoạt động.
Tôi tạo ra một lớp CursorUtil với các chức năng:
public struct IconInfo {
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
public class CursorUtil {
[DllImport("user32.dll")]
public static extern IntPtr CreateIconIndirect(ref IconInfo icon);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr handle);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);
// Based on the article and comments here:
// http://www.switchonthecode.com/tutorials/csharp-tutorial-how-to-use-custom-cursors
// Note that the returned Cursor must be disposed of after use, or you'll leak memory!
public static Cursor CreateCursor(Bitmap bm, int xHotspot, int yHotspot) {
IntPtr cursorPtr;
IntPtr ptr = bm.GetHicon();
IconInfo tmp = new IconInfo();
GetIconInfo(ptr, ref tmp);
tmp.xHotspot = xHotspot;
tmp.yHotspot = yHotspot;
tmp.fIcon = false;
cursorPtr = CreateIconIndirect(ref tmp);
if (tmp.hbmColor != IntPtr.Zero) DeleteObject(tmp.hbmColor);
if (tmp.hbmMask != IntPtr.Zero) DeleteObject(tmp.hbmMask);
if (ptr != IntPtr.Zero) DestroyIcon(ptr);
return new Cursor(cursorPtr);
}
public static Bitmap AsBitmap(Control c) {
Bitmap bm = new Bitmap(c.Width, c.Height);
c.DrawToBitmap(bm, new Rectangle(0, 0, c.Width, c.Height));
return bm;
}
Sau đó, tôi đã viết một lớp Kéo (cũng không hướng đối tượng, than ôi, nhưng tôi figured bạn chỉ có thể kéo một điều tại một thời điểm trong một máy tính để bàn ứng dụng).Dưới đây là một chút mã mà:
public static void StartDragging(Control c) {
Dragged = c;
DisposeOldCursors();
Bitmap bm = CursorUtil.AsBitmap(c);
DragCursorMove = CursorUtil.CreateCursor((Bitmap)bm.Clone(), DragStart.X, DragStart.Y);
DragCursorLink = CursorUtil.CreateCursor((Bitmap)bm.Clone(), DragStart.X, DragStart.Y);
DragCursorCopy = CursorUtil.CreateCursor(CursorUtil.AddCopySymbol(bm), DragStart.X, DragStart.Y);
DragCursorNo = CursorUtil.CreateCursor(CursorUtil.AddNoSymbol(bm), DragStart.X, DragStart.Y);
//Debug.WriteLine("Starting drag");
}
// This gets called once when we move over a new control,
// or continuously if that control supports dropping.
public static void UpdateCursor(object sender, GiveFeedbackEventArgs fea) {
//Debug.WriteLine(MainForm.MousePosition);
fea.UseDefaultCursors = false;
//Debug.WriteLine("effect = " + fea.Effect);
if (fea.Effect == DragDropEffects.Move) {
Cursor.Current = DragCursorMove;
} else if (fea.Effect == DragDropEffects.Copy) {
Cursor.Current = DragCursorCopy;
} else if (fea.Effect == DragDropEffects.None) {
Cursor.Current = DragCursorNo;
} else if (fea.Effect == DragDropEffects.Link) {
Cursor.Current = DragCursorLink;
} else {
Cursor.Current = DragCursorMove;
}
}
Bạn có thể sử dụng các phương pháp này khi bạn thiết lập kiểm soát của bạn, ví dụ như trong các nhà xây dựng:
GiveFeedback += new GiveFeedbackEventHandler(Drag.UpdateCursor);
và trong phương pháp này:
protected override void OnMouseMove(MouseEventArgs mea) {
if (Drag.IsDragging(mea)) {
Drag.StartDragging(this);
DragDropEffects dde = DoDragDrop(Plan, DragDropEffects.Move | DragDropEffects.Copy);
Drag.StopDragging();
}
}
Bất kỳ cơ hội nào nhìn thấy mã đầy đủ cho lớp Kéo? TIA, Johnny J. –