/// <summary>
        /// Invokes the Delete command on the shell item.
        /// </summary>
        public void InvokeDelete()
        {
            CMINVOKECOMMANDINFO invoke = new CMINVOKECOMMANDINFO();

            invoke.cbSize = Marshal.SizeOf(invoke);
            invoke.lpVerb = "delete";

            try
            {
                m_ComInterface.InvokeCommand(ref invoke);
            }
            catch (COMException e)
            {
                // Ignore the exception raised when the user cancels
                // a delete operation.
                if (e.ErrorCode != unchecked ((int)0x800704C7))
                {
                    throw;
                }
            }
        }
 /// <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
         };
     }
 }
    /// <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) == 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) == 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);
            }
        }
    }
Exemple #4
0
        /// <summary>
        /// Displays shell shortcut menu.
        /// </summary>
        /// <param name="idlw">IDLWrapper object that specifies shell item</param>
        /// <param name="pntShow">location of the shortcut menu, in screen coordinates.</param>
        /// <param name="hwndParent">Handle of parent control. Parent control will get focus, and receives the messages about drawing 'Send to' submenues.</param>
        /// <param name="fCanRemove">set true to add 'remove this' menu item.</param>
        /// <returns>
        /// 0xFFFF	user selected "Remove this item from menu".
        /// 0xFFFE	user selected "Open containing folder".
        /// 0xFFFD	If the user cancels the menu without making a selection, or if an error occurs
        /// </returns>
        public int Open(IDLWrapper idlw, Point pntShow, IntPtr hwndParent, bool fCanRemove)
        {
            const uint   MF_STRING         = 0x00000000;
            const uint   MF_SEPARATOR      = 0x00000800;
            const uint   CMF_NORMAL        = 0x00000000;
            const uint   CMF_EXTENDEDVERBS = 0x00000100;
            const uint   TPM_RETURNCMD     = 0x0100;
            const uint   S_OK = 0;
            const int    COMMANDID_REMOVEITEM = 0xffff; // todo: move to const class
            const int    COMMANDID_OPENPARENT = 0xfffe;
            const int    COMMANDID_USERCANCEL = 0xfffd;
            IShellFolder shellFolderParent    = null;

            try {
                // get IShellFolder
                IntPtr pIDLRelative;
                if (idlw.Available && S_OK == PInvoke.SHBindToParent(idlw.PIDL, ExplorerGUIDs.IID_IShellFolder, out shellFolderParent, out pIDLRelative) && shellFolderParent != null)
                {
                    // get IContextMenu2
                    IntPtr[] pIDLs    = new IntPtr[] { pIDLRelative };
                    uint     reserved = 0;
                    object   oUnk;

                    if (S_OK == shellFolderParent.GetUIObjectOf(IntPtr.Zero, (uint)pIDLs.Length, pIDLs, ExplorerGUIDs.IID_IContextMenu, ref reserved, out oUnk))
                    {
                        pIContextMenu2 = oUnk as IContextMenu2;
                        if (pIContextMenu2 != null)
                        {
                            using (ContextMenu contextMenu = new ContextMenu()) {
                                int  nResult = -1;
                                uint uFlags  = CMF_NORMAL;
                                if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
                                {
                                    uFlags |= CMF_EXTENDEDVERBS;
                                }

                                pIContextMenu2.QueryContextMenu(contextMenu.Handle, 0, 1, 0xffff, uFlags);

                                // append optional menus
                                if (fCanRemove)
                                {
                                    // "Remove this item from menu"
                                    PInvoke.AppendMenu(contextMenu.Handle, MF_SEPARATOR, IntPtr.Zero, null);
                                    PInvoke.AppendMenu(contextMenu.Handle, MF_STRING, new IntPtr(COMMANDID_REMOVEITEM), QTUtility.ResMain[25]);
                                }
                                if (idlw.HasPath && idlw.Path.Length > 3 && idlw.IsFileSystem /*&& ( idlw.IsFileSystemFolder || idlw.IsFileSystemFile )*/)
                                {
                                    // "Open containing folder"
                                    if (!fCanRemove)
                                    {
                                        // separator
                                        PInvoke.AppendMenu(contextMenu.Handle, MF_SEPARATOR, IntPtr.Zero, null);
                                    }
                                    PInvoke.AppendMenu(contextMenu.Handle, MF_STRING, new IntPtr(COMMANDID_OPENPARENT), QTUtility.ResMain[26]);
                                }

                                uint commandID = PInvoke.TrackPopupMenu(contextMenu.Handle, TPM_RETURNCMD, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero);
                                if (commandID != 0)
                                {
                                    if (commandID == COMMANDID_REMOVEITEM)
                                    {
                                        return(COMMANDID_REMOVEITEM);
                                    }
                                    else if (commandID == COMMANDID_OPENPARENT)
                                    {
                                        if (idlw.HasPath)
                                        {
                                            try {
                                                QTTabBarClass tabbar = InstanceManager.GetThreadTabBar();
                                                if (tabbar != null)
                                                {
                                                    using (IDLWrapper idlwParent = idlw.GetParent()) {
                                                        if (idlwParent.Available)
                                                        {
                                                            tabbar.OpenNewTabOrWindow(idlwParent);
                                                        }
                                                    }
                                                }
                                                // DesktopTool will handle it by itself
                                                nResult = COMMANDID_OPENPARENT;
                                            }
                                            catch {
                                                System.Media.SystemSounds.Asterisk.Play();
                                            }
                                        }
                                    }
                                    else
                                    {
                                        CMINVOKECOMMANDINFO cmInfo = new CMINVOKECOMMANDINFO {
                                            cbSize       = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFO)),
                                            fMask        = 0,
                                            hwnd         = hwndParent,
                                            lpVerb       = (IntPtr)((commandID - 1) & 0xFFFF),
                                            lpParameters = IntPtr.Zero,
                                            lpDirectory  = IntPtr.Zero,
                                            nShow        = 1, //SW_SHOWNORMAL;
                                            dwHotKey     = 0,
                                            hIcon        = IntPtr.Zero
                                        };

                                        // returns S_OK if successful, or an error value otherwise.
                                        // E_ABORT when user clicked "Open folder link target exists" of link file...( E_ABORT  _HRESULT_TYPEDEF_(0x80004004L) )
                                        nResult = pIContextMenu2.InvokeCommand(ref cmInfo);
                                    }
                                }
                                else
                                {
                                    // 'if the user cancels the menu without making a selection, or if an error occurs' (MSDN)
                                    nResult = COMMANDID_USERCANCEL;
                                }

                                return(nResult);
                            }
                        }
                    }
                }

                // if failed to create shell context menu, show 'remove this' menu instead
                if (fCanRemove)
                {
                    using (ContextMenu contextMenu = new ContextMenu()) {
                        PInvoke.AppendMenu(contextMenu.Handle, MF_STRING, new IntPtr(COMMANDID_REMOVEITEM), QTUtility.ResMain[25]);

                        if (COMMANDID_REMOVEITEM == PInvoke.TrackPopupMenu(contextMenu.Handle, TPM_RETURNCMD, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero))
                        {
                            return(COMMANDID_REMOVEITEM);
                        }
                    }
                }

                return(COMMANDID_USERCANCEL);
            }
            catch {
            }
            finally {
                if (shellFolderParent != null)
                {
                    Marshal.ReleaseComObject(shellFolderParent);
                }

                if (pIContextMenu2 != null)
                {
                    Marshal.ReleaseComObject(pIContextMenu2);
                    pIContextMenu2 = null;
                }
            }
            return(-1);
        }
