开发者

OneNote keeps greying out my plugin button

开发者 https://www.devze.com 2023-01-21 01:11 出处:网络
I\'ve created a toolbar button in OneNote like Daniel Escapa showed. Usually, it works, but sometimes OneNote decides to grey out the toolbar button, making it impossible to click. I can\'t figure out

I've created a toolbar button in OneNote like Daniel Escapa showed. Usually, it works, but sometimes OneNote decides to grey out the toolbar button, making it impossible to click. I can't figure out what state is causing this. How can I prevent this?

I'm careful to return true from the OnEvent and OnClick handlers, but maybe there's a special case that is causing it to return false? Here is my code:

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


EDIT: I remember this issue, now! When you close OneNote, check if an instance of it is still running in taskman, I think this sort of locks the addon in future instances and grays them out, make sure you dont have any code left running that would be causing the instance to stay alive.


In my project properties Build tab, I had forgotten to check "Register for COM interop" in Release mode. This caused intermittent errors.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号