开发者

Why does one code path show the form on top immediately while the other doesn't?

开发者 https://www.devze.com 2023-03-28 08:53 出处:网络
I\'m maintaining a C# .net program that uses Castle Windsor as a framework. It also uses Skincrafter to decorate the forms.

I'm maintaining a C# .net program that uses Castle Windsor as a framework. It also uses Skincrafter to decorate the forms.

In it we have functionality that detects the presence of a file on a USB device and produces another form to deal with it. The software checks for the file either when a USB Event is raised by Windows or when the user presses a button that forces a recheck.

When the user forces a recheck, if the file is found the form appears on top of the main form and is decorated by Skincrafter. If a USB event is raised then the form is produced, but doesn't appear on top (Have to click on it in the task bar to see it) and is not decorated by Skincrafter.

Both methods for detecting the file reach the same function which tells another part of the program to produce the form to deal with the file. The only difference I have found when debugging is that the force recheck method uses the Main Thread whilst the USB Event method has it's own child thread that goes through to the form being shown.

Is it the seperate thread that's causing Windows not to produce t开发者_开发知识库he form on top (And presumably be ignored by Skincrafter) or is there likely some other issue?

I can post code if required, but the code paths are identical other than the method calling the file check and the data is identical.

Edit - Code:

This is a simple reconstruction that I produced. New WinForms project with System.Management added to references. Just make a form (FormStartPosition set to CenterScreen) with a button and use this code:

public partial class Form1 : Form
{
    private ManagementEventWatcher _eventWatcher = null;
    int devices = 0;

    public Form1()
    {
        InitializeComponent();
            WqlEventQuery q = new WqlEventQuery();
            q.EventClassName = "__InstanceOperationEvent";
            q.WithinInterval = new TimeSpan(0, 0, 3);
            q.Condition = @"TargetInstance ISA 'Win32_USBControllerDevice' ";
            _eventWatcher = new ManagementEventWatcher(q);
            _eventWatcher.EventArrived += new EventArrivedEventHandler(UsbEventArrived);
            _eventWatcher.Start(); // Start listen for events

    }

    private void UsbEventArrived(object sender, EventArrivedEventArgs e)
    {
        if(System.Environment.GetLogicalDrives().Length - devices != 0) {
            ShowThingy();
            devices = System.Environment.GetLogicalDrives().Length;
        }
    }


    private void button1_Click(object sender, EventArgs e)
    {
        ShowThingy();
    }

    private void ShowThingy()
    {
        Form form2 = new Form();
        form2.Size = new Size(50, 50);
        form2.StartPosition = FormStartPosition.CenterParent;
        form2.TopMost = true;
        form2.ShowDialog();
    }

}

Run and insert a USB Device and the form2 Form should appear behind the main form.

This doesn't seem to recreate the problem each time. But the first time I plug a USB device always seems to create the second form behind the first. Clicking the button produces the second form on top every time.

I should note that I'm running Windows 7.


You're not setting the owner for the modal window, and the default is the active window (which may not be your main window).

What happens if you use the overload of ShowDialog that takes an owner?

form2.ShowDialog(this);

If that doesn't work, it smells strongly of a threading issue. Can you try changing your USB event handler to use Invoke on the form?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号