ApplicationContext and SaveFileDialog

G

Guest

in my application, i derive from ApplicationContext to provide a simple
splash window. basically, what happens is:
1. splash window loads
2. splash window starts a new thread to do some initialization, while the
user gets to see the pretty splash window
3. initialization thread ends and calls Invoke(new MethodInvoker(Close)) to
close the splash window
4. custom ApplicationContext overrides OnMainFormClosed() and shows the main
window when the splash window closes.

from here on, i figure my main window should run just fine. and it does,
except:
i have a button that opens a SaveFileDialog, with OverwritePrompt = true.
when i select an existing file, i get the following exception:
System.ObjectDisposedException: Cannot access a disposed object named
"splashform".
Object name: "splashform".
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Form.CreateHandle()
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.ThreadWindows.Callback(IntPtr hWnd, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.EnumThreadWindows(Int32
dwThreadId, EnumThreadWindowsCallback lpfn, HandleRef lParam)
at System.Windows.Forms.ThreadWindows..ctor(Control parent, Boolean
onlyWinForms)
at System.Windows.Forms.ThreadContext.DisableWindowsForModalLoop(Boolean
onlyWinForms)
at System.Windows.Forms.ThreadContext.BeginModalMessageLoop()
at System.Windows.Forms.Application.BeginModalMessageLoop()
at System.Windows.Forms.MessageBox.ShowCore(IWin32Window owner, String
text, String caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options)
at System.Windows.Forms.MessageBox.Show(String text, String caption,
MessageBoxButtons buttons, MessageBoxIcon icon)
at System.Windows.Forms.FileDialog.MessageBoxWithFocusRestore(String
message, String caption, MessageBoxButtons buttons, MessageBoxIcon icon)
at System.Windows.Forms.SaveFileDialog.PromptFileOverwrite(String fileName)
at System.Windows.Forms.SaveFileDialog.PromptUserIfAppropriate(String
fileName)
at System.Windows.Forms.FileDialog.ProcessFileNames()
at System.Windows.Forms.FileDialog.DoFileOk(IntPtr lpOFN)
at System.Windows.Forms.FileDialog.HookProc(IntPtr hWnd, Int32 msg,
IntPtr wparam, IntPtr lparam)
at
System.Windows.Forms.UnsafeNativeMethods.GetSaveFileName(OPENFILENAME_I ofn)
at System.Windows.Forms.SaveFileDialog.RunFileDialog(OPENFILENAME_I ofn)
at System.Windows.Forms.FileDialog.RunDialog(IntPtr hWndOwner)
at System.Windows.Forms.CommonDialog.ShowDialog(IWin32Window owner)
at applicationcontexttext.Form1.button1_Click(Object sender, EventArgs e)
in c:\documents and settings\scott\my documents\visual studio
projects\amazing
programmers\applicationcontexttext\applicationcontexttext\form1.cs:line 95
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons
button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,
Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at
System.Windows.Forms.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(Int32
dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.ThreadContext.RunMessageLoopInner(Int32 reason,
ApplicationContext context)
at System.Windows.Forms.ThreadContext.RunMessageLoop(Int32 reason,
ApplicationContext context)
at System.Windows.Forms.Application.Run(ApplicationContext context)
at applicationcontexttext.Form1.Main()

maybe the SaveFileDialog is trying to create the prompt using the splash
window as its owner? i do not know. here is some minimal example code with
which the problem can be reproduced:

//custom ApplicationContext
public class SplashContext :ApplicationContext {
Form m_applicationForm = null;
public SplashContext(Form splashForm, Form applicationForm)
:base(splashForm) {
m_applicationForm = applicationForm;
}

protected override void OnMainFormClosed(object sender, EventArgs e) {
if (sender is splashform) {
//the splash screen was closed
base.MainForm = m_applicationForm;
base.MainForm.Show();
}
else {
//not the splash screen. proceed normally.
base.OnMainFormClosed(sender, e);
}
}
}

//splashform... just a System.Windows.Forms.Form with:
private void splashform_Load(object sender, System.EventArgs e) {
Thread thread = new Thread(new ThreadStart(ThreadProc));
thread.Start();
}

private void ThreadProc() {
Thread.Sleep(5000);
Invoke(new MethodInvoker(Close));
}

//and the main form....
[STAThread]
static void Main() {
try {
Form1 mainForm = new Form1();
splashform splashWindow = new splashform();
SplashContext scContext = new SplashContext(splashWindow, mainForm);
Application.Run(scContext);
}
catch (Exception e) {
Debug.WriteLine(e.ToString());
}
}

private void button1_Click(object sender, System.EventArgs e) {
SaveFileDialog sfd = new SaveFileDialog();
sfd.OverwritePrompt = true;
sfd.ShowDialog(this);
}

the exception is caught and handled (printed) by the catch block in Main().

any ideas? am i missing something?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top