Как узнать выбранную папку в IContextMenu.QueryContextMenu
От: S_V_B Беларусь  
Дата: 17.05.10 11:35
Оценка:
Мне нужно кастомизировать контекстное меню explorer-a в зависимости от элемента, который выбран в данный момент.

Если выбран файл или папка (и я по ним кликаю правой кнопкой), я узнаю его(ее) полный путь с помощью функции DragQueryFile.

Как узнать, какая папка выбрана, если я кликаю правой кнопкой в пустом месте explorer-a?

Спасибо
icontextmenu
Re: Как узнать выбранную папку в IContextMenu.QueryContextMe
От: Alexey Frolov Беларусь  
Дата: 17.05.10 13:16
Оценка:
Здравствуйте, S_V_B, Вы писали:

S_V>Мне нужно кастомизировать контекстное меню explorer-a в зависимости от элемента, который выбран в данный момент.


S_V>Если выбран файл или папка (и я по ним кликаю правой кнопкой), я узнаю его(ее) полный путь с помощью функции DragQueryFile.


А если выбраны и файл и папка?

S_V>Как узнать, какая папка выбрана, если я кликаю правой кнопкой в пустом месте explorer-a?


Для того чтобы обрабатывать клик на пустом месте, нужно регистрировать соответствующим образом свою компоненту. Конкретно здесь — Directory\Background\shellex\YourShellExHandler
Re[2]: Как узнать выбранную папку в IContextMenu.QueryContex
От: S_V_B Беларусь  
Дата: 19.05.10 08:35
Оценка:
AF>А если выбраны и файл и папка?

Если выбран и файл, и папка или несколько файлов, то DragQueryFile возвращает весь список выбранных файлов (папок).

S_V>>Как узнать, какая папка выбрана, если я кликаю правой кнопкой в пустом месте explorer-a?


AF>Для того чтобы обрабатывать клик на пустом месте, нужно регистрировать соответствующим образом свою компоненту. Конкретно здесь — Directory\Background\shellex\YourShellExHandler


Да, я так и делаю (регистрирую компоненту в смысле), и правый клик у меня обрабатывается, событие в QueryContextMenu приходит и здесь я могу добавить нужные мне команды, но мне их нужно добавлять в зависимости от выбранного каталога (в левом дереве в эксплоере). А как его узнать, я пока не понял.
В данном сценарии DragQueryFile не возвращает выбранный каталог.
Re[3]: Как узнать выбранную папку в IContextMenu.QueryContex
От: Jolly Roger  
Дата: 19.05.10 10:52
Оценка: 3 (1)
Здравствуйте, S_V_B, Вы писали:

S_V>Да, я так и делаю (регистрирую компоненту в смысле), и правый клик у меня обрабатывается, событие в QueryContextMenu приходит и здесь я могу добавить нужные мне команды, но мне их нужно добавлять в зависимости от выбранного каталога (в левом дереве в эксплоере). А как его узнать, я пока не понял.

S_V>В данном сценарии DragQueryFile не возвращает выбранный каталог.

В метод IShellExtInit::Initialize Вам передаются два параметра: LPCITEMIDLIST pidlFolder и IDataObject *pdtobj, причём один из них равен нулю. Если кликнули по файлу или папке, то нулю равен первый, а если по подложке — второй. В этом случае получить путь к папке можно с помощью SHGetPathFromIDList.
"Нормальные герои всегда идут в обход!"
Re[4]: Как узнать выбранную папку в IContextMenu.QueryContex
От: S_V_B Беларусь  
Дата: 19.05.10 11:24
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, S_V_B, Вы писали:


S_V>>Да, я так и делаю (регистрирую компоненту в смысле), и правый клик у меня обрабатывается, событие в QueryContextMenu приходит и здесь я могу добавить нужные мне команды, но мне их нужно добавлять в зависимости от выбранного каталога (в левом дереве в эксплоере). А как его узнать, я пока не понял.

S_V>>В данном сценарии DragQueryFile не возвращает выбранный каталог.

JR>В метод IShellExtInit::Initialize Вам передаются два параметра: LPCITEMIDLIST pidlFolder и IDataObject *pdtobj, причём один из них равен нулю. Если кликнули по файлу или папке, то нулю равен первый, а если по подложке — второй. В этом случае получить путь к папке можно с помощью SHGetPathFromIDList.


Огромное спасибо! Все получилось.
Re[4]: Как узнать выбранную папку в IContextMenu.QueryContex
От: S_V_B Беларусь  
Дата: 04.06.10 07:51
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, S_V_B, Вы писали:


S_V>>Да, я так и делаю (регистрирую компоненту в смысле), и правый клик у меня обрабатывается, событие в QueryContextMenu приходит и здесь я могу добавить нужные мне команды, но мне их нужно добавлять в зависимости от выбранного каталога (в левом дереве в эксплоере). А как его узнать, я пока не понял.

S_V>>В данном сценарии DragQueryFile не возвращает выбранный каталог.

