/// <summary> /// Carry out the command associated with a shortcut menu item. /// </summary> /// <param name="pici"> /// A pointer to a CMINVOKECOMMANDINFO or CMINVOKECOMMANDINFOEX structure /// containing information about the command. /// </param> public void InvokeCommand(IntPtr pici) { bool isUnicode = false; // Determine which structure is being passed in, CMINVOKECOMMANDINFO or // CMINVOKECOMMANDINFOEX based on the cbSize member of lpcmi. Although // the lpcmi parameter is declared in Shlobj.h as a CMINVOKECOMMANDINFO // structure, in practice it often points to a CMINVOKECOMMANDINFOEX // structure. This struct is an extended version of CMINVOKECOMMANDINFO // and has additional members that allow Unicode strings to be passed. CMINVOKECOMMANDINFO ici = (CMINVOKECOMMANDINFO)Marshal.PtrToStructure( pici, typeof(CMINVOKECOMMANDINFO)); CMINVOKECOMMANDINFOEX iciex = new CMINVOKECOMMANDINFOEX(); if (ici.cbSize == Marshal.SizeOf(typeof(CMINVOKECOMMANDINFOEX))) { if ((ici.fMask & CMIC.CMIC_MASK_UNICODE) != 0) { isUnicode = true; iciex = (CMINVOKECOMMANDINFOEX)Marshal.PtrToStructure(pici, typeof(CMINVOKECOMMANDINFOEX)); } } // Determines whether the command is identified by its offset or verb. // There are two ways to identify commands: // // 1) The command's verb string // 2) The command's identifier offset // // If the high-order word of lpcmi->lpVerb (for the ANSI case) or // lpcmi->lpVerbW (for the Unicode case) is nonzero, lpVerb or lpVerbW // holds a verb string. If the high-order word is zero, the command // offset is in the low-order word of lpcmi->lpVerb. // For the ANSI case, if the high-order word is not zero, the command's // verb string is in lpcmi->lpVerb. if (!isUnicode && NativeMethods.HighWord(ici.verb.ToInt32()) != 0) { // Is the verb supported by this context menu extension? if (Marshal.PtrToStringAnsi(ici.verb) == this.verb) { OnVerbDisplayFileName(ici.hwnd); } else { string verb = Marshal.PtrToStringAnsi(ici.verb); System.Windows.Forms.MessageBox.Show("Ansi - " + verb); // If the verb is not recognized by the context menu handler, it // must return E_FAIL to allow it to be passed on to the other // context menu handlers that might implement that verb. Marshal.ThrowExceptionForHR(WinError.E_FAIL); } } // For the Unicode case, if the high-order word is not zero, the // command's verb string is in lpcmi->lpVerbW. else if (isUnicode && NativeMethods.HighWord(iciex.verbW.ToInt32()) != 0) { // Is the verb supported by this context menu extension? if (Marshal.PtrToStringUni(iciex.verbW) == this.verb) { OnVerbDisplayFileName(ici.hwnd); } else { string verb = Marshal.PtrToStringAnsi(iciex.verbW); System.Windows.Forms.MessageBox.Show("Unicode - " + verb); // If the verb is not recognized by the context menu handler, it // must return E_FAIL to allow it to be passed on to the other // context menu handlers that might implement that verb. Marshal.ThrowExceptionForHR(WinError.E_FAIL); } } // If the command cannot be identified through the verb string, then // check the identifier offset. else { int verb = NativeMethods.LowWord(ici.verb.ToInt32()); string temp = "start "; // Loop over pairs with foreach foreach (KeyValuePair <int, string> pair in pathMap) { temp += pair.Key + " " + pair.Value + " "; } //System.Windows.Forms.MessageBox.Show(verb.ToString() + temp); if (pathMap.ContainsKey(verb)) { //System.Windows.Forms.MessageBox.Show(pathMap[verb]); if (System.Windows.Forms.DialogResult.OK == System.Windows.Forms.MessageBox.Show("Copy " + selectedFile + " to " + pathMap[verb] + "?", "Confirm Copy", System.Windows.Forms.MessageBoxButtons.OKCancel)) { //System.Windows.Forms.MessageBox.Show("copying..."); try { File.Copy(this.selectedFile, Path.Combine(pathMap[verb], Path.GetFileName(this.selectedFile))); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show("Unable to Copy: " + ex.Message); } } //System.Windows.Forms.MessageBox.Show("done..."); } else { // If the verb is not recognized by the context menu handler, it // must return E_FAIL to allow it to be passed on to the other // context menu handlers that might implement that verb. Marshal.ThrowExceptionForHR(WinError.E_FAIL); } } }
/// <summary> /// Carry out the command associated with a shortcut menu item. /// </summary> /// <param name="pici"> /// A pointer to a CMINVOKECOMMANDINFO or CMINVOKECOMMANDINFOEX structure /// containing information about the command. /// </param> public void InvokeCommand(IntPtr pici) { bool isUnicode = false; // Determine which structure is being passed in, CMINVOKECOMMANDINFO or // CMINVOKECOMMANDINFOEX based on the cbSize member of lpcmi. Although // the lpcmi parameter is declared in Shlobj.h as a CMINVOKECOMMANDINFO // structure, in practice it often points to a CMINVOKECOMMANDINFOEX // structure. This struct is an extended version of CMINVOKECOMMANDINFO // and has additional members that allow Unicode strings to be passed. CMINVOKECOMMANDINFO ici = (CMINVOKECOMMANDINFO)Marshal.PtrToStructure( pici, typeof(CMINVOKECOMMANDINFO)); CMINVOKECOMMANDINFOEX iciex = new CMINVOKECOMMANDINFOEX(); if (ici.cbSize == Marshal.SizeOf(typeof(CMINVOKECOMMANDINFOEX))) { if ((ici.fMask & CMIC.CMIC_MASK_UNICODE) != 0) { isUnicode = true; iciex = (CMINVOKECOMMANDINFOEX)Marshal.PtrToStructure(pici, typeof(CMINVOKECOMMANDINFOEX)); } } // Determines whether the command is identified by its offset or verb. // There are two ways to identify commands: // // 1) The command's verb string // 2) The command's identifier offset // // If the high-order word of lpcmi->lpVerb (for the ANSI case) or // lpcmi->lpVerbW (for the Unicode case) is nonzero, lpVerb or lpVerbW // holds a verb string. If the high-order word is zero, the command // offset is in the low-order word of lpcmi->lpVerb. // For the ANSI case, if the high-order word is not zero, the command's // verb string is in lpcmi->lpVerb. if (!isUnicode && NativeMethods.HighWord(ici.verb.ToInt32()) != 0) { // Is the verb supported by this context menu extension? if (Marshal.PtrToStringAnsi(ici.verb) == this.verb) { OnVerbDisplayFileName(ici.hwnd); } else { // If the verb is not recognized by the context menu handler, it // must return E_FAIL to allow it to be passed on to the other // context menu handlers that might implement that verb. Marshal.ThrowExceptionForHR(WinError.E_FAIL); } } // For the Unicode case, if the high-order word is not zero, the // command's verb string is in lpcmi->lpVerbW. else if (isUnicode && NativeMethods.HighWord(iciex.verbW.ToInt32()) != 0) { // Is the verb supported by this context menu extension? if (Marshal.PtrToStringUni(iciex.verbW) == this.verb) { OnVerbDisplayFileName(ici.hwnd); } else { // If the verb is not recognized by the context menu handler, it // must return E_FAIL to allow it to be passed on to the other // context menu handlers that might implement that verb. Marshal.ThrowExceptionForHR(WinError.E_FAIL); } } // If the command cannot be identified through the verb string, then // check the identifier offset. else { // Is the command identifier offset supported by this context menu // extension? if (NativeMethods.LowWord(ici.verb.ToInt32()) == IDM_DISPLAY) { OnVerbDisplayFileName(ici.hwnd); } else { // If the verb is not recognized by the context menu handler, it // must return E_FAIL to allow it to be passed on to the other // context menu handlers that might implement that verb. Marshal.ThrowExceptionForHR(WinError.E_FAIL); } } }
/// <summary> /// 当用户点击相关联的菜单项后则调用该方法. /// </summary> /// <param name="pici"> /// 参数pici是一个指向包含相关必须信息的CMINVOKECOMMANDINFO或CMINVOKECOMMANDINFOEX指针 /// </param> public void InvokeCommand(IntPtr pici) { bool isUnicode = false; //检查什么类型的结构体被传递进函数,CMINVOKECOMMANDINFO还是CMINVOKECOMMANDINFOEX取决于 //lpcmi的成员变量cbSize,虽然lpcmi在 Shlobj.h中指向CMINVOKECOMMANDINFO结构体 //但通常lpcmi指向的是一个CMINVOKECOMMANDINFOEX结构体,CMINVOKECOMMANDINFOEX是CMINVOKECOMMANDINFO的扩展 //可以接受Unicode字符串 CMINVOKECOMMANDINFO ici = (CMINVOKECOMMANDINFO)Marshal.PtrToStructure( pici, typeof(CMINVOKECOMMANDINFO)); CMINVOKECOMMANDINFOEX iciex = new CMINVOKECOMMANDINFOEX(); if (ici.cbSize == Marshal.SizeOf(typeof(CMINVOKECOMMANDINFOEX))) { if ((ici.fMask & CMIC.CMIC_MASK_UNICODE) != 0) { isUnicode = true; iciex = (CMINVOKECOMMANDINFOEX)Marshal.PtrToStructure(pici, typeof(CMINVOKECOMMANDINFOEX)); } } // 检查命令是动态的还是偏移产生的. // 有两种方法来确定: // // 1) 命令是动态的 // 2) 命令是偏移的 // //如果在ANSI的情况下lpcmi->lpVerb或Unicode情况下的lpcmi->lpVerbW为非0,且保存了一个动态的字符串则可以判断其为动态的, //反之则可以确定为偏移的 if (!isUnicode && NativeMethods.HighWord(ici.lpVerb.ToInt32()) != 0) { //上下文菜单是否支持动态的 if (Marshal.PtrToStringAnsi(ici.lpVerb) == this.verb) { OnVerbDisplayFileName(ici.hwnd); } else { // 如果上下文菜单处理程序不能识别该命令, 必须返回E_FAIL,并传递到其他的能识别该命令的上下文菜单项上,并抛出异常 Marshal.ThrowExceptionForHR(WinError.E_FAIL); } } //在Unicode情况下, 不为0, 动态命令保存在 lpcmi->lpVerbW. else if (isUnicode && NativeMethods.HighWord(iciex.lpVerbW.ToInt32()) != 0) { // 该上下文菜单是否支持动态 if (Marshal.PtrToStringUni(iciex.lpVerbW) == this.verb) { OnVerbDisplayFileName(ici.hwnd); } else { // 如果上下文菜单处理程序不能识别该命令, 必须返回E_FAIL,并传递到其他的能识别该命令的上下文菜单项上,并抛出异常 Marshal.ThrowExceptionForHR(WinError.E_FAIL); } } // 如果该命令不能通过动态确定,则可以确定为偏移的 else { //上下文菜单是否支持偏移的 if (NativeMethods.LowWord(ici.lpVerb.ToInt32()) == IDM_DISPLAY) { OnVerbDisplayFileName(ici.hwnd); } else { //如果上下文菜单处理程序不能识别该命令, 必须返回E_FAIL,并传递到其他的能识别该命令的上下文菜单项上. Marshal.ThrowExceptionForHR(WinError.E_FAIL); } } }