【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

ファイルの遅延レンダリング

ネットワークファイルシステムのクライアント(FTPソフトなど)からExplorerにドラッグ&ドロップでファイルをコピーするため、ドロップ後にダウンロードしながらコピーさせたいことがあります。これを遅延レンダリングと呼びます。

C#で遅延レンダリングをなるべく短く実装したコードを置いておきます。パブリックドメインです。ネットワークとは関係ありませんが、テキストボックス内の文字列をテンポラリファイルなしでコピーしています。

using System;
using System.IO;
using System.Text;
using System.Windows.Forms;

static class Program
{
    [STAThread]
    static void Main()
    {
        var f = new Form { Text = "File Render" };
        var tb = new TextBox { Text = "テスト\r\n", Dock = DockStyle.Fill, Multiline = true };
        f.Controls.Add(tb);
        tb.MouseMove += (sender, e) =>
        {
            if (e.Button != MouseButtons.Left) return;
            byte[] data = null;
            var dobj = new CustomDataObject();
            dobj.SetData("FileGroupDescriptorW", null);
            dobj.SetData("FileContents", null);
            dobj.OnGetData = (format, autoConvert) =>
            {
                if (data == null) data = Encoding.UTF8.GetBytes(tb.Text);
                switch (format)
                {
                    case "FileGroupDescriptorW":
                        var ms = new MemoryStream();
                        var bw = new BinaryWriter(ms);
                        bw.Write(1);
                        bw.Write(0x4040);
                        bw.Write(new byte[16 + 4 * 5 + 8 * 3 + 4]);
                        bw.Write(data.Length);
                        bw.Write(Encoding.Unicode.GetBytes("TestDnD.txt".PadRight(260, '\0')));
                        return ms;
                    case "FileContents":
                        return new MemoryStream(data);
                }
                return null;
            };
            f.DoDragDrop(dobj, DragDropEffects.Copy);
        };
        Application.Run(f);
    }
}

public class CustomDataObject : DataObject
{
    public Func<string, bool, object> OnGetData;

    public override object GetData(string format, bool autoConvert)
    {
        return OnGetData(format, autoConvert) ?? base.GetData(format, autoConvert);
    }
}

テキストボックスからフォルダなどにドラッグ&ドロップすると、テキストボックスの内容がTestDnD.txtというファイルに書き出されます。