开发者

Windows requires a click to activate a window before a second click will select a button. How can I change this?

My application is a C# Windows Forms Application and .Net somehow makes the default behavior of my main menu bar and tool strip buttons to be that you have to first click on my app's window (anywhere), before it will let you click the menu or tool strip button. How can I change this?

Old apps like Notepad and WordPad don't behave this way. But all the Microsoft Office apps do. But this is so annoying!

It gets worse because my app pops up secondary windo开发者_运维技巧ws and each time I change windows, I have to first activate the blasted window before I can do anything. Ugh!

I am hoping there is some global way to change this behavior, so I don't have to override lots of controls individually (I haven't tried that). Does anybody know?

Note that controls on my app's dialogs don't exhibit this stupid behavior. Why are they different?


Well, I ended up finding my own solution that it pretty simple. I derive my own ToolStrip class (and MenuStrip class) as follows:

// This version of ToolStrip enables mouse click's even when the main form is NOT active.
private class MyToolStrip : ToolStrip
{
    const uint WM_LBUTTONDOWN = 0x201;
    const uint WM_LBUTTONUP   = 0x202;

    static private bool down = false;

    protected override void WndProc(ref Message m)
    {
        if (m.Msg==WM_LBUTTONUP && !down) {
            m.Msg=(int)WM_LBUTTONDOWN; base.WndProc(ref m);
            m.Msg=(int)WM_LBUTTONUP;
            }

        if (m.Msg==WM_LBUTTONDOWN) down=true;
        if (m.Msg==WM_LBUTTONUP)   down=false;

        base.WndProc(ref m);
    }
}

It appears that, just like the Mac OS X, Windows has made a GUI style decision that requires one to first activate a window BEFORE it will allow any controls to be selected. However, Windows only does this for specific controls, like ToolStrip and MenuStrip. When your window is NOT active, these controls are not sent the mouse DOWN event. I'm not sure how WinForms enforces this GUI guideline, but perhaps it uses a message filter using Application.AddMessageFilter().

Regardless, the MenuStrip controls STILL get the mouse UP event. And that inspired my solution. I simply look for any mouse UP event that is missing it's corresponding DOWN event. When I see this peculiar case, I generate my own mouse DOWN event, and for the ToolStrip controls, the world is all happy. :-)


easy and clean solution

public class MyToolStrip : System.Windows.Forms.ToolStrip
{
    protected override void OnMouseEnter(EventArgs e)
    {
        if (this.CanFocus && !this.Focused)
            this.Focus();

        base.OnMouseEnter(e);
    }
}


This seems to be simpler solution:

Register MainMenu component onto Toolbox bar, (in Visual Studio, use menu "Tools", then option "Choose Toolbox Items", then find "MainMenu"), and then use it on a form instead of MenuStrip.


You can detect the click on your form even when the application doesn't have focus if you subscribe for the MouseClick event.

Then, when you click your form, you'll get the callback whether the form previously had focus or not.

Then you can simulate the click on the control that you want.

This isn't a terribly elegant solution, but it should work. You do have to make sure that the click doesn't get sent to your toolbar button twice.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