Exemple #5
0
        /// <summary>
        /// Displays shell shortcut menu for multiple items. Paths must be sub items of one directory.
        /// </summary>
        /// <param name="lstIDLs"></param>
        /// <param name="pntShow"></param>
        /// <param name="hwndParent"></param>
        /// <returns></returns>
        public int Open(List <byte[]> lstIDLs, Point pntShow, IntPtr hwndParent)
        {
            // All lstIDLs members must share the same parent, for compatibility.
            const uint S_OK = 0;

            if (lstIDLs == null || lstIDLs.Count == 0)
            {
                return(-1);
            }

            IShellFolder  shellFolder  = null;
            List <IntPtr> lstRltvPIDLs = new List <IntPtr>();
            IntPtr        pIDLFirst    = IntPtr.Zero;

            try {
                // build array of relative idls
                for (int i = 0; i < lstIDLs.Count; i++)
                {
                    if (i == 0)
                    {
                        pIDLFirst = ShellMethods.CreateIDL(lstIDLs[0]);
                    }

                    using (IDLWrapper idlw = new IDLWrapper(lstIDLs[i])) {
                        if (!idlw.Available)
                        {
                            continue;
                        }
                        IntPtr p = PInvoke.ILClone(PInvoke.ILFindLastID(idlw.PIDL));
                        if (p != IntPtr.Zero)
                        {
                            lstRltvPIDLs.Add(p);
                        }
                    }
                }
                IntPtr[] apidl = lstRltvPIDLs.ToArray();

                if (apidl.Length > 0)
                {
                    IntPtr pIDLRltv1st;
                    if (S_OK == PInvoke.SHBindToParent(pIDLFirst, ExplorerGUIDs.IID_IShellFolder, out shellFolder, out pIDLRltv1st))
                    {
                        // get IContextMenu2
                        uint   rsv = 0;
                        object oUnk;

                        if (S_OK == shellFolder.GetUIObjectOf(IntPtr.Zero, (uint)apidl.Length, apidl, ExplorerGUIDs.IID_IContextMenu, ref rsv, out oUnk))
                        {
                            pIContextMenu2 = oUnk as IContextMenu2;
                            if (pIContextMenu2 != null)
                            {
                                using (ContextMenu contextMenu = new ContextMenu()) {
                                    const uint CMF_EXTENDEDVERBS = 0x00000100;
                                    const uint TPM_RETURNCMD     = 0x0100;

                                    uint uFlags = 0;
                                    if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
                                    {
                                        uFlags |= CMF_EXTENDEDVERBS;
                                    }

                                    pIContextMenu2.QueryContextMenu(contextMenu.Handle, 0, 1, 0xffff, uFlags);

                                    uint commandID = PInvoke.TrackPopupMenu(contextMenu.Handle, TPM_RETURNCMD, pntShow.X, pntShow.Y, 0, hwndParent, IntPtr.Zero);
                                    if (commandID != 0)
                                    {
                                        CMINVOKECOMMANDINFO cmInfo = new CMINVOKECOMMANDINFO {
                                            cbSize       = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFO)),
                                            fMask        = 0,
                                            hwnd         = hwndParent,
                                            lpVerb       = (IntPtr)((commandID - 1) & 0xFFFF),
                                            lpParameters = IntPtr.Zero,
                                            lpDirectory  = IntPtr.Zero,
                                            nShow        = 1, //SW_SHOWNORMAL
                                            dwHotKey     = 0,
                                            hIcon        = IntPtr.Zero
                                        };

                                        // this returns E_ABORT when user clicked "Open folder link target exists" of link file...
                                        pIContextMenu2.InvokeCommand(ref cmInfo);
                                        return(0);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch {
            }
            finally {
                if (shellFolder != null)
                {
                    Marshal.ReleaseComObject(shellFolder);
                }
                if (pIDLFirst != IntPtr.Zero)
                {
                    PInvoke.CoTaskMemFree(pIDLFirst);
                }
                foreach (IntPtr pIDL in lstRltvPIDLs.Where(pIDL => pIDL != IntPtr.Zero))
                {
                    PInvoke.CoTaskMemFree(pIDL);
                }
                if (pIContextMenu2 != null)
                {
                    Marshal.ReleaseComObject(pIContextMenu2);
                    pIContextMenu2 = null;
                }
            }
            return(-1);
        }
Exemple #6
0
        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));

            #region unicode
            //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));
            //    }
            //}
            #endregion
            // Is the command identifier offset supported by this context menu
            // extension?
            int id = NativeMethods.LowWord(ici.verb.ToInt32());

            if (id == MenuConnectWIFI_ID)
            {
                string s          = "";
                string lastipfile = Path.GetTempPath() + "lastip.txt";
                if (File.Exists(lastipfile))
                {
                    FileStream   fs = new FileStream(lastipfile, FileMode.Open);
                    StreamReader sr = new StreamReader(fs);
                    s = sr.ReadLine();
                    sr.Close();
                    fs.Close();
                }
                s = Microsoft.VisualBasic.Interaction.InputBox(Properties.Resources.prompt_ConnectViaWIFI,
                                                               Properties.Resources.menu_ConnectViaWIFI,
                                                               s);
                if (!String.IsNullOrEmpty(s))
                {
                    if (NativeMethods.isIPAddress(s))
                    {
                        File.Delete(lastipfile);
                        FileStream   fs = new FileStream(lastipfile, FileMode.CreateNew);
                        StreamWriter sw = new StreamWriter(fs);
                        sw.WriteLine(s);
                        sw.Close();
                        fs.Close();

                        (new AndroidToolAdb()).Connect(s);
                    }
                    else
                    {
                        System.Windows.Forms.MessageBox.Show(Properties.Resources.prompt_NotAnIP);
                    }
                }
            }
            else
            {
                for (int i = 0; i < devices.Count; i++)
                {
                    AndroidDevice  d   = (AndroidDevice)devices[i];
                    AndroidToolAdb adb = new AndroidToolAdb();
                    if (MenuInstall2Memory_ID[i] == id)
                    {
                        adb.install(d.Serialno, sFileName);
                    }
                    else if (MenuInstall2SD_ID[i] == id)
                    {
                        adb.install(d.Serialno, sFileName, true);
                    }
                    else if (MenuUninstall_ID[i] == id)
                    {
                        if (curApk == null)
                        {
                            curApk = AndroidPackage2.GetAndroidPackage(sFileName);
                        }
                        adb.uninstall(d.Serialno, curApk.PackageName);
                    }
                    else if (MenuDisconnect_ID[i] == id)
                    {
                        adb.Disconnect(d.Serialno);
                    }
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Called to invoke the comamand.
        /// </summary>
        /// <param name="pici">The command info pointer.</param>
        int IContextMenu.InvokeCommand(IntPtr pici) // ref CMINVOKECOMMANDINFO pici)
        {
            //  We could have been provided with a CMINVOKECOMMANDINFO or a
            //  CMINVOKECOMMANDINFOEX - cast to the small and then check the size.
            CMINVOKECOMMANDINFO ici = default(CMINVOKECOMMANDINFO);

            try
            {
                if (pici != IntPtr.Zero)
                {
                    ici = (CMINVOKECOMMANDINFO)Marshal.PtrToStructure((IntPtr)pici, typeof(CMINVOKECOMMANDINFO));
                }
            }
            catch { pici = IntPtr.Zero; }
            if (pici == IntPtr.Zero)
            {
                return(WinError.E_NOTIMPL);
            }
            var iciex = new CMINVOKECOMMANDINFOEX();

            //  We'll work out whether the commandis unicode or not...
            var isUnicode = false;

            //  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((IntPtr)pici,
                                                                              typeof(CMINVOKECOMMANDINFOEX));
                }
            }

            //  The derived class MAY need some of the extended command data,
            //  so we store it now. It can be retrieved and used in the handler
            //  of the menu item.
            SaveInvokeCommandInfo(isUnicode, ici, iciex);

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