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