JR>В метод IShellExtInit::Initialize Вам передаются два параметра: LPCITEMIDLIST pidlFolder и IDataObject *pdtobj, причём один из них равен нулю. Если кликнули по файлу или папке, то нулю равен первый, а если по подложке — второй. В этом случае получить путь к папке можно с помощью SHGetPathFromIDList.


Столкнулся с еще одной проблемой:
Если я кликаю по файлу или папке, то путь я пытаюсь получить следующим образом:

            uint nselected = Helpers.DragQueryFile(m_hDrop, 0xffffffff, null, 0);
            if (nselected > 0)
            {
                Helpers.DragQueryFile(m_hDrop, 0, sb, sb.Capacity + 1);
                curPath = sb.ToString();
            }


На vista работает, а на windows 7 x64 почему-то nselected = 0 и я никак не могу получить путь

Спасибо
dragqueryfile windows 7
Re[5]: Как узнать выбранную папку в IContextMenu.QueryContex
От: Jolly Roger  
Дата: 04.06.10 15:17
Оценка:
Здравствуйте, S_V_B, Вы писали:

S_V>На vista работает, а на windows 7 x64 почему-то nselected = 0


"Нормальные герои всегда идут в обход!"
Re[6]: Как узнать выбранную папку в IContextMenu.QueryContex
От: S_V_B Беларусь  
Дата: 09.06.10 10:44
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, S_V_B, Вы писали:


S_V>>На vista работает, а на windows 7 x64 почему-то nselected = 0


JR>


А вообще DragQueryFile работает на x64?
Я вызываю ее из managed кода на .net, может быть в этом причина, возможно я как-то не правильно определил ее?

Я определяю так:

        [DllImport("shell32")]
        internal static extern uint DragQueryFile(uint hDrop,uint iFile, StringBuilder buffer, int cch);


Возможно есть другой путь получения пути к выбранному элементу в контекстном меню?
Re[7]: Как узнать выбранную папку в IContextMenu.QueryContex
От: Jolly Roger  
Дата: 09.06.10 11:48
Оценка:
Здравствуйте, S_V_B, Вы писали:

S_V>
S_V>        [DllImport("shell32")]
S_V>        internal static extern uint DragQueryFile(uint hDrop,uint iFile, StringBuilder buffer, int cch);
S_V>


Попробуйте тип hDrop поменять на IntPtr.
"Нормальные герои всегда идут в обход!"
Re[8]: Как узнать выбранную папку в IContextMenu.QueryContex
От: S_V_B Беларусь  
Дата: 14.06.10 07:15
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, S_V_B, Вы писали:


S_V>>
S_V>>        [DllImport("shell32")]
S_V>>        internal static extern uint DragQueryFile(uint hDrop,uint iFile, StringBuilder buffer, int cch);
S_V>>


JR>Попробуйте тип hDrop поменять на IntPtr.


Попробовал, к сожалению, не помогло.
На x86 продолжает работать, а на x64 — нет
Re[9]: Как узнать выбранную папку в IContextMenu.QueryContex
От: SaliamiSan  
Дата: 07.09.10 07:23
Оценка:
Здравствуйте, S_V_B, Вы писали:

S_V>Здравствуйте, Jolly Roger, Вы писали:


JR>>Здравствуйте, S_V_B, Вы писали:


S_V>>>
S_V>>>        [DllImport("shell32")]
S_V>>>        internal static extern uint DragQueryFile(uint hDrop,uint iFile, StringBuilder buffer, int cch);
S_V>>>


JR>>Попробуйте тип hDrop поменять на IntPtr.


S_V>Попробовал, к сожалению, не помогло.

S_V>На x86 продолжает работать, а на x64 — нет :(

На х64 в DragQueryFile может передаваться пустой hDrop. Причина в том, что hDrop неправильно получается. А получается он неправльно из-за неверно определённых структур для x64. В System.Runtime.InteropServices.ComTypes есть нужные структуры для получения hDrop.

int    IShellExtInit.Initialize (IntPtr pidlFolder, IntPtr lpdobj, uint hKeyProgID)
        {
            try
            {
                m_dataObject = null;
                if (lpdobj != (IntPtr)0)
                {
                    m_dataObject = (System.Runtime.InteropServices.ComTypes.IDataObject)Marshal.GetObjectForIUnknown(lpdobj);
                    System.Runtime.InteropServices.ComTypes.FORMATETC format = new System.Runtime.InteropServices.ComTypes.FORMATETC();
                    format.tymed = System.Runtime.InteropServices.ComTypes.TYMED.TYMED_HGLOBAL;
                    format.lindex = -1;
                    format.ptd = (IntPtr)0;
                    format.dwAspect = System.Runtime.InteropServices.ComTypes.DVASPECT.DVASPECT_CONTENT;
                    format.cfFormat = 15;
                    System.Runtime.InteropServices.ComTypes.STGMEDIUM med = new System.Runtime.InteropServices.ComTypes.STGMEDIUM();

                    m_dataObject.GetData(ref format, out med);
                    m_hDrop = (uint)med.unionmember;
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            return 0;
        }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.