代码之家  ›  专栏  ›  技术社区  ›  JamesMLV

窗体一旦丢失就不能接收焦点

  •  4
  • JamesMLV  · 技术社区  · 14 年前

    我已经为visualstudio2008创建了一个外接程序,它使用 Form1.Show(this);

    如果(在窗体打开时)用户打开/关闭VisualStudio对话框(例如程序集信息),则用户无法将焦点放回由加载项创建的窗体上。

    是否缺少允许用户返回表单的内容?如果我使用 Form1.ShowDialog(this) ,但我希望用户在自定义窗体打开时查看程序集信息。

    外接程序实现 IWin32Window 使用

    public System.IntPtr Handle
    {
        get
        {
            return new System.IntPtr(_applicationObject.MainWindow.HWnd);
        }
    }
    

  • 创建visual studio外接程序项目
  • 将以下内容添加到 public void Exec(...)
    System.Windows.Forms.Form f = new System.Windows.Forms.Form();
    f.Show();
    

  • 运行外接程序,并在已启动的VisualStudio实例中打开一个项目
  • 打开“项目属性”,转到“应用程序”选项卡,打开“程序集信息”,然后将其关闭。
  • 2 回复  |  直到 14 年前
        1
  •  5
  •   Nope landerton    14 年前

    谢谢你的复制步骤。我能重现你的问题。

    据我所知,VisualStudioIDE使用控件而不是窗体。

    由于不知道表单的预期功能是什么,我只是在下面添加了一个基本示例来开始。

    很容易有很多其他的方法可以做到这一点。我不是插件开发人员,因此我在这方面的知识是有限的。

    用户控件

    首先,右键单击项目并添加新的用户控件。在我的示例中,我将我的表单命名为“MyForm”,并在其上放置了一个简单的按钮,单击时显示“Hello”。 这个用户控件将成为您的窗体。

    namespace MyAddin1
    {
        public partial class MyForm : UserControl
        {
            public MyForm()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                MessageBox.Show("Hello");
            }
        }
    }
    

    创建窗体

    我们需要使用承载您的加载项的应用程序和加载项的实例。 这两个成员都已在外接程序项目中声明:\u applicationObject和\u addInInstance。这些是在OnConnection事件中设置的。

    在下面的代码中,我创建了一个新的工具窗口,在其中托管我的用户控件。我使用的是Windows2.CreateTooWindow2方法。

    我已经将示例代码添加到EXEC事件中,如下所示。再说一次,我不确定这是否是它的正确位置,但为了演示代码,它应该足够了。

    /// <summary>Implements the Exec method of the IDTCommandTarget interface. This is called when the command is invoked.</summary>
    /// <param term='commandName'>The name of the command to execute.</param>
    /// <param term='executeOption'>Describes how the command should be run.</param>
    /// <param term='varIn'>Parameters passed from the caller to the command handler.</param>
    /// <param term='varOut'>Parameters passed from the command handler to the caller.</param>
    /// <param term='handled'>Informs the caller if the command was handled or not.</param>
    /// <seealso class='Exec' />
    public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
    {
        object tempObject = null;   // It's required but I'm not sure what one can do with it...
        Windows2 windows2 = null;   // Reference to the window collection displayed in the application host.
        Assembly asm = null;        // The assembly containing the user control.
        Window myWindow = null;     // Will contain the reference of the new Tool Window.
    
        try
        {
            handled = false;
    
            if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
            {
                if (commandName == "MyAddin1.Connect.MyAddin1")
                {
                    handled = true;
    
                    // Get a reference to the window collection displayed in the application host.
                    windows2 = (Windows2)_applicationObject.Windows;
    
                    // Get the executing assembly.
                    asm = Assembly.GetExecutingAssembly();
    
                    // Create the tool window and insert the user control.
                    myWindow = windows2.CreateToolWindow2(_addInInstance, asm.Location, "MyAddin1.MyForm", "My Tool Window", "{CB2AE2BD-2336-4615-B0A3-C55B9C7794C9}", ref tempObject);
    
                    // Set window properties to make it act more like a modless form.
                    myWindow.Linkable = false;  // Indicates whether the window can be docked with other windows in the IDE or not.
                    myWindow.IsFloating = true; // Indicates whether the window floats over other windows or not.
    
                    // Show the window.
                    myWindow.Visible = true;
    
                    return;
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    

    我测试了这个应用程序,它确实将我的外接程序添加到IDE的“工具”菜单中,当我单击我的外接程序时,它显示了窗口,并且工作正常。在显示装配对话框时,它也没有冻结、挂起或任何东西。