Simulate Form's ShowDialog with other control (threading?)

G

Guest

I want to extend a ListBox by adding a ShowDialog method that will wait (block) the main thread until the user has selected an item in the ListBox (i.e. similar to Form.ShowDialog). I'm not clear about what threads are running behind the scenes in C# (GUI, etc.). How can I block the main thread while allowing the GUI thread and also (if needed) a separate thread to handle the ListBox events. Once the user has selected an item or has selected outside the ListBox, I would unblock the main thread and return the result

I already have this working by putting a ListBox inside of a Form, but the dialog (of ShowDialog) takes focus away from the main application when shown (application title is out of focus since dialog has focus).

If I can duplicate the blocking mechanism of the ShowDialog method, I will be able to keep all focus within the application. Note: I use Capture to handle mouse clicks outside of the ListBox.
 
G

Guest

Well, I know this might not be the best way, and I have to admit that I didn't try it, but in theory it should work. Try to show the form using Show, then save the Form's handle in a IntPtr and call the Win32 function WaitForSingleObject. This function will wait until the handle of the Form is "signaled", e.g. destroyed. I am not sure if you should override the Form's close event and specifically request the handle to be destroyed, or if it is done automatically by Close()...
 
G

Guest

Does anyone at Microsoft have sample code from the Form.ShowDialog method that would show how to block the calling thread, but leave the GUI (+ any other threads) running - so that a user still interact?
 
G

Guest

Perhaps you can create something like Application.RunDialog that does this

internal static void RunDialog(Form form
{
ThreadContext.FromCurrent().RunMessageLoop(4, new ModalApplicationContext(form))
 
G

Guest

Here it is

public DialogResult ShowDialog(IWin32Window owner
{ IntPtr ptr1
IntPtr ptr2
IntPtr ptr3
Form form1
object[] array1
if (owner == this

array1 = new object[1]
array1[0] = "showDialog"
throw new ArgumentException(SR.GetString("OwnsSelfOrOwner", array1), "owner")


if (base.Visible

array1 = new object[1]
array1[0] = "showDialog"
throw new InvalidOperationException(SR.GetString("ShowDialogOnVisible", array1))


if (!base.Enabled

array1 = new object[1]
array1[0] = "showDialog"
throw new InvalidOperationException(SR.GetString("ShowDialogOnDisabled", array1))


if (!this.TopLevel

array1 = new object[1]
array1[0] = "showDialog"
throw new InvalidOperationException(SR.GetString("ShowDialogOnNonTopLevel", array1))


if (this.Modal

array1 = new object[1]
array1[0] = "showDialog"
throw new InvalidOperationException(SR.GetString("ShowDialogOnModal", array1))


if (!SystemInformation.UserInteractive

throw new InvalidOperationException(SR.GetString("CantShowModalOnNonInteractive"))


if ((owner != null) && (((UnsafeNativeMethods.GetWindowLong(new HandleRef(owner, owner.Handle), -20) & 8) == 0) && ((owner as Control) != null))

owner = ((Control) owner).TopLevelControl


this.calledOnLoad = false
this.calledMakeVisible = false
ptr1 = UnsafeNativeMethods.GetCapture()
if (ptr1 != IntPtr.Zero

UnsafeNativeMethods.SendMessage(new HandleRef(null, ptr1), 31, IntPtr.Zero, IntPtr.Zero)
SafeNativeMethods.ReleaseCapture()


ptr2 = UnsafeNativeMethods.GetActiveWindow()
ptr3 = ((owner == null) ? ptr2 : owner.Handle)
base.Properties.SetObject(Form.PropDialogOwner, owner)
form1 = this.OwnerInternal
if (((owner as Form) != null) && (owner != form1)

this.Owner = ((Form) owner)


tr

base.SetState(32, 1)
this.dialogResult = 0
base.CreateControl()
if ((ptr3 != IntPtr.Zero) && (ptr3 != base.Handle)

if (UnsafeNativeMethods.GetWindowLong(new HandleRef(owner, ptr3), -8) == base.Handle

array1 = new object[1]
array1[0] = "showDialog"
throw new ArgumentException(SR.GetString("OwnsSelfOrOwner", array1), "owner")


UnsafeNativeMethods.GetWindowLong(new HandleRef(this, base.Handle), -8)
UnsafeNativeMethods.SetWindowLong(new HandleRef(this, base.Handle), -8, new HandleRef(owner, ptr3))


tr

base.Visible = true
if (this.dialogResult == 0

Application.RunDialog(this)


goto L_02EE


finall

if (!UnsafeNativeMethods.IsWindow(new HandleRef(null, ptr2))

ptr2 = ptr3


if (UnsafeNativeMethods.IsWindow(new HandleRef(null, ptr2)) && SafeNativeMethods.IsWindowVisible(new HandleRef(null, ptr2))

UnsafeNativeMethods.SetActiveWindow(new HandleRef(null, ptr2))


base.SetVisibleCore(0)
if (base.IsHandleCreated

IntSecurity.ManipulateWndProcAndHandles.Assert()
tr

base.DestroyHandle()


finall

CodeAccessPermission.RevertAssert()




base.SetState(32, 0)




finall

this.Owner = form1
base.Properties.SetObject(Form.PropDialogOwner, null)



L_02EE
return this.DialogResult;
}
 

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