I have once create such a dialog for a simply paint program which basically
calls the Windows API function GetSaveFileName() and adds a hook procedure
to it which intercepts certain windows messages and this way, allows me to
change the text of the "Help"-button to options and makes it possible to run
custom actions when the user changes the index of the filetypes combo.
Here is the class:
public class NuffSaveFileDialog
{
[StructLayoutAttribute(LayoutKind.Sequential, Pack=1, Size=0,
CharSet=CharSet.Auto)]
struct OFN
{
public int lStructSize;
public IntPtr hwndOwner;
public IntPtr hInstance;
public string lpstrFilter;
public IntPtr lpstrCustomFilter;
public int nMaxCustFilter;
public int nFilterIndex;
public /*IntPtr*/string lpstrFile;
public int nMaxFile;
public IntPtr lpstrFileTitle;
public int nMaxFileTitle;
public string lpstrInitialDir;
public string lpstrTitle;
public int Flags;
public short nFileOffset;
public short nFileExtension;
public string lpstrDefExt;
public IntPtr lCustData;
public /*WndProc*//*IntPtr*/OFNHookProcOldStyle lpfnHook;
public string lpTemplateName;
public IntPtr pvReserved;
public int dwReserved;
public int FlagsEx;
}
const int OFN_READONLY = 0x00000001;
const int OFN_OVERWRITEPROMPT = 0x00000002;
const int OFN_HIDEREADONLY = 0x00000004;
const int OFN_NOCHANGEDIR = 0x00000008;
const int OFN_SHOWHELP = 0x00000010;
const int OFN_ENABLEHOOK = 0x00000020;
const int OFN_ENABLETEMPLATE = 0x00000040;
const int OFN_ENABLETEMPLATEHANDLE = 0x00000080;
const int OFN_NOVALIDATE = 0x00000100;
const int OFN_ALLOWMULTISELECT = 0x00000200;
const int OFN_EXTENSIONDIFFERENT = 0x00000400;
const int OFN_PATHMUSTEXIST = 0x00000800;
const int OFN_FILEMUSTEXIST = 0x00001000;
const int OFN_CREATEPROMPT = 0x00002000;
const int OFN_SHAREAWARE = 0x00004000;
const int OFN_NOREADONLYRETURN = 0x00008000;
const int OFN_NOTESTFILECREATE = 0x00010000;
const int OFN_NONETWORKBUTTON = 0x00020000;
const int OFN_NOLONGNAMES = 0x00040000; // force no long names for 4.x
modules;
const int OFN_EXPLORER = 0x00080000; // new look commdlg;
const int OFN_NODEREFERENCELINKS = 0x00100000;
const int OFN_LONGNAMES = 0x00200000; // force long names for 3.x modules;
const int OFN_ENABLEINCLUDENOTIFY = 0x00400000; // send include message to
callback;
const int OFN_ENABLESIZING = 0x00800000;
const int OFN_DONTADDTORECENT = 0x02000000;
const int OFN_FORCESHOWHIDDEN = 0x10000000; // Show All files including
System and hidden files;
//FlagsEx Values;
const int OFN_EX_NOPLACESBAR = 0x00000001;
[System.Runtime.InteropServices.DllImport("Comdlg32 .dll",
EntryPoint="GetSaveFileNameW")]
//[System.Runtime.InteropServices.DllImport("msvfw32. dll",
EntryPoint="GetSaveFileNamePreviewW")]
unsafe extern static int GetSaveFileName(ref OFN ofn);
[System.Runtime.InteropServices.DllImport("Kernel32 ")]
extern static int GetLastError();
[System.Runtime.InteropServices.DllImport("User32")]
extern static int SetDlgItemText(
IntPtr hDlg,
int nIDDlgItem,
string lpString
);
[System.Runtime.InteropServices.DllImport("User32")]
extern static int GetDlgItemText(
IntPtr hDlg,
int nIDDlgItem,
StringBuilder lpString,
int nMaxCount
);
[System.Runtime.InteropServices.DllImport("User32")]
extern static IntPtr GetParent(
IntPtr hWnd
);
delegate uint OFNHookProcOldStyle
(
IntPtr hdlg,
uint uiMsg,
int wParam,
int lParam
);
const int WM_INITDIALOG = 0x0110;
const int WM_NOTIFY = 0x004E;
const uint CDN_FIRST = unchecked(0u-601u);
const uint CDN_HELP = (CDN_FIRST - 0x0004);
[StructLayoutAttribute(LayoutKind.Sequential, Pack=1, Size=0,
CharSet=CharSet.Auto)]
struct NMHDR
{
public IntPtr hwndFrom;
public uint idFrom;
public uint code; // NM_ code
}
unsafe static uint OfnHook(
IntPtr hdlg,
uint uiMsg,
int wParam,
int lParam
)
{
Console.WriteLine(uiMsg+" "+wParam+" "+lParam);
// nowhere documented but seems to work
if (uiMsg==49313 && wParam==1136)
{
const int FileTitleCntrlID = 0x47c;
CurrentDialog.FilterIndex = lParam;
NuffImageEncoder nie =
(NuffImageEncoder)NuffImageEncoder.EncoderInfoList[CurrentDialog.FilterIndex
];
StringBuilder sb = new StringBuilder(255);
GetDlgItemText(GetParent(hdlg), FileTitleCntrlID, sb, 255);
string s = Path.ChangeExtension(sb.ToString(), nie.DefaultExtension);
SetDlgItemText(GetParent(hdlg), FileTitleCntrlID, s);
}
switch (uiMsg)
{
case WM_INITDIALOG:
SetDlgItemText(GetParent(hdlg), 0x40e, "Options");
break;
case WM_NOTIFY:
NMHDR nmhdr = (NMHDR)Marshal.PtrToStructure(new IntPtr(lParam),
typeof(NMHDR));
if (nmhdr.code==CDN_HELP)
{
NuffImageEncoder nie =
(NuffImageEncoder)NuffImageEncoder.EncoderInfoList[CurrentDialog.FilterIndex
];
nie.RunSettingsDialog();
}
break;
}
return 0;
}
public NuffSaveFileDialog()
{
}
static NuffSaveFileDialog CurrentDialog;
public int FilterIndex;
string fileName;
string filter;
OFN ofn;
public string Filter
{
get
{
return this.filter;
}
set
{
this.filter=value;
}
}
public string FileName
{
get
{
return this.fileName;
}
}
public unsafe DialogResult ShowDialog()
{
ofn = new OFN();
ofn.hInstance = Marshal.GetHINSTANCE(typeof(MainWindow).Module);
ofn.lStructSize = Marshal.SizeOf(typeof(OFN));
//ofn.hwndOwner = form.Handle;
ofn.lpstrFilter = filter;
ofn.lpfnHook = new OFNHookProcOldStyle(OfnHook);
ofn.Flags |=
OFN_EXPLORER|OFN_ENABLEHOOK|OFN_EXTENSIONDIFFERENT |OFN_SHOWHELP|OFN_OVERWRIT
EPROMPT|OFN_ENABLESIZING;
const int MaxFile = 8192;
NuffImageEncoder nie =
(NuffImageEncoder)NuffImageEncoder.EncoderInfoList[0];
string Unnamed = "Unnamed."+nie.DefaultExtension;
ofn.nMaxFileTitle = 260;
ofn.nMaxFile = MaxFile;
ofn.lpstrFile = Unnamed+new string(new char[MaxFile-Unnamed.Length-1]);
CurrentDialog = this;
int res = GetSaveFileName(ref ofn);
if (res!=0)
{
this.fileName = ofn.lpstrFile;
return DialogResult.OK;
}
else
{
return DialogResult.Cancel;
}
}
}
//-------- end code -------------------------------------//
you simply call it like:
NuffSaveFileDialog dlg = new NuffSaveFileDialog();
dlg.ShowDialog();
--
cody
[Freeware, Games and Humor]
www.deutronium.de.vu ||
www.deutronium.tk