locked
FAQs: 如何为VSTO应用程序创建一个初始屏幕? RRS feed

答案

  • VSTO里创建一个初始屏幕是很平常的需求。你可以采用两种方法。第一种也就是最初能想到的是简单地在后台线程中显示模态窗口。这可能是最直接的方法,代码如下:

    using System;

    using System.Collections.Generic;

    using System.Data;

    using System.Linq;

    using System.Text;

    using System.Windows.Forms;

    using System.Xml.Linq;

    using Microsoft.VisualStudio.Tools.Applications.Runtime;

    using Excel = Microsoft.Office.Interop.Excel;

    using Office = Microsoft.Office.Core;

    using System.Threading;

    namespace ExcelWorkbook13

    {

    public delegate void InvokeClose();

    public partial class Sheet1

    {

    private Form1 m_splashScreen = new Form1();

    private void Sheet1_Startup(object sender, System.EventArgs e)

    {

    // 准确地,NativeWindow作为子类(不必要的)// 创建自己的IWin32Window 实现也许更可取

    // 因为它是比较安全的IntPtr hwndExcel = new IntPtr(Application.Hwnd);

    NativeWindow parent = new NativeWindow();

    parent.AssignHandle(hwndExcel);

     

    try

    {

    Thread t = new Thread(SplashScreenProc);

    t.Start(parent);

    // 考虑:可能想为同步使用事件来确保在开始操作之前//显示出示屏幕

    // 循环操作for (int i = 1; i < 10000; i++)

    {

    Excel.Range r = (Excel.Range)this.Cells[i, 1];

    r.Value2 = i;

    }

    // 必须使用invoke,因为正在调用交叉的线程InvokeClose invokeClose = new InvokeClose(m_splashScreen.Close);

    m_splashScreen.Invoke(invokeClose);

    }

    finally

    {

    // 必须经常撤销子类,否则会失败Must always undo the subclass or you can crash!

    parent.ReleaseHandle();

    }

    }

    //显示初始屏幕 Display the splash screen

    private void SplashScreenProc(object param)

    {

    //撤销: UNDONE: 确定出初始屏幕的位置 the splash screen.

    IWin32Window parent = (IWin32Window)param;

    m_splashScreen.ShowDialog(parent);

    }

    }

    }

    另外一种方法是在进行长任务之前(正如Martin建议的那样),在主线程中显示非模态窗口。如果你那样做,你将需要在每次循环中弹出消息。这正是Martin的代码遗漏的。可能你也想P/Invoke Win32 PeekMessage函数来做这些,因为你可能想阻止多数的消息被调度(也就是 你不想调度用户输入消息,但是你想调度OLERPC消息,这个消息将避免以前看到的ContextSwitchDeadlock MDA)。你将需要创建一个消息弹出循环,大致是这样的:

    while (PeekMessage(...))

    {

        DispatchMessage(...);

    }

     

    System.Windows.Forms.Application.DoEvents 将会你做这些工作,但是它也会让所有的消息通过,所以用户输入将被加工。也有点奇怪,因为VSTO不是Windows窗体应用程序,所以有可能(尽管可能性很小)DoEvents的实现在将来可以改变,以至于在上下文中它将不再与预期相符。

    这个方法可行,但是它很难实现,比较慢。所以对于多数的情况,在后台线程中显示初始屏幕更有意义。

    相关的论坛帖子:http://social.msdn.microsoft.com/forums/en-US/vsto/thread/2cbf9c7c-f562-4028-9673-d8e5cdf0dc77/

    更多的有关VSTOFAQ,请看:

    http://social.msdn.microsoft.com/Forums/zh-CN/vstudiozhchs/thread/ed10f3de-40bb-4f16-81f9-25ace1f152ba


    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载  MSDN 论坛好帮手
    2011年2月28日 10:06