Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Delphi: WinAPI и системное программирование > Контекстное меню файлового браузера |
Автор: Keeper89 26.2.2009, 16:28 |
Доброго времени суток! Делаю файловый браузер на основе ListView и присоединяю свое pop-up меню. Вопрос в следующем: каким образом можно добавить в свое меню часть контекстного меню проводника Windows с сохранением функциональности? Желательно небольшой примерчик, а не просто совет "куда копать". Заранее спасибо. |
Автор: Rrader 26.2.2009, 19:43 | ||
Можно получать меню итема через IContextMenu, затем обрезать его, как надо. И все это делать только тогда, когда требуется, так наиболее удобно, т.е. не хранить меню ![]() Накидал пример - выбираем через OpenDialog файл, для него вызывается меню, у которого оставлены 5 последних итемов (включая separator). Исполнение кода главного потока приостанавливается до тех пор, пока чего-нибудь не нажмём.
|
Автор: Keeper89 26.2.2009, 22:04 |
Спасибо за пример! И еще несколько вопросов: 1) как заставить работать код для виртуальных папок (Например Рабочего Стола или Моего Компьютера)? 2) меню Отправить и Открыть с помощью отображаются, но вместо вложенного меню оказывается та же надпись, для WinRAR же например все нормально... 3) можно ли каким то образом добавить полученное меню к своему pop-up? |
Автор: Keeper89 28.2.2009, 15:18 | ||||
Спасибо, работает отлично.
Пользуюсь следующей функцией для определения ItemID:
Но при этом меню работает только для папок, к которым можно определить путь (например Рабочий стол), а Мой Компьютер и Рабочий стол как виртуальная папка не работают. ---------- + еще вопрос: в таком компоненте как ShellListView уже реализовано меню, которое мне необходимо. Можно ли как то его "выдернуть" и добавить из него элементы в своему меню? |
Автор: Rrader 1.3.2009, 08:42 | ||||||
Путь не нужен, нужен ItemID:
И далее работать нужно с ним через GetUIObjectOf.
ShellListView использует примерно такой же код, какой привел я. Меню нигде не хранится и не является дельфийским TPopupMenu. |
Автор: Keeper89 1.3.2009, 17:32 | ||
Немного подкорректировал ваш код под себя следующим образом, где путь я передаю как параметр:
Никак не могу разобраться, где здесь можно использовать GetUIObjectOf и передавать ItemID? --- Как можно однозначно идентифицировать виртуальную папку для раскрытия меню? Например, если определять через путь, то Мои Документы будут иметь путь, а Мой Компьютер нет. По названию непонятно, ведь обычная папка тоже может называться Рабочий Стол и т.д.... |
Автор: Rrader 2.3.2009, 06:33 | ||
Keeper89, давайте обговорим несколько вещей... Shell для работы с файловой системой и объектами использует свой особый подход. В них вместо файловых путей используются ItemIDs. Подробности http://msdn.microsoft.com/en-us/library/bb776813(VS.85).aspx Еще прочитайте http://www.geocities.com/SiliconValley/4942/itemids.html Затем откройте файл ShellCtrls.pas и посмотрите, как там все реализовано (файл лежит в папке Demos\...\ShellCtrls\ )
Позле ознакомления с предыдущим материалом таких вопросов уже не должно возникнуть. |
Автор: Keeper89 2.3.2009, 15:26 | ||
Спасибо, разобрался. Как можно еще сделать 2 вещи:
|
Автор: Rrader 4.3.2009, 15:50 | ||||||
Можно использовать Menu API. Но учтите, чтобы это работало при разных локализациях, т.е. используйте метод на свой страх и риск. ![]()
Использование:
Ну если это настолько необходимо, то вручную, через Menu API. Но я бы делал наоборот - вносил все изменения только в оригинал (Menu в примере). Это сильно упрощает хэндлинг, как выше уже говорил. |
Автор: Keeper89 4.3.2009, 21:46 | ||||||
А как можно удалить элемент (с подменю если оно есть)? Возможно стоит воспользоваться функцией
с параметром MF_DELETE = $200, определив заранее вашим способом нужный индекс элемента?
Как можно реализовать то что вы советуете, если у меня имеются:
|
Автор: Rrader 5.3.2009, 08:10 | ||||
Для простоты используйте DeleteMenu:
Для этого есть AppendMenu, InsertMenuItem. При щелчке на итеме главному окну-владельцу посылается сообщение WM_COMMAND. |
Автор: Keeper89 5.3.2009, 12:48 | ||
Прощу прощения. все-таки необходимо вставлять HMENU в свое меню. Дело в том, я использую специальный компонент ToolBar2000, где всплывающее меню имеет дополнительные характеристики по сравнению с дельфийским TPopupMenu. Как постараться реализовать это? |
Автор: Keeper89 11.3.2009, 15:30 |
Так все-таки как постараться это сделать? |
Автор: Rrader 11.3.2009, 16:50 | ||
Сорри, забыл про темку ![]() Что делать - нужно создать процедуру конвертации меню через API, создавать ImageList для меню TB2000, в него динамически добавлять Bitmap'ы из меню Menu (через TBitmap). Меню на основе TB2000 проще создавать и удалять вместе с Menu из примера. Подменю - тут посложнее, так как пока показано основное меню, HandleMenuMsg может вызываться многократно (каждый раз при открытии), что затрудняет преобразование. Попробуйте написать функцию, а там дальше, если что неясно станет, помогу ![]() Пример простейшей конвертации
|
Автор: Keeper89 4.11.2009, 01:56 | ||
Возобновляю тему ![]() Сделал копирование контекстного меню в TBPopupMenu:
В принципе выглядит вполне кошерно (слева стандартное, справа мое): ![]() Не получаются некоторые вещи: 0) Получать "эксплорерное" меню при щелчке по пустому месту в ShellListView; 1) Добавлять иконки контекстного меню к себе (закомментированные строчки); 2) Отобрать вложенные меню (IContextMenu2 и IContextMenu3) "Отправить" или "Открыть с помощью", хотя в системном меню как положено обрабатываются в WndProc; 3) Выполнять команды в своем меню (эмулировать нажатие системного КМ). Что из этого реально (возможно) сделать и как подступиться? ![]() |
Автор: bems 4.11.2009, 22:02 |
прочтитай цикл, начинающийся http://transl-gunsmoker.blogspot.com/2009/07/icontextmenu-1.html |
Автор: Keeper89 5.11.2009, 00:46 |
bems, давно прочтен ![]() |
Автор: Rrader 5.11.2009, 18:08 |
Keeper89, выложи тестовый пример с TB, облегчи жизнь желающим помочь ![]() |
Автор: CodeMonkey 5.11.2009, 18:33 |
WndProc вообще вызывается? И с нужными сообщениями? И интерфейсы не nil? Не понял, зачем там CreatePopupMenu с FillMyMenu. Как-то мешанина: два меню и оба попапаются. Чё-то куда-то зачем-то копируется... |
Автор: Keeper89 5.11.2009, 18:59 | ||
Rrader, прикрепил проект вместе с EXE. ToolBar2000 http://www.jrsoftware.org/tb2kdl.php. На счет этого сомневаюсь ![]()
Я только инициализирую системное меню и беру из него данные, поэтому TrackPopupMenuEx закомментирована. |
Автор: Keeper89 10.11.2009, 13:40 |
Есть идеи? ![]() |
Автор: CodeMonkey 11.11.2009, 19:59 |
...мне лениво... |