Taskbar Minimize C# Windows Form Problem

大兔子大兔子 提交于 2019-12-13 02:02:03

问题


I have a Windows Form application that, when the form is Activated, Deactivated, or SizeChanged, the form does something. It's rather specific. For example:

Form Activated: Will set the variable isActive to true, and focus the input to an input box for someone to enter something too.

Form Deactivated: Will set the variable isActive to false, so that any focus changes in the application (caused by remote machine messages, chat messages, etc), does not steal focus from other applications.

Right now, I have my webBrowser1.Focus() command inside of the Form Activated event which isn't ideal, as when you click on the taskbar icon, it tries to minimize, but since it focuses back to the web browser, the form is then restored/activated again.

I did some searching here on Stack Overflow, and found the following information:

Edited for the below information:

I did find this information in another post here on Stack Overflow:

protected void OnActivateApp(bool activate)
{
    Console.WriteLine("Activate {0}", activate);
}

protected override void WndProc(ref System.Windows.Forms.Message m)
{
    // Trap WM_ACTIVATEAPP
    if (m.Msg == 0x1c) OnActivateApp(m.WParam != IntPtr.Zero);
    base.WndProc(ref m);
}

But the behavior is similar to the problem I'm seeing with the above 2 events. When the taskbar icon is CLICKED, the form does catch the Deactivated:

Activate False

But then immediately, it does this:

Activate True

It would appear, that when you minimize a window with the taskbar button, it still remains as the 'focused' application until you click on another application.

One of the posts did suggest I capture the GotFocus of the form, but there is no event that I can find for a form level for GotFocus, as GotFocus is derived from a control, not an application form.

Question: How do I allow the form to be minimized with the taskbar button, and when the form is then reshown, get it to do the webBrowser1.Focus() command to put the focus where it should be?


回答1:


Sorry I had thought the GotFocus Event would work against the Form but it seems not to fire when the focus on the window itself changes.

So I took the liberty of writing code that does work. It taps into the Form Resize Event instead. I left event handlers for your Activated and Deactivate events in case they were still required but I dont think they should be. Just be sure to call 'Refresh' so the form repaints and the focus moves.

    public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private bool isActive = false;
    private FormWindowState previousstate;
    private void Form1_Load(object sender, EventArgs e)
    {
        previousstate = this.WindowState;
        //Got Focus Anonymous Delegate handles focus on the textbox
        //if the Form currently is Activated
        this.Resize += delegate(object resizesender, EventArgs resizee)
        {
            //if (previousstate == FormWindowState.Minimized)
            // {
                txtGetFocus.Focus();
                this.Refresh();
            // }
            previousstate = this.WindowState;
        };
        this.Activated += delegate(object activatedsender, EventArgs activatede)
        {
            isActive = true;
        };
        this.Deactivate += delegate(object deactivatesender, EventArgs deactivatee)
        {
            isActive = false;
        };
    }
}

I commented out a test case in the event you want to suppress movement based on a certain Windowstate. Hope this helps.




回答2:


Here's how I ended up solving the problem. Previously, I was calling Focus() on the ActiveElement in OnActivated. However, in addition to the taskbar minimization call you noticed, pressing Alt-tab to give your form focus also doesn't cause a call to OnActivated.

As a result, I chose to look at the WM_ACTIVATE message to determine when to give focus. From the MSDN docs:

wParam

The low-order word specifies whether the window is being activated or deactivated. This parameter can be one of the following values. The high-order word specifies the minimized state of the window being activated or deactivated. A nonzero value indicates the window is minimized.

[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
protected override void WndProc(ref Message message)
{
    base.WndProc(ref message);
    if (message.Msg == 0x6)
    {
        int highOrderWord = (int)((message.WParam.ToInt32() & 0xFFFF0000) >> 16);
        bool minimized = highOrderWord != 0;
        bool activating = message.WParam != IntPtr.Zero;
        if (activating && !minimized)
        {
            this.FocusBrowserElement();
        }
    }
}


private void FocusBrowserElement()
{
    if (!this.webBrowser.IsDisposed && 
         this.webBrowser.Document != null &&
         this.webBrowser.Document.ActiveElement != null)
    {
        this.webBrowser.Document.ActiveElement.Focus();
    }
}



回答3:


I don't like your approach with the focuses and this is a brutal hack but you could postpone the change of focus for one second liek this:

Thread t = new Thread((ThreadStart)delegate(){
  Thread.Sleep(1000);
  this.Invoke(methodChangingFocus, new object[] {});
}).Start();

That could give the opportunity to the user to press the minimize button.



来源:https://stackoverflow.com/questions/5811739/taskbar-minimize-c-sharp-windows-form-problem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!