/// <summary>
        /// Called to invoke the comamand.
        /// </summary>
        /// <param name="pici">The command info pointer.</param>
        int IContextMenu.InvokeCommand(IntPtr pici)
        {
            //  We'll work out whether the commandis unicode or not...
            var isUnicode = false;

            //  We could have been provided with a CMINVOKECOMMANDINFO or a
            //  CMINVOKECOMMANDINFOEX - cast to the small and then check the size.
            var ici = (CMINVOKECOMMANDINFO)Marshal.PtrToStructure(pici, typeof(CMINVOKECOMMANDINFO));
            var iciex = new CMINVOKECOMMANDINFOEX();

            //  Is it a CMINVOKECOMMANDINFOEX?
            if (ici.cbSize == Marshal.SizeOf(typeof(CMINVOKECOMMANDINFOEX)))
            {
                //  Check the unicode flag, get the extended command info.
                if ((ici.fMask & CMIC.CMIC_MASK_UNICODE) != 0)
                {
                    isUnicode = true;
                    iciex = (CMINVOKECOMMANDINFOEX)Marshal.PtrToStructure(pici,
                        typeof(CMINVOKECOMMANDINFOEX));
                }
            }

            //  If we're not unicode and the verb hiword is not zero,
            //  we've got an ANSI verb string.
            if (!isUnicode && User32.HighWord(ici.verb.ToInt32()) != 0)
            {
                //  Get the verb.
                var verb = Marshal.PtrToStringAnsi(ici.verb);

                //  DebugLog this key event.
                Log(string.Format("Invoke ANSI verb {0}", verb));

                //  Try and invoke the command. If we don't invoke it, throw
                //  E_FAIL so that other handlers can try.
                if (!nativeContextMenuWrapper.TryInvokeCommand(verb))
                    Marshal.ThrowExceptionForHR(WinError.E_FAIL);
            }
            //  If we're unicode, and the verb hiword is not zero,
            //  we've got a unicode command string.
            else if (isUnicode && User32.HighWord(iciex.verbW.ToInt32()) != 0)
            {
                //  Get the verb.
                var verb = Marshal.PtrToStringAnsi(ici.verb);

                //  DebugLog this key event.
                Log(string.Format("Invoke Unicode verb {0}", verb));

                //  Try and invoke the command. If we don't invoke it, throw
                //  E_FAIL so that other handlers can try.
                if (!nativeContextMenuWrapper.TryInvokeCommand(verb))
                    Marshal.ThrowExceptionForHR(WinError.E_FAIL);
            }
            //  The verb pointer isn't a string at all, it's an index.
            else
            {
                //  Get the command index. Logically, we don't actually need to
                //  loword it, as the hiword is zero, but we're following the
                //  documentation rigourously.
                var index = User32.LowWord(ici.verb.ToInt32());

                //  DebugLog this key event.
                Log(string.Format("Invoke command index {0}", index));

                //  Try and invoke the command. If we don't invoke it, throw
                //  E_FAIL so that other handlers can try.
                if (!nativeContextMenuWrapper.TryInvokeCommand(index))
                    Marshal.ThrowExceptionForHR(WinError.E_FAIL);
            }

            //  Return success.
            return WinError.S_OK;
        }
 /// <summary>
 /// Saves the invoke command information.
 /// </summary>
 /// <param name="isUnicode">if set to <c>true</c> the unicode structure is used.</param>
 /// <param name="ici">The ici.</param>
 /// <param name="iciex">The iciex.</param>
 private void SaveInvokeCommandInfo(bool isUnicode, CMINVOKECOMMANDINFO ici, CMINVOKECOMMANDINFOEX iciex)
 {
     if (isUnicode)
     {
         //  Create command info from the Unicode structure.
         currentInvokeCommandInfo = new InvokeCommandInfo
         {
             WindowHandle = iciex.hwnd,
             ShowCommand = iciex.nShow
         };
     }
     else
     {
         //  Create command info from the ANSI structure.
         currentInvokeCommandInfo = new InvokeCommandInfo
         {
             WindowHandle = ici.hwnd,
             ShowCommand = ici.nShow
         };
     }
 }