私はC#コードを使用して、ユーザーが別のプロセスでファイルをコントロールにドラッグアンドドロップするのをシミュレートしたいと考えています。この目標の踏み台として、自分のTextBoxにWM_DROPFILESメッセージを送信し、DragDropイベントがトリガーされていることを確認しようとしています。C#からWM_DROPFILESを送信するにはどうすればよいですか?
1つのTextBoxと2つのボタンを含むフォームの下のコードでは、button1をクリックするとtextBox1のテキストが正常に「Hello World」に設定されます。それで、私はSendMessageを正しく使用していると思われ、ポインタを介して引数を提供できるようになっています。 Windowsエクスプローラからテキストボックス1にファイルをドラッグ&ドロップするとMessageBoxが表示されるので、ドラッグアンドドロップされたファイルを正しく受け取るようにtextBox1が設定されます。しかし、button2をクリックすると何も起こりません。 button2をクリックしたときにMessageBoxが表示されないのはなぜですか?
using System;
using System.Data;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace StackOverflow
{
public partial class BadDragDrop : Form
{
#region WINAPI
[Serializable]
[StructLayout(LayoutKind.Sequential)]
struct POINT
{
public Int32 X;
public Int32 Y;
}
[Serializable]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
class DROPFILES
{
public Int32 size;
public POINT pt;
public Int32 fND;
public Int32 WIDE;
}
const uint WM_DROPFILES = 0x0233;
const uint WM_SETTEXT = 0x000C;
[DllImport("Kernel32.dll", SetLastError = true)]
static extern int GlobalLock(IntPtr Handle);
[DllImport("Kernel32.dll", SetLastError = true)]
static extern int GlobalUnlock(IntPtr Handle);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
#endregion
public BadDragDrop()
{
InitializeComponent();
textBox1.AllowDrop = true;
}
private void button1_Click(object sender, EventArgs e)
{
string textToSet = "Hello world\0";
IntPtr p = Marshal.AllocHGlobal(textToSet.Length);
Marshal.Copy(textToSet.Select(c => (byte)c).ToArray(), 0, p, textToSet.Length);
int success = GlobalUnlock(p);
SendMessage(textBox1.Handle, WM_SETTEXT, IntPtr.Zero, p);
Marshal.FreeHGlobal(p);
}
private void button2_Click(object sender, EventArgs e)
{
string filePath = @"C:\Windows\win.ini" + "\0\0";
DROPFILES s = new DROPFILES()
{
size = Marshal.SizeOf<DROPFILES>(),
pt = new POINT() { X = 10, Y = 10 },
fND = 0,
WIDE = 0,
};
int wparamLen = s.size + filePath.Length;
IntPtr p = Marshal.AllocHGlobal(wparamLen);
int iSuccess = GlobalLock(p);
Marshal.StructureToPtr(s, p, false);
Marshal.Copy(filePath.Select(c => (byte)c).ToArray(), 0, p + s.size, filePath.Length);
iSuccess = GlobalUnlock(p);
var verify = new byte[wparamLen];
Marshal.Copy(p, verify, 0, wparamLen);
var ipSuccess = SendMessage(textBox1.Handle, WM_DROPFILES, p, IntPtr.Zero);
Marshal.FreeHGlobal(p);
}
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
MessageBox.Show(this, "Drag drop!");
}
private void textBox1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
}
}