Get Hashcode for Excel workbook in VSTO to enable state based buttons

I create a VSTO Ribbon AddIn for excel, and I save the workbook status information in my application, which I use to update the visual buttons. Given that there may be several books, I save this state object in a dictionary in the ThisAddIn class. My problem is that I don’t know how to get a unique Hash / Key / Guid for the book, because all I get is a COM wrapper that constantly changes the hash. rightly, I fully understand this.

One solution that I used for a long time was to create a guide and save it in CustomDocumentProperties for the workbook and display the state based on this as a key. This at least works, but it fails if I create a copy of the workbook and open it in the same instance of the application, and now you have several books with the same director.

Now I got the idea that I can update this Guid on the Workbook_Open event. But still, this seems like a dodgy decision.

The second solution I found here: http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/04efa74d-83bd-434d-ab07-36742fd8410e/

So, I used the guys code and created this:

public static class WorkbookExtensions
{
    public static IntPtr GetHashery(this msExcel.Workbook workbook)
    {
        IntPtr punk = IntPtr.Zero;
        try
        {
            punk = Marshal.GetIUnknownForObject(workbook);
            return punk;
        }
        finally
        {
            //Release to decrease ref count
            Marshal.Release(punk);
        }
    }
}

, "COM-, RCW, " Application.ActiveWorkbook.

COM ? , , GUID ? , state, Marshal.FinalReleaseComObject(workbook)? Ref , FinalRelease , Ribbon Apps ? COM Workbook VSTO, ?

, , , , ? , " ", " ".

Ribbon Designer .

, , .

+5
1

, IntPtr , IntPtr . IntPtr, - .

, . , , WorkbookState, , , .

:

public static class WorkbookExtensions
{
    public static long GetHashery(this msExcel.Workbook workbook)
    {
        if (workbook == null)
        {
            throw new ArgumentNullException("workbook");
        }

        IntPtr pUnknown = IntPtr.Zero;
        try
        {
            pUnknown = Marshal.GetIUnknownForObject(workbook);
            return pUnknown.ToInt64();
        }
        finally
        {
            // GetIUnknownForObject causes AddRef.
            if (pUnknown != IntPtr.Zero)
            {
                Marshal.Release(pUnknown);
            }
        }
    }
}

VSTO/ExcelDna ThisAddIn , - :

private Dictionary<long, WorkbookState> _workbookStates = new Dictionary<long, WorkbookState>();
public WorkbookState WorkbookState
{
    get
    {
        long hash = Application.ActiveWorkbook.GetHashery();
        WorkbookState state;
        if (!_workbookStates.TryGetValue(hash, out state))
        {
            state = _workbookStates[hash] = new WorkbookState();
        }
        return state;
    }
}

, , WorkbookState , ThisAddIn.WorkbookState

+5

All Articles