在允许丢弃之前,有没有办法检查目标(它属于哪个.exe)?
我打算实现的目标是让控件成为一种阻力。放在Word或Excel上,取决于哪个目标应用程序,传递相应的文件。
编辑: 这是我在VB中尝试的代码
@David感谢您的代码。我尝试使用Button控件(WPF)并在dataobject中添加文件路径。我得到了Stack Imbalance异常。
这是代码(在VB.Net中尝试) - 这给了我这个错误: 对PInvoke函数'TestApplication!TestApplication.MainWindow :: GetCursorPos'的调用使堆栈失衡。这很可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。
我忘记了什么吗?
EDIT 进行了一些更改,现在可以正常使用。
Imports System.Diagnostics
Imports System.Runtime.InteropServices
Imports System.Collections.Specialized
Class MainWindow
<DllImport("user32.dll")> _
Private Shared Function WindowFromPoint(ByVal xPoint As Integer, ByVal yPoint As Integer) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function GetCursorPos(lpPoint As Point) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function GetProcessId(hWnd As IntPtr) As Integer
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function GetWindowThreadProcessId(hWnd As IntPtr, lpdwProcessId As Integer) As UInteger
End Function
Private MouseIsDown As Boolean = Nothing
Private Sub DropButton_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles DropButton.PreviewMouseLeftButtonDown
MouseIsDown = True
End Sub
Private Sub DropButton_MouseMove(sender As Object, e As MouseEventArgs) Handles DropButton.MouseMove
If MouseIsDown Then
Dim data As New DataObject()
Dim DropList As New StringCollection
DropList.Add("c:\file.txt")
data.SetFileDropList(DropList)
DragDrop.DoDragDrop(CType(e.OriginalSource, DependencyObject), data, DragDropEffects.Move)
End If
End Sub
Private Sub DropButton_GiveFeedback(sender As Object, e As GiveFeedbackEventArgs) Handles DropButton.GiveFeedback
Dim a = Mouse.GetPosition(Me)
If a <> Nothing Then
Dim hWnd As IntPtr = WindowFromPoint(a.X, a.Y)
If hWnd <> Nothing Then
Dim processId As Integer
GetWindowThreadProcessId(hWnd, processId)
Dim proc As Process = Process.GetProcessById(processId)
label1.Content = proc.MainWindowTitle
End If
End If
End Sub
End Class
答案 0 :(得分:0)
不确定。您可以通过在GiveFeedback事件中为执行拖放操作的控件实现一些互操作来实现此目的。我制作了一个示例应用程序,并使用树形视图控件和表单上的标签进行测试。
using System.Diagnostics;
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
static extern IntPtr WindowFromPoint(Point Point);
[DllImport("user32.dll")]
static extern bool GetCursorPos(out Point lpPoint);
[DllImport("kernel32.dll", SetLastError = true)]
static extern int GetProcessId(IntPtr hWnd);
[DllImport("user32.dll", SetLastError=true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
private void treeView1_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
Point p;
if (GetCursorPos(out p))
{
IntPtr hWnd = WindowFromPoint(p);
if (hWnd != null)
{
int processId;
GetWindowThreadProcessId(hWnd, out processId);
Process proc = Process.GetProcessById(processId);
label1.Text = proc.MainWindowTitle;
}
}
}
答案 1 :(得分:0)
问题在于范式与你想要的相反。您必须指定可用的内容。然后你放下它的应用程序可以选择它想要的东西。
不幸的是,如果你在DataFormats.FileDrop中放入多个文件,Excel将打开这两个文件(我假设Word也会这样)。
另外,对于excel(我假设单词),你放弃的地方/当它改变了它的偏好,例如:
所以,执行此操作的代码是......
DataObject d = new DataObject();
d.SetData(DataFormats.CommaSeparatedValue, csvValue);
d.SetData(DataFormats.Rtf, rtfValue);
DoDragDrop(d, DragDropEffects.Copy);
因此,如果您可以在调用之前将数据转换为csv和rtf格式,它将传递数据。无论如何我都找不到使用文件来做这件事。
答案 2 :(得分:0)
如果要选择要在放置时呈现的剪贴板格式,则必须延迟内容的呈现,直到implementing IASyncOperation/IDataObjectAsyncCapability发生丢弃为止。但Office没有关于如何识别拖动源的文档。有一个来自Windows团队的DDWM_UPDATEWINDOW消息,但我不确定办公室团队是否使用它。
一般来说,each program have its own preference of clipboard formats。例如,如果使用WordML调用了IDataObject :: GetData,则目标可能是Microsoft Word。如果首选SpreadsheetML,则目标可能是Microsoft Excel。您不需要实际提供这两种格式的内容,但您可以使用查询的剪贴板格式模式来确定数据被删除的程序类型,并在以后提供数据,例如,当CF_HTML时被查询。当然,如果你不介意浪费一些内存,你不需要IASyncOperation,只需用Word和Excel之间不共享的格式填充数据对象,Word会选择它理解的第一种格式,Excel会选择第一种格式格式它理解。