1

ダイアログを開いたままにして、場合によってはユーザーが入力したファイル名を別のファイル名に置き換えるために、イベントにSaveFileDialog関連付けられたイベントハンドラーでのファイル名を変更したいと思います。FileOk

var dialog = new SaveFileDialog();
...
dialog.FileOk +=
    delegate (object sender, CancelEventArgs e)
    {
        if (dialog.FileName.EndsWith (".foo"))
        {
            dialog.FileName = "xyz.bar";
            e.Cancel = true;
        }
    };

コードをステップ実行すると、FileNameが実際に適切に更新されることが示されますが、イベント ハンドラーが戻ったときに、ダイアログに表示されるファイル名は変更されません。理論的には、次のような Win32 コードを使用して、ダイアログ自体のファイル名を変更できることがわかりました。

class Win32
{
   [DllImport("User32")]
   public static extern IntPtr GetParent(IntPtr);

   [DllImport("User32")]
   public static extern int SetDlgItemText(IntPtr, int string, int);

   public const int FileTitleCntrlID = 0x47c;
}

void SetFileName(IntPtr hdlg, string name)
{
    Win32.SetDlgItemText (Win32.GetParent (hdlg), Win32.FileTitleCntrlID, name);
}

ただし、インスタンスにHDLG関連付けられた をどこから取得できるかわかりません。ラッパーSaveFileDialog全体を自分で書き直すことができることはわかっていますが(またはNuffSaveFileDialog のようなコードや SaveFileDialogのCodeProject 拡張機能を使用することもできます)、技術的な理由から標準の WinForms クラスを使用したいと思います。SaveFileDialog

4

1 に答える 1

2

SetFileNameダイアログハンドルを取得するために、リフレクションを使用し、そのハンドルで呼び出しました。

dialog.FileOk +=
    delegate (object sender, CancelEventArgs e)
    {
        if (dialog.FileName.EndsWith (".foo"))
        {
            Type type = typeof(FileDialog);
            FieldInfo info = type.GetField("dialogHWnd", BindingFlags.NonPublic 
                                                       | BindingFlags.Instance);
            IntPtr fileDialogHandle = (IntPtr)info.GetValue(dialog);

            SetFileName(fileDialogHandle, "xyz.bar");
            e.Cancel = true;
        }
    };

注意:Win32クラスでは、SetDlgItemText関数を定義して(必要はありませんGetParent)、ダイアログハンドルを渡すだけです。

    [DllImport("User32")]
    public static extern int SetDlgItemText(IntPtr hwnd, int id, string title);

    public const int FileTitleCntrlID = 0x47c;

    void SetFileName(IntPtr hdlg, string name)
    {
        SetDlgItemText(hdlg, FileTitleCntrlID, name);
    }

編集:

以前のコードをWindows7で動作させるには(Vistaもそうだと思いますか?)、ダイアログのプロパティShowHelptrue次のように設定します。

dialog.ShowHelp = true;

見た目は少し変わりますが、大したことではないと思います。

于 2009-10-21T09:00:39.640 に答える