WPF怎么实现文件拖放功能winform怎么实现拖拽功能

WPF怎么实现文件拖放功能winform怎么实现文件拖拽功能,在管理员模式下wpf winform怎么实现文件的拖拽功能

WPF实现文件拖放功能,正常情况并没有什么问题,但是如果你的程序使用管理员身份启动,你就会发现文件拖放功能就会失效。同样winform使用管理员身份启动,你就会发现文件拖放功能就会失效

解决一,管理员不给拖拽,就吧管理员启动kill掉

方案一:让你的程序使用非管理员启动,程序中需要管理员身份的操作,一般为涉及到注册表操作或驱动操作,可以考虑将这部分操作放到一个服务里单独操作,可以理解为程序分成服务与应用程序两块,需要管理员身份操作的

功能部分放到服务里实现,界面相关的操作在应用程序里实现。

这种方案也能解决,并且问题解决的比较彻底,但是项目工程量比较大的情况下,工作量就比较大了,为一个文件拖放的功能,增加了较大的工作量,得不偿失。

方案二:将需要管理员权限启动的部分做成另一个单独的exe程序,在主程序中用调用,可参考C#默认以管理员身份运行程序_刘水镜的博客-CSDN博客

方案三:提供一个折中的办法,WPF经过我较长的上网搜索及研究,没有找到合适的办法解决这个问题,但是 WinForm 通过消息Hook却能实现,所以这个折中的办法就是WPF+WinForm来解决这个问题。

主要方法详解:

下面我们将主要讲解如何使用 WPF+WinForm 解决WPF程序使用管理员身份启动后不能拖放文件的问题。

第一部分:使用 WinForm 解决使用不能拖动的问题,关键代码如下

ElevatedDragDropManager.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Windows;public class ElevatedDragDropManager : IMessageFilter
{#region "P/Invoke"[DllImport("user32.dll")][return: MarshalAs(UnmanagedType.Bool)]private static extern bool ChangeWindowMessageFilterEx(IntPtr hWnd, uint msg, ChangeWindowMessageFilterExAction action, ref CHANGEFILTERSTRUCT changeInfo);[DllImport("user32.dll")][return: MarshalAs(UnmanagedType.Bool)]private static extern bool ChangeWindowMessageFilter(uint msg, ChangeWindowMessageFilterFlags flags);[DllImport("shell32.dll")]private static extern void DragAcceptFiles(IntPtr hwnd, bool fAccept);[DllImport("shell32.dll")]private static extern uint DragQueryFile(IntPtr hDrop, uint iFile, [Out()]
StringBuilder lpszFile, uint cch);[DllImport("shell32.dll")]private static extern bool DragQueryPoint(IntPtr hDrop, ref POINT lppt);[DllImport("shell32.dll")]private static extern void DragFinish(IntPtr hDrop);[StructLayout(LayoutKind.Sequential)]private struct POINT{public int X;public int Y;public POINT(int newX, int newY){X = newX;Y = newY;}public static implicit operator System.Drawing.Point(POINT p){return new System.Drawing.Point(p.X, p.Y);}public static implicit operator POINT(System.Drawing.Point p){return new POINT(p.X, p.Y);}}private enum MessageFilterInfo : uint{None,AlreadyAllowed,AlreadyDisAllowed,AllowedHigher}private enum ChangeWindowMessageFilterExAction : uint{Reset,Allow,Disallow}private enum ChangeWindowMessageFilterFlags : uint{Add = 1,Remove = 2}[StructLayout(LayoutKind.Sequential)]private struct CHANGEFILTERSTRUCT{public uint cbSize;public MessageFilterInfo ExtStatus;}#endregionpublic static ElevatedDragDropManager Instance = new ElevatedDragDropManager();public event EventHandler<ElevatedDragDropArgs> ElevatedDragDrop;private const uint WM_DROPFILES = 0x233;private const uint WM_COPYDATA = 0x4a;private const uint WM_COPYGLOBALDATA = 0x49;private readonly bool IsVistaOrHigher = Environment.OSVersion.Version.Major >= 6;private readonly bool Is7OrHigher = (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major > 6;public void EnableDragDrop(IntPtr hWnd){if (Is7OrHigher){CHANGEFILTERSTRUCT changeStruct = new CHANGEFILTERSTRUCT();changeStruct.cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(CHANGEFILTERSTRUCT)));ChangeWindowMessageFilterEx(hWnd, WM_DROPFILES, ChangeWindowMessageFilterExAction.Allow, ref changeStruct);ChangeWindowMessageFilterEx(hWnd, WM_COPYDATA, ChangeWindowMessageFilterExAction.Allow, ref changeStruct);ChangeWindowMessageFilterEx(hWnd, WM_COPYGLOBALDATA, ChangeWindowMessageFilterExAction.Allow, ref changeStruct);}else if (IsVistaOrHigher){ChangeWindowMessageFilter(WM_DROPFILES, ChangeWindowMessageFilterFlags.Add);ChangeWindowMessageFilter(WM_COPYDATA, ChangeWindowMessageFilterFlags.Add);ChangeWindowMessageFilter(WM_COPYGLOBALDATA, ChangeWindowMessageFilterFlags.Add);}DragAcceptFiles(hWnd, true);}public bool PreFilterMessage(ref Message m){if (m.Msg == WM_DROPFILES){HandleDragDropMessage(m);return true;}return false;}private void HandleDragDropMessage(Message m){dynamic sb = new StringBuilder(260);uint numFiles = DragQueryFile(m.WParam, 0xffffffffu, sb, 0);dynamic list = new List<string>();for (uint i = 0; i <= numFiles - 1; i++){if (DragQueryFile(m.WParam, i, sb, Convert.ToUInt32(sb.Capacity) * 2) > 0){list.Add(sb.ToString());}}POINT p = default(POINT);DragQueryPoint(m.WParam, ref p);DragFinish(m.WParam);dynamic args = new ElevatedDragDropArgs();args.HWnd = m.HWnd;args.Files = list;args.X = p.X;args.Y = p.Y;if (ElevatedDragDrop != null){ElevatedDragDrop(this, args);}}
}public class ElevatedDragDropArgs : EventArgs
{public IntPtr HWnd{get { return m_HWnd; }set { m_HWnd = value; }}private IntPtr m_HWnd;public List<string> Files{get { return m_Files; }set { m_Files = value; }}private List<string> m_Files;public int X{get { return m_X; }set { m_X = value; }}private int m_X;public int Y{get { return m_Y; }set { m_Y = value; }}private int m_Y;public ElevatedDragDropArgs(){Files = new List<string>();}
}

