mirror of
https://gitee.com/csharpui/CPF.git
synced 2025-06-28 13:34:09 +08:00
524 lines
20 KiB
C#
524 lines
20 KiB
C#
![]() |
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Text;
|
|||
|
using System.Threading;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using CPF;
|
|||
|
using CPF.Drawing;
|
|||
|
using CPF.Input;
|
|||
|
using CPF.Platform;
|
|||
|
using static CPF.Windows.UnmanagedMethods;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using CPF.Controls;
|
|||
|
using System.Linq;
|
|||
|
|
|||
|
namespace CPF.Windows
|
|||
|
{
|
|||
|
public class WindowsPlatform : RuntimePlatform
|
|||
|
{
|
|||
|
public override PixelPoint MousePosition
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
POINT pt = new POINT();
|
|||
|
GetCursorPos(out pt);
|
|||
|
return new PixelPoint(pt.X, pt.Y);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public override TimeSpan DoubleClickTime
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return TimeSpan.FromSeconds(0.4);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public override IClipboard GetClipboard()
|
|||
|
{
|
|||
|
return new ClipboardImpl();
|
|||
|
}
|
|||
|
|
|||
|
public override IPopupImpl CreatePopup()
|
|||
|
{
|
|||
|
return new PopupImpl();
|
|||
|
}
|
|||
|
|
|||
|
//public override IViewImpl CreateView()
|
|||
|
//{
|
|||
|
// return new WindowImpl();
|
|||
|
//}
|
|||
|
|
|||
|
public override IWindowImpl CreateWindow()
|
|||
|
{
|
|||
|
return new WindowImpl();
|
|||
|
}
|
|||
|
|
|||
|
public override SynchronizationContext GetSynchronizationContext()
|
|||
|
{
|
|||
|
return new WindowsSynchronizationContext();
|
|||
|
}
|
|||
|
|
|||
|
public override void Run()
|
|||
|
{
|
|||
|
MSG msg = new MSG();
|
|||
|
while (Application.Main != null && GetMessage(ref msg, IntPtr.Zero, 0, 0))
|
|||
|
{
|
|||
|
CPF.Threading.DispatcherTimer.SetTimeTick();
|
|||
|
TranslateMessage(ref msg);
|
|||
|
DispatchMessage(ref msg);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public override void Run(CancellationToken cancellation)
|
|||
|
{
|
|||
|
MSG msg = new MSG();
|
|||
|
while (Application.Main != null && !cancellation.IsCancellationRequested && GetMessage(ref msg, IntPtr.Zero, 0, 0))
|
|||
|
{
|
|||
|
CPF.Threading.DispatcherTimer.SetTimeTick();
|
|||
|
TranslateMessage(ref msg);
|
|||
|
DispatchMessage(ref msg);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
internal static bool registerForMarshalling = true;
|
|||
|
/// <summary>
|
|||
|
/// 初始化Windows平台
|
|||
|
/// </summary>
|
|||
|
/// <param name="RegisterForMarshalling">net5以上才有用的,为了兼容aot,自动注册COM的。 如果你要使用Winform控件出现com问题,你可以把这个改成false</param>
|
|||
|
public WindowsPlatform(bool RegisterForMarshalling)
|
|||
|
{
|
|||
|
registerForMarshalling = RegisterForMarshalling;
|
|||
|
#if !Net4
|
|||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|||
|
#endif
|
|||
|
{
|
|||
|
var w = WindowImpl.Window;
|
|||
|
SetDpiAwareness();
|
|||
|
}
|
|||
|
}
|
|||
|
public WindowsPlatform()
|
|||
|
{
|
|||
|
#if !Net4
|
|||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|||
|
#endif
|
|||
|
{
|
|||
|
var w = WindowImpl.Window;
|
|||
|
SetDpiAwareness();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static void SetDpiAwareness()
|
|||
|
{
|
|||
|
var user32 = LoadLibrary("user32.dll");
|
|||
|
var method = GetProcAddress(user32, nameof(SetProcessDpiAwarenessContext));
|
|||
|
|
|||
|
if (method != IntPtr.Zero)
|
|||
|
{
|
|||
|
if (SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) ||
|
|||
|
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE))
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var shcore = LoadLibrary("shcore.dll");
|
|||
|
method = GetProcAddress(shcore, nameof(SetProcessDpiAwareness));
|
|||
|
|
|||
|
if (method != IntPtr.Zero)
|
|||
|
{
|
|||
|
SetProcessDpiAwareness(PROCESS_DPI_AWARENESS.PROCESS_PER_MONITOR_DPI_AWARE);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (Environment.OSVersion.Version.Major > 5)
|
|||
|
{
|
|||
|
SetProcessDPIAware();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#if Net4
|
|||
|
public override IList<Screen> GetAllScreen()
|
|||
|
#else
|
|||
|
public override IReadOnlyList<Screen> GetAllScreen()
|
|||
|
#endif
|
|||
|
{
|
|||
|
//return new ScreenImpl(new CPF.Drawing.Rect(), new CPF.Drawing.Rect(), false, IntPtr.Zero).GetAllScreens();
|
|||
|
var ScreenCount = GetSystemMetrics(SystemMetric.SM_CMONITORS);
|
|||
|
List<Screen> screens = new List<Screen>();
|
|||
|
EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero,
|
|||
|
(IntPtr monitor, IntPtr hdcMonitor, ref Rect lprcMonitor, IntPtr data) =>
|
|||
|
{
|
|||
|
screens.Add(ScreenImpl.FromMonitor(monitor, hdcMonitor));
|
|||
|
return true;
|
|||
|
}, IntPtr.Zero);
|
|||
|
return screens;
|
|||
|
}
|
|||
|
|
|||
|
public override object GetCursor(Cursors cursorType)
|
|||
|
{
|
|||
|
IntPtr rv;
|
|||
|
if (!Cache.TryGetValue(cursorType, out rv))
|
|||
|
{
|
|||
|
Cache[cursorType] = rv = UnmanagedMethods.LoadCursor(IntPtr.Zero, new IntPtr(CursorTypeMapping[cursorType]));
|
|||
|
}
|
|||
|
return rv;
|
|||
|
}
|
|||
|
|
|||
|
private const UnmanagedMethods.FOS DefaultDialogOptions = UnmanagedMethods.FOS.FOS_FORCEFILESYSTEM | UnmanagedMethods.FOS.FOS_NOVALIDATE |
|
|||
|
UnmanagedMethods.FOS.FOS_NOTESTFILECREATE | UnmanagedMethods.FOS.FOS_DONTADDTORECENT;
|
|||
|
const int FILEBUFSIZE = 8192;
|
|||
|
|
|||
|
public override Task<string[]> ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent)
|
|||
|
{
|
|||
|
var hWnd = (parent as WindowImpl)?.Handle ?? IntPtr.Zero;
|
|||
|
return Task.Factory.StartNew(() =>
|
|||
|
{
|
|||
|
// var result = Array.Empty<string>();
|
|||
|
var result = new string[0];
|
|||
|
try
|
|||
|
{
|
|||
|
Guid clsid = dialog is OpenFileDialog ? ShellIds.OpenFileDialog : ShellIds.SaveFileDialog;
|
|||
|
Guid iid = ShellIds.IFileDialog;
|
|||
|
|
|||
|
//兼容xp
|
|||
|
#if Net4
|
|||
|
CPF.Threading.Dispatcher.MainThread.Invoke(() =>
|
|||
|
{
|
|||
|
string filler = "";
|
|||
|
if (dialog.Filters != null && dialog.Filters.Count > 0)
|
|||
|
{
|
|||
|
foreach (var item in dialog.Filters)
|
|||
|
{
|
|||
|
if (!string.IsNullOrWhiteSpace(item.Extensions))
|
|||
|
{
|
|||
|
filler += item.Name + "|*." + string.Join(";*.", item.Extensions.Split(',')) + "|";
|
|||
|
}
|
|||
|
}
|
|||
|
filler = filler.TrimEnd('|');
|
|||
|
}
|
|||
|
|
|||
|
if (dialog is OpenFileDialog open)
|
|||
|
{
|
|||
|
using (var openFileDialog = new System.Windows.Forms.OpenFileDialog
|
|||
|
{
|
|||
|
Multiselect = open.AllowMultiple,
|
|||
|
Title = open.Title,
|
|||
|
FileName = open.InitialFileName,
|
|||
|
InitialDirectory = open.Directory,
|
|||
|
Filter = filler
|
|||
|
})
|
|||
|
{
|
|||
|
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
|||
|
{
|
|||
|
result = openFileDialog.FileNames;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else if (dialog is SaveFileDialog save)
|
|||
|
{
|
|||
|
using (var saveFileDialog = new System.Windows.Forms.SaveFileDialog
|
|||
|
{
|
|||
|
Title = save.Title,
|
|||
|
FileName = save.InitialFileName,
|
|||
|
InitialDirectory = save.Directory,
|
|||
|
Filter = filler
|
|||
|
})
|
|||
|
{
|
|||
|
if (saveFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
|||
|
{
|
|||
|
result = new string[] { saveFileDialog.FileName };
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
#else
|
|||
|
CPF.Threading.Dispatcher.MainThread.Invoke(() =>
|
|||
|
{
|
|||
|
CoInitializeEx(IntPtr.Zero, COINIT_APARTMENTTHREADED);
|
|||
|
var r = CoCreateInstance(ref clsid, null, 1, ref iid, out var unk);
|
|||
|
var frm = (IFileDialog)unk;
|
|||
|
var openDialog = dialog as OpenFileDialog;
|
|||
|
|
|||
|
uint options;
|
|||
|
frm.GetOptions(out options);
|
|||
|
options |= (uint)(DefaultDialogOptions);
|
|||
|
if (openDialog?.AllowMultiple == true)
|
|||
|
options |= (uint)UnmanagedMethods.FOS.FOS_ALLOWMULTISELECT;
|
|||
|
frm.SetOptions(options);
|
|||
|
|
|||
|
var defaultExtension = (dialog as SaveFileDialog)?.DefaultExtension ?? "";
|
|||
|
frm.SetDefaultExtension(defaultExtension);
|
|||
|
frm.SetFileName(dialog.InitialFileName ?? "");
|
|||
|
if (!string.IsNullOrEmpty(dialog.Title))
|
|||
|
{
|
|||
|
frm.SetTitle(dialog.Title);
|
|||
|
}
|
|||
|
|
|||
|
var filters = new List<COMDLG_FILTERSPEC>();
|
|||
|
if (dialog.Filters != null)
|
|||
|
{
|
|||
|
foreach (var filter in dialog.Filters)
|
|||
|
{
|
|||
|
if (!string.IsNullOrWhiteSpace(filter.Extensions))
|
|||
|
{
|
|||
|
var extMask = string.Join(";", filter.Extensions.Split(',').Where(a => !string.IsNullOrWhiteSpace(a)).Select(e => "*." + e.Trim()));
|
|||
|
filters.Add(new COMDLG_FILTERSPEC { pszName = filter.Name, pszSpec = extMask });
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (filters.Count == 0)
|
|||
|
filters.Add(new COMDLG_FILTERSPEC { pszName = "All files", pszSpec = "*.*" });
|
|||
|
|
|||
|
frm.SetFileTypes((uint)filters.Count, filters.ToArray());
|
|||
|
frm.SetFileTypeIndex(0);
|
|||
|
|
|||
|
if (dialog.Directory != null)
|
|||
|
{
|
|||
|
IShellItem directoryShellItem;
|
|||
|
Guid riid = UnmanagedMethods.ShellIds.IShellItem;
|
|||
|
if (UnmanagedMethods.SHCreateItemFromParsingName(dialog.Directory, IntPtr.Zero, ref riid, out directoryShellItem) == (uint)HRESULT.S_OK)
|
|||
|
{
|
|||
|
frm.SetFolder(directoryShellItem);
|
|||
|
frm.SetDefaultFolder(directoryShellItem);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (frm.Show(hWnd) == (uint)HRESULT.S_OK)
|
|||
|
{
|
|||
|
if (openDialog?.AllowMultiple == true)
|
|||
|
{
|
|||
|
IShellItemArray shellItemArray;
|
|||
|
((IFileOpenDialog)frm).GetResults(out shellItemArray);
|
|||
|
uint count;
|
|||
|
shellItemArray.GetCount(out count);
|
|||
|
result = new string[count];
|
|||
|
for (uint i = 0; i < count; i++)
|
|||
|
{
|
|||
|
IShellItem shellItem;
|
|||
|
shellItemArray.GetItemAt(i, out shellItem);
|
|||
|
result[i] = GetAbsoluteFilePath(shellItem);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
IShellItem shellItem;
|
|||
|
if (frm.GetResult(out shellItem) == (uint)HRESULT.S_OK)
|
|||
|
{
|
|||
|
result = new string[] { GetAbsoluteFilePath(shellItem) };
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
#endif
|
|||
|
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
MessageBox.Show(e.ToString());
|
|||
|
}
|
|||
|
return result;
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
public override Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent)
|
|||
|
{
|
|||
|
return Task.Factory.StartNew(() =>
|
|||
|
{
|
|||
|
string result = string.Empty;
|
|||
|
|
|||
|
var hWnd = (parent as WindowImpl)?.Handle ?? IntPtr.Zero;
|
|||
|
Guid clsid = ShellIds.OpenFileDialog;
|
|||
|
Guid iid = ShellIds.IFileDialog;
|
|||
|
|
|||
|
#if Net4
|
|||
|
CPF.Threading.Dispatcher.MainThread.Invoke(() =>
|
|||
|
{
|
|||
|
using (var folderBrowser = new System.Windows.Forms.FolderBrowserDialog
|
|||
|
{
|
|||
|
SelectedPath = dialog.Directory,
|
|||
|
Description = dialog.Title,
|
|||
|
ShowNewFolderButton = true,
|
|||
|
})
|
|||
|
{
|
|||
|
if (folderBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
|||
|
{
|
|||
|
result = folderBrowser.SelectedPath;
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
#else
|
|||
|
CPF.Threading.Dispatcher.MainThread.Invoke(() =>
|
|||
|
{
|
|||
|
var r = CoCreateInstance(ref clsid, IntPtr.Zero, 1, ref iid, out var unk);
|
|||
|
var frm = (IFileDialog)unk;
|
|||
|
uint options;
|
|||
|
frm.GetOptions(out options);
|
|||
|
options |= (uint)(UnmanagedMethods.FOS.FOS_PICKFOLDERS | DefaultDialogOptions);
|
|||
|
frm.SetOptions(options);
|
|||
|
if (!string.IsNullOrEmpty(dialog.Title))
|
|||
|
{
|
|||
|
frm.SetTitle(dialog.Title);
|
|||
|
}
|
|||
|
|
|||
|
if (dialog.Directory != null)
|
|||
|
{
|
|||
|
IShellItem directoryShellItem;
|
|||
|
Guid riid = UnmanagedMethods.ShellIds.IShellItem;
|
|||
|
if (UnmanagedMethods.SHCreateItemFromParsingName(dialog.Directory, IntPtr.Zero, ref riid, out directoryShellItem) == (uint)HRESULT.S_OK)
|
|||
|
{
|
|||
|
frm.SetFolder(directoryShellItem);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (dialog.Directory != null)
|
|||
|
{
|
|||
|
IShellItem directoryShellItem;
|
|||
|
Guid riid = UnmanagedMethods.ShellIds.IShellItem;
|
|||
|
if (UnmanagedMethods.SHCreateItemFromParsingName(dialog.Directory, IntPtr.Zero, ref riid, out directoryShellItem) == (uint)HRESULT.S_OK)
|
|||
|
{
|
|||
|
frm.SetDefaultFolder(directoryShellItem);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (frm.Show(hWnd) == (uint)HRESULT.S_OK)
|
|||
|
{
|
|||
|
IShellItem shellItem;
|
|||
|
if (frm.GetResult(out shellItem) == (uint)HRESULT.S_OK)
|
|||
|
{
|
|||
|
result = GetAbsoluteFilePath(shellItem);
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
#endif
|
|||
|
return result;
|
|||
|
});
|
|||
|
}
|
|||
|
private string GetAbsoluteFilePath(IShellItem shellItem)
|
|||
|
{
|
|||
|
IntPtr pszString;
|
|||
|
if (shellItem.GetDisplayName(UnmanagedMethods.SIGDN_FILESYSPATH, out pszString) == (uint)HRESULT.S_OK)
|
|||
|
{
|
|||
|
if (pszString != IntPtr.Zero)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
return Marshal.PtrToStringAuto(pszString);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
Marshal.FreeCoTaskMem(pszString);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return "";
|
|||
|
}
|
|||
|
static Dictionary<KeyGesture, PlatformHotkey> keyValuePairs = new Dictionary<KeyGesture, PlatformHotkey>() {
|
|||
|
{ new KeyGesture(Keys.C,InputModifiers.Control),PlatformHotkey.Copy},
|
|||
|
{ new KeyGesture(Keys.X,InputModifiers.Control),PlatformHotkey.Cut},
|
|||
|
{ new KeyGesture(Keys.V,InputModifiers.Control),PlatformHotkey.Paste},
|
|||
|
{ new KeyGesture(Keys.Y,InputModifiers.Control),PlatformHotkey.Redo},
|
|||
|
{ new KeyGesture(Keys.A,InputModifiers.Control),PlatformHotkey.SelectAll},
|
|||
|
{ new KeyGesture(Keys.Z,InputModifiers.Control),PlatformHotkey.Undo},
|
|||
|
};
|
|||
|
public override PlatformHotkey Hotkey(KeyGesture keyGesture)
|
|||
|
{
|
|||
|
keyValuePairs.TryGetValue(keyGesture, out PlatformHotkey platformHotkey);
|
|||
|
return platformHotkey;
|
|||
|
}
|
|||
|
|
|||
|
public override DragDropEffects DoDragDrop(DragDropEffects allowedEffects, params (DataFormat, object)[] data)
|
|||
|
{
|
|||
|
Threading.Dispatcher.MainThread.VerifyAccess();
|
|||
|
try
|
|||
|
{
|
|||
|
OleDragSource src = new OleDragSource();
|
|||
|
DataObject dataObject = new DataObject(data);
|
|||
|
int allowed = (int)ConvertDropEffect(allowedEffects);
|
|||
|
|
|||
|
int[] finalEffect = new int[1];
|
|||
|
UnmanagedMethods.DoDragDrop(dataObject, src, allowed, finalEffect);
|
|||
|
|
|||
|
return ConvertDropEffect((DropEffect)finalEffect[0]);
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Console.WriteLine(e);
|
|||
|
System.Diagnostics.Debug.WriteLine(e);
|
|||
|
}
|
|||
|
return DragDropEffects.None;
|
|||
|
}
|
|||
|
|
|||
|
public static DropEffect ConvertDropEffect(DragDropEffects operation)
|
|||
|
{
|
|||
|
DropEffect result = DropEffect.None;
|
|||
|
if (operation.HasFlag(DragDropEffects.Copy))
|
|||
|
result |= DropEffect.Copy;
|
|||
|
if (operation.HasFlag(DragDropEffects.Move))
|
|||
|
result |= DropEffect.Move;
|
|||
|
if (operation.HasFlag(DragDropEffects.Link))
|
|||
|
result |= DropEffect.Link;
|
|||
|
return result;
|
|||
|
}
|
|||
|
public static DragDropEffects ConvertDropEffect(DropEffect effect)
|
|||
|
{
|
|||
|
DragDropEffects result = DragDropEffects.None;
|
|||
|
if (effect.HasFlag(DropEffect.Copy))
|
|||
|
result |= DragDropEffects.Copy;
|
|||
|
if (effect.HasFlag(DropEffect.Move))
|
|||
|
result |= DragDropEffects.Move;
|
|||
|
if (effect.HasFlag(DropEffect.Link))
|
|||
|
result |= DragDropEffects.Link;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
public override INativeImpl CreateNative()
|
|||
|
{
|
|||
|
return new NativeHost();
|
|||
|
}
|
|||
|
|
|||
|
public override INotifyIconImpl CreateNotifyIcon()
|
|||
|
{
|
|||
|
return new NotifyIcon();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private static readonly Dictionary<Cursors, IntPtr> Cache =
|
|||
|
new Dictionary<Cursors, IntPtr>();
|
|||
|
private static readonly Dictionary<Cursors, int> CursorTypeMapping = new Dictionary
|
|||
|
<Cursors, int>
|
|||
|
{
|
|||
|
{Cursors.AppStarting, 32650},
|
|||
|
{Cursors.Arrow, 32512},
|
|||
|
{Cursors.Cross, 32515},
|
|||
|
{Cursors.Hand, 32649},
|
|||
|
{Cursors.Help, 32651},
|
|||
|
{Cursors.Ibeam, 32513},
|
|||
|
{Cursors.No, 32648},
|
|||
|
{Cursors.SizeAll, 32646},
|
|||
|
{Cursors.UpArrow, 32516},
|
|||
|
{Cursors.SizeNorthSouth, 32645},
|
|||
|
{Cursors.SizeWestEast, 32644},
|
|||
|
{Cursors.Wait, 32514},
|
|||
|
//Same as SizeNorthSouth
|
|||
|
{Cursors.TopSide, 32645},
|
|||
|
{Cursors.BottomSide, 32645},
|
|||
|
//Same as SizeWestEast
|
|||
|
{Cursors.LeftSide, 32644},
|
|||
|
{Cursors.RightSide, 32644},
|
|||
|
//Using SizeNorthWestSouthEast
|
|||
|
{Cursors.TopLeftCorner, 32642},
|
|||
|
{Cursors.BottomRightCorner, 32642},
|
|||
|
//Using SizeNorthEastSouthWest
|
|||
|
{Cursors.TopRightCorner, 32643},
|
|||
|
{Cursors.BottomLeftCorner, 32643},
|
|||
|
|
|||
|
// Fallback, should have been loaded from ole32.dll
|
|||
|
{Cursors.DragMove, 32516},
|
|||
|
{Cursors.DragCopy, 32516},
|
|||
|
{Cursors.DragLink, 32516},
|
|||
|
};
|
|||
|
}
|
|||
|
}
|