2013-03-06 20 views
0

在允许删除之前,有没有办法检查目标(它属于哪个.exe)?在允许删除之前检查目标窗口

我打算实现的是允许控制是拖&掉在Word或Excel中,并根据所目标应用是,通过相应的文件。

编辑: 这里是我在VB中尝试了代码

@大卫感谢代码。我用Button控件(WPF)尝试了类似的东西,并在数据对象中添加了一个文件路径。我得到一个堆栈不平衡异常。

这里是代码(尝试在VB.Net中) - 这是给我这个错误: 调用PInvoke函数'TestApplication!TestApplication.MainWindow :: GetCursorPos'已经失去了堆栈。这很可能是因为托管的PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名相匹配。

我忘记了什么吗?

编辑做了一些改变,现在它的工作。


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

肯定。您可以通过在正在执行拖放操作的控件的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; 
     } 
    } 
} 
+0

我忘了提及我只是在我的例子中显示窗口标题。您可以使用proc.MainModule.FileName获取应用程序的.exe名称。 – David 2013-03-06 20:40:25

+0

没错,但问题是你已经不得不告诉DragDrop你的数据对象是什么,我没有看到任何改变它的方法。我想你可以将正确类型的文件保存到没有扩展名的文件中,每次接收应用程序从反馈中改变。 – 2013-03-06 20:40:32

+0

@David感谢您的代码。我用Button控件(WPF)尝试了类似的东西,并在数据对象中添加了一个文件路径。我得到一个堆栈不平衡异常。 – pingvj 2013-03-07 08:47:38

0

问题是,范例的工作原理与你想要的相反。你必须指定你有什么可用的。然后,您将它放到的应用程序可以选择想要的内容。

不幸的是,如果你把一个DataFormats.FileDrop中的多个文件,Excel将打开这两个文件(我假设Word也会)。

此外,为Excel(我假定字),其中/当你把它改变它的偏好,例如:

  • 如果你把当Excel没有文件打开它更FileDrop,丹尼斯一切
  • 如果你的标题栏有所下降,但更喜欢FileDrop,丹尼斯一切
  • 如果你在一个开放的板材下降时,喜欢的StringFormat(虽然我认为它宁愿CSV)
  • 如何过Excel不会喜欢Rtf转换为CSV,所以如果你把两者都放入你的数据中,Word将会是ta柯RTF和Excel将采取CSV

因此,代码要做到这一点...

DataObject d = new DataObject(); 
    d.SetData(DataFormats.CommaSeparatedValue, csvValue); 
    d.SetData(DataFormats.Rtf, rtfValue); 
    DoDragDrop(d, DragDropEffects.Copy); 

所以,如果你可以在你的数据转换成之前的通话CSV和RTF格式它会传递数据。无论如何,我无法找到使用文件来做到这一点。

0

如果您想选择在放置时渲染的剪贴板格式,则必须延迟渲染内容,直到丢失发生在implementing IASyncOperation/IDataObjectAsyncCapability之间。但是Office没有关于它如何识别您的拖动源的文档。 Windows团队有一个DDWM_UPDATEWINDOW消息,但我不确定办公室团队使用它。

一般来说,each program have its own preference of clipboard formats。例如,如果您的IDataObject :: GetData被调用了WordML,那么目标可能是Microsoft Word。如果首选SpreadsheetML,那么目标可能是Microsoft Excel。您不需要实际提供这两种格式的内容,但可以使用查询的剪贴板格式模式来确定将数据放入哪种程序,并在稍后提供数据,例如,CF_HTML被查询。当然,如果您不介意浪费一些内存,则不需要IASyncOperation,只需使用Word和Excel之间不共享的格式填充数据对象,Word将选择它理解的第一种格式,并且Excel将选择第一种格式它理解的格式。