OneNote不断灰显我的插件按钮

时间:2010-10-25 07:17:49

标签: c# plugins onenote

我在OneNote中创建了一个工具栏按钮,如Daniel Escapa showed。通常,它可以工作,但有时OneNote决定使工具栏按钮变灰,从而无法点击。我无法弄清楚造成这种情况的状态。我该如何防止这种情况?

我小心翼翼地从OnEvent和OnClick处理程序返回true,但是可能有一个特殊情况导致它返回false?这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OneNoteAddin;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.IO;
using OneNote = Microsoft.Office.Interop.OneNote;

namespace NoteTakerPlugin
{

    [Guid("792d0410-d53c-402d-92c9-5db9ea29f644")]
    public class NoteTakerButton : IOneNoteAddIn 
    {
        // for sending messages to window handles
        private struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cbData;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpData;
        }

        // this should be hardcoded in the note taker application
        private const string NoteTakerAppClassName = "CubicNoteTaker-792d0410-d53c-402d-92c9-5db9ea29f644::EventReceiver";

        private const int WM_COPYDATA = 0x4A;

        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

        IntPtr app;

        public NoteTakerButton()
        {
            tellAppSomething("{ \"appStart\": true }", false);
        }

        public bool OnClick([In] String strActivePageID)
        {
            // send the click event to the note taker app
            tellAppSomething("{ \"click\": { \"pageId\": \"" + strActivePageID + "\" }}", true);
            return true;
        }

        public bool OnEvent([In] OneNote.OneNoteAddIn_Event evt, [In] String strParameter)
        {
            // send the event to the note taker app
            tellAppSomething("{ \"event\": { \"id\": " + (int)evt + ", \"param\": \"" + strParameter + "\" }}", false);
            return true;
        }

        private void tellAppSomething(String message, bool startProgram)
        {
            // if the process is running
            refreshAppStatus();
            if( app != IntPtr.Zero  )
            {
                // send a window message to the process telling it the message
                sendMessageTo(app, message);
            }
            else if( startProgram )
            {
                // start the process with a command line telling it the message
                startApp(message);
            }
        }

        private void refreshAppStatus()
        {
            app = FindWindowByCaption(IntPtr.Zero, NoteTakerAppClassName);
        }

        private void sendMessageTo(IntPtr hWnd, String msg)
        {
            int wParam = 0;
            int result = 0;

            if (hWnd != IntPtr.Zero )
            {
                byte[] sarr = System.Text.Encoding.Default.GetBytes(msg);
                int len = sarr.Length;
                COPYDATASTRUCT cds;
                cds.dwData = IntPtr.Zero;
                cds.lpData = msg;
                cds.cbData = len + 1;
                result = SendMessage(hWnd, WM_COPYDATA, wParam, ref cds);
            }
        }

        private void startApp(String args)
        {
            string exe = getAppExe();
            if (File.Exists(exe))
            {
                System.Diagnostics.Process.Start(exe, args);
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("You need to reinstall the Note Taker application. The installation is corrupted.");
            }
        }

        private string getAppExe()
        {
            // use the registry to find where the application is installed
            RegistryKey noteTakerKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\NoteTaker");
            String path = noteTakerKey.GetValue("Path","").ToString();
            String exe = noteTakerKey.GetValue("Exe", "").ToString();

            if (!Directory.Exists(path))
                return "";

            String combo = Path.Combine(path, exe);

            if( File.Exists(combo) )
                return combo;
            else // not installed
                return ""; 
        }
    }
}

2 个答案:

答案 0 :(得分:0)

编辑:我现在记得这个问题!当你关闭OneNote时,检查它的实例是否仍然在taskman中运行,我认为这种类型会在将来的实例中锁定插件并将其灰显,确保没有任何代码继续运行会导致实例停留活着。

答案 1 :(得分:0)

在我的项目属性Build选项卡中,我忘记在Release模式下检查“Register for COM interop”。这导致间歇性错误。