欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 解决 wpf 管理员权限无法拖放文件的问题

解决 wpf 管理员权限无法拖放文件的问题

2024/10/23 19:30:49 来源:https://blog.csdn.net/simpleman2000/article/details/140952294  浏览:    关键词:解决 wpf 管理员权限无法拖放文件的问题

如果你的wpf程序是以管理员权限运行,那么,是无法接收文件资源管理器拖拽文件的事件的,用下面这个Helper类可以解决这个问题

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Interop;namespace WpfApp1
{public class WpfDragHelper{public event EventHandler DragDrop;public string[] DropFilePaths { get; private set; }public POINT DropPoint { get; private set; }public HwndSource HwndSource { get; set; }public void AddHook(){this.RemoveHook();this.HwndSource.AddHook(WndProc);IntPtr handle = this.HwndSource.Handle;if (IsUserAnAdmin()) RevokeDragDrop(handle);DragAcceptFiles(handle, true);ChangeMessageFilter(handle);}public void RemoveHook(){this.HwndSource.RemoveHook(WndProc);DragAcceptFiles(this.HwndSource.Handle, false);}private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled){if (TryGetDropInfo(msg, wParam, out string[] filePaths, out POINT point)){DropPoint = point; //这个point需要除以windows的dpi,才能得出在wpf窗口中的真正坐标DropFilePaths = filePaths;DragDrop?.Invoke(this, null);handled = true;}return IntPtr.Zero;}[DllImport("user32.dll", SetLastError = true)]private static extern bool ChangeWindowMessageFilterEx(IntPtr hWnd, uint msg, uint action, ref CHANGEFILTERSTRUCT pChangeFilterStruct);[DllImport("user32.dll", SetLastError = true)]private static extern bool ChangeWindowMessageFilter(uint msg, uint flags);[DllImport("shell32.dll")]private static extern void DragAcceptFiles(IntPtr hWnd, bool fAccept);[DllImport("shell32.dll", CharSet = CharSet.Unicode)]private static extern uint DragQueryFile(IntPtr hWnd, uint iFile, StringBuilder lpszFile, int cch);[DllImport("shell32.dll")]private static extern bool DragQueryPoint(IntPtr hDrop, out POINT lppt);[DllImport("shell32.dll")]private static extern void DragFinish(IntPtr hDrop);[DllImport("ole32.dll")]private static extern int RevokeDragDrop(IntPtr hWnd);[DllImport("shell32.dll")]private static extern bool IsUserAnAdmin();[StructLayout(LayoutKind.Sequential)]public struct POINT{public int X;public int Y;}[StructLayout(LayoutKind.Sequential)]struct CHANGEFILTERSTRUCT{public uint cbSize;public uint ExtStatus;}const uint WM_COPYGLOBALDATA = 0x0049;const uint WM_COPYDATA = 0x004A;const uint WM_DROPFILES = 0x0233;const uint MSGFLT_ALLOW = 1;const uint MSGFLT_ADD = 1;const int MAX_PATH = 260;private static void ChangeMessageFilter(IntPtr handle){Version ver = Environment.OSVersion.Version;bool isVistaOrHigher = ver >= new Version(6, 0);bool isWin7OrHigher = ver >= new Version(6, 1);if (isVistaOrHigher){var status = new CHANGEFILTERSTRUCT { cbSize = 8 };foreach (uint msg in new[] { WM_DROPFILES, WM_COPYGLOBALDATA, WM_COPYDATA }){bool error = false;if (isWin7OrHigher) error = !ChangeWindowMessageFilterEx(handle, msg, MSGFLT_ALLOW, ref status);else error = !ChangeWindowMessageFilter(msg, MSGFLT_ADD);if (error) throw new Win32Exception(Marshal.GetLastWin32Error());}}}private static bool TryGetDropInfo(int msg, IntPtr wParam, out string[] dropFilePaths, out POINT dropPoint){dropFilePaths = null;dropPoint = new POINT();if (msg != WM_DROPFILES) return false;uint fileCount = DragQueryFile(wParam, uint.MaxValue, null, 0);dropFilePaths = new string[fileCount];for (uint i = 0; i < fileCount; i++){var sb = new StringBuilder(MAX_PATH);uint result = DragQueryFile(wParam, i, sb, sb.Capacity);if (result > 0) dropFilePaths[i] = sb.ToString();}DragQueryPoint(wParam, out dropPoint);DragFinish(wParam);return true;}}
}

使用方法:

WpfDragHelper _wpfDragHelper ;public MainWindow(){this.InitializeComponent();var _wpfDragHelper = new WpfDragHelper();this.SourceInitialized += (sender, e) =>{var helper = new WindowInteropHelper(this);_wpfDragHelper.HwndSource = HwndSource.FromHwnd(helper.Handle);_wpfDragHelper.AddHook();};this.Closing += (sender, e) =>{_wpfDragHelper.RemoveHook();};_wpfDragHelper.DragDrop += (sender, e) =>{MessageBox.Show(_wpfDragHelper.DropFilePaths[0]);};}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com