Form1.cs

注:需要将Form1窗口的AllowDrop属性设置为false,否则无法拖动文件。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;namespace FileDragDrop
{public partial class FileDragDrop : Form{public FileDragDrop(){InitializeComponent();//this.AllowDrop设置为falsethis.AllowDrop = false;ElevatedDragDropManager filter = new ElevatedDragDropManager();//开启拖放功能filter.EnableDragDrop(this.Handle);//添加消息过滤器Application.AddMessageFilter(filter);//设置拖放结束回调filter.ElevatedDragDrop += this.ElevatedDragDrop;}//拖放结束事件private void ElevatedDragDrop(System.Object sender, ElevatedDragDropArgs e){try{if (e.HWnd == this.Handle){foreach (string file in e.Files){//拖动文件MessageBox.Show("ElevatedDragDrop File=" + (file) + "!");}}}catch (Exception ex){//异常信息MessageBox.Show("ElevatedDragDrop error=" + (ex.TargetSite?.Name) + "!");}}}
}

最终的效果:

 

WinForm项目代码链接:

GitHub - zhaobangyu/C-SHAP at WinForm

第二部分:WPF+WinForm的组合使用

效果图:

 ​WPF+WinForm项目代码链接:

https://github.com/zhaobangyu/C-SHAP/tree/WPF/FileDragDrop

补充

这个直接使用没问题。但如果关闭这个页面重新打开就会有问题。这个拖拽事件一直绑定的第一次创建时的handle。

原因是要在关闭的时候重新释放消息过滤器

 借鉴自https://www.cnblogs.com/whr2071/p/15922643.html

大体的报错范围是,在父窗体中进行释放,可以新建接收拖放的窗口,但窗口句柄与接收放置的句柄匹配不上,触发不了后续事件。在子窗体中进行释放,父窗体中的操作会直接报错“无法访问已释放的对象”。

最后,当我放弃第一个链接的方法去寻找其他解决办法时,看到了第二个链接。发现我没有释放消息过滤器,也就是

Application.RemoveMessageFilter(this);

当我把这个加到我的工程中,一切问题就解决了。

 WPF怎么实现文件拖放功能winform怎么实现文件拖拽功能,在管理员模式下wpf winform怎么实现文件的拖拽功能

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/89671.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MOS管开关电路栅极为什么要串接电阻

在MOS管开关电路或者驱动电路中&#xff0c;常常会在MOS管的栅极串接一个电阻。 这个电阻阻值一般是几十欧姆&#xff0c;那么这个电阻有什么作用呢&#xff1f; 第一个作用就是可以限制驱动电流 &#xff0c;防止瞬间驱动电流过大导致驱动芯片驱动能力不足或者损坏。 MOS管的…

Mybatis缓存

缓存(cache&#xff09;的作用是为了减去数据库的压力&#xff0c;提高查询性能。缓存实现的原理 是从数据库中查询出来的对象在使用完后不要销毁&#xff0c;而是存储在内存&#xff08;缓存&#xff09;中&#xff0c; 当再次需要获取该对象时&#xff0c;直接从内存&#xf…

性价比高的照明品牌,五大性价比高的照明品牌台灯推荐

很多家长有时候会说孩子觉得家里的台灯灯光刺眼&#xff0c;看书看久了就不舒服。这不仅要看光线亮度是否柔和&#xff0c;还要考虑台灯是不是有做遮光式设计。没有遮光式设计的台灯&#xff0c;光源外露&#xff0c;灯光会直射孩子头部&#xff0c;孩子视线较低&#xff0c;很…

安达发|模拟车间模型生成生产排产计划

根据车间模型生成排产计划的一般程序可简单地描述为下面6个步骤。 1. 建模 车间模型必须详细地捕捉生产流程的特征和相应的物流&#xff0c;以便以最小的成本生成可行的计划。由于一个系统的产出率只受潜在瓶颈资源的限制&#xff0c;因此&#xff0c;我们只需对车间现有全部资…

成都睿趣科技:抖音开网店前期的流程是什么

随着互联网的快速发展&#xff0c;电子商务成为了商业领域中的一大利器&#xff0c;而在电商领域中&#xff0c;抖音作为一个强大的平台&#xff0c;也吸引了众多商家的目光。然而&#xff0c;要在抖音上开设一家成功的网店&#xff0c;并不是一件简单的事情&#xff0c;需要经…

网络字节序——TCP接口及其实现简单TCP服务器

网络字节序——TCP接口及其实现简单TCP服务器 文章目录 网络字节序——TCP接口及其实现简单TCP服务器简单TCP服务器的实现1. 单进程版&#xff1a;客户端串行版2. 多进程版&#xff1a;客户端并行版netstat查看网络信息3.多线程版&#xff1a;并行执行log.hpp 守护进程fg、bg s…

【GO】LGTM_Grafana_Tempo(2)_官方用例改后实操

最近在尝试用 LGTM 来实现 Go 微服务的可观测性&#xff0c;就顺便整理一下文档。 Tempo 会分为 4 篇文章&#xff1a; Tempo 的架构官网测试实操跑通gin 框架发送 trace 数据到 tempogo-zero 微服务框架使用发送数据到 tempo 根据官方文档实操跑起来 tempo&#xff0c;中间根…

几个nlp的小任务(生成式任务——语言模型(CLM与MLM))

@TOC 本章节需要用到的类库 微调任意Transformers模型(CLM因果语言模型、MLM遮蔽语言模型) CLM MLM 准备数据集 展示几个数据的结构

Linux 虚拟机同步时间crontab以及crond详解

目录 一 Linux 虚拟机同步时间设置 1. 检查是否安装cron服务&#xff08;即时间同步器&#xff09; 2. 下载时间同步器 3. 编辑crontab 内容 4. 同步更新电脑网络时间 5.设置 reload 6. 查看 crond 状态 二 crond 详解 1. 启动/关闭cron服务 2. crontab命令格式 3. …

2021年12月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;书架 John最近买了一个书架用来存放奶牛养殖书籍&#xff0c;但书架很快被存满了&#xff0c;只剩最顶层有空余。 John共有N头奶牛(1 ≤ N ≤ 20,000)&#xff0c;每头奶牛有自己的高度Hi(1 ≤ Hi ≤ 10,000)&#xff0c;N头奶牛的总高度为S。书架高度为B(1 ≤…

基于Spring Boot 的 Ext JS 应用框架之coworkee

Ext JS 官方提供了一个人员管理的完整应用框架 - coworkee。该框架的显示如下: 该框架的布局特点如下: 布局方式: 左右布局, 左侧导航栏默认收合特点:左侧导航区占用空间小, 工作区较大, 适合没有二级导航栏,工作区需要显示的内容较多的系统。如果导航栏是横向底部,就…

AI 绘画Stable Diffusion 研究(十七)SD lora 详解(上)

大家好&#xff0c;我是风雨无阻。 本期内容&#xff1a; Lora的原理是什么&#xff1f;Lora如何下载安装&#xff1f;Lora如何使用&#xff1f; 大家还记得 AI 绘画Stable Diffusion 研究&#xff08;三&#xff09;sd模型种类介绍及安装使用详解 这篇文章中&#xff0c;曾简…