0

ドロップを許可する前に、ターゲット(ターゲットが属する.exe)を確認する方法はありますか?

私が達成しようとしているのは、コントロールをWordまたはExcelにドラッグアンドドロップできるようにし、ターゲットアプリケーションに応じて適切なファイルを渡すことです。

編集:これは私がVBで試したコードです

@Davidコードをありがとう。Buttonコントロール(WPF)を使用して同様のことを試し、データオブジェクトにファイルパスを追加しました。スタック不均衡の例外が発生しています。

コードは次のとおりです(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

4

3 に答える 3

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;
        }
    }
}
于 2013-03-06T20:33:58.047 に答える
0

問題は、パラダイムがあなたが望むものと逆に機能することです。利用可能なものを指定する必要があります。次に、ドロップしたアプリケーションは、取得したいものを選択できます。

残念ながら、DataFormats.FileDropに複数のファイルを配置すると、Excelは両方のファイルを開きます(Wordも開くと思います)。

また、Excelの場合(そして私は単語を想定しています)、ドロップする場所/ドロップすると、設定が変更されます。たとえば、次のようになります。

  • Excelでファイルが開いていないときにドロップすると、FileDropが優先され、他のすべてが拒否されます
  • タイトルバーにドロップすると、FileDropが優先され、他のすべてが拒否されます
  • 開いているシートにドロップすると、StringFormatが優先されます(CSVが優先されると思いましたが)
  • ただし、ExcelはCSVよりもRtfを優先するため、両方をデータに入れると、WordがRtfを取得し、ExcelがCSVを取得します。

したがって、これを行うためのコードは...

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

したがって、呼び出しの前にデータをcsvおよびrtf形式に変換できれば、データは渡されます。とにかくファイルを使用してこれを行うことができませんでした。

于 2013-03-06T20:38:28.533 に答える
0

ドロップ時にレンダリングするクリップボード形式を選択する場合は、IASyncOperation / IDataObjectAsyncCapabilityを実装して、ドロップが発生するまでコンテンツのレンダリングを遅らせる必要があります。ただし、ドラッグソースに対してOfficeがどのように識別されるかについてのOfficeからのドキュメントはありません。WindowsチームからDDWM_UPDATEWINDOWメッセージがありますが、オフィスチームがそれを使用しているかどうかはわかりません。

一般的に、各プログラムには独自のクリップボード形式の設定があります。たとえば、IDataObject :: GetDataがWordMLで呼び出された場合、ターゲットはおそらくMicrosoftWordです。SpreadsheetMLの場合が優先される場合、ターゲットはおそらくMicrosoftExcelです。これら2つの形式のコンテンツを実際に提供する必要はありませんが、クエリされたクリップボード形式のパターンを使用して、データがドロップされるプログラムの種類を判別し、後でデータを提供することができます(CF_HTMLなど)。照会されます。もちろん、メモリを浪費してもかまわない場合は、IASyncOperationは必要ありません。データオブジェクトに、WordとExcelで共有されていない形式を入力するだけで、Wordが理解できる最初の形式を選択し、Excelが最初の形式を選択します。理解できるフォーマット。

于 2013-03-06T20:48:12.110 に答える