【问题标题】:Taskbar Minimize C# Windows Form Problem任务栏最小化 C# Windows 窗体问题
【发布时间】:2011-08-14 06:44:37
【问题描述】:

我有一个 Windows 窗体应用程序,当窗体被激活、停用或 SizeChanged 时,窗体会执行一些操作。比较具体。例如:

Form Activated:将变量isActive 设置为true,并将输入集中到输入框,以便某人也可以输入内容。

Form Deactivated:将变量isActive设置为false,这样应用程序中的任何焦点变化(由远程机器消息、聊天消息等引起)都不会从其他人那里窃取焦点应用程序。

现在,我在 Form Activated 事件中使用了我的 webBrowser1.Focus() 命令,这并不理想,因为当您单击任务栏图标时,它会尝试最小化,但由于它会重新集中在网络浏览器上,然后再次恢复/激活表单。

我在 Stack Overflow 上搜索了一下,发现如下信息:

针对以下信息进行了编辑:

我确实在 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);
}

但行为与我在上述 2 个事件中看到的问题相似。当任务栏图标被点击时,表单会捕捉到 Deactivated:

激活错误

但马上,它会这样做:

激活真

看起来,当您使用任务栏按钮最小化一个窗口时,它仍然保持为“焦点”应用程序,直到您单击另一个应用程序。

其中一个帖子确实建议我捕获表单的 GotFocus,但是我找不到 GotFocus 的表单级别的事件,因为 GotFocus 是从控件派生的,而不是应用程序形式。

问题:如何使用任务栏按钮最小化表单,然后在重新显示表单时,让它执行webBrowser1.Focus() 命令将焦点放在应有的位置是吗?

【问题讨论】:

    标签: c# winforms taskbar minimize


    【解决方案1】:

    我不喜欢你的焦点方法,这是一个残酷的黑客,但你可以将焦点的改变推迟一秒钟,例如:

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

    这可以让用户有机会按下最小化按钮。

    【讨论】:

    • 我也不喜欢我的方法;这就是我在这里问的原因。如果有冒犯性,我深表歉意,这从来都不是我的本意:(
    • Thread.Sleep() 在这里绝对没有位置。真丢脸!
    【解决方案2】:

    抱歉,我原以为 GotFocus 事件会对表单起作用,但当窗口本身的焦点发生变化时,它似乎不会触发。

    所以我冒昧地编写了有效的代码。它改为利用 Form Resize 事件。我为您的 Activated 和 Deactivate 事件留下了事件处理程序,以防它们仍然需要,但我认为它们不应该。请务必调用“刷新”,以便重新绘制表单并移动焦点。

        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;
            };
        }
    }
    

    我注释掉了一个测试用例,如果你想抑制基于某个 Windows 状态的移动。希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      这就是我最终解决问题的方法。以前,我在 OnActivated 中的 ActiveElement 上调用 Focus()。但是,除了您注意到的任务栏最小化调用之外,按 Alt-tab 以使您的表单获得焦点不会导致调用 OnActivated。

      因此,我选择查看 WM_ACTIVATE 消息以确定何时给予焦点。来自MSDN docs

      w参数

      低位字指定窗口是被激活还是 停用。此参数可以是以下值之一。这 高位字指定窗口的最小化状态 激活或停用。非零值表示窗口是 最小化。

      [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();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-21
        • 2015-11-18
        相关资源
        最近更新 更多