Як управляти IContextMenu, частина 1 - вступне слово
IContextMenu використовується наступним чином:- Створення.
- IContextMenu.QueryContextMenu. Це инициализирует контекстне меню. Під час цього виклику, контекстне меню вирішує, які елементи потрібно відображати, грунтуючись на переданих вами прапорах.
- Показати меню або вибрати його команду іншим способом, використовуючи IContextMenu.GetCommandString. IContextMenu2.HandleMenuMsg і IContextMenu3.HandleMenuMsg 2 для емуляції взаємодії користувача.
- IContextMenu.InvokeCommand. Цей виклик виконує команду.
Оболонка спочатку викликає IContextMenu.QueryContextMenu. Вона передає дескриптор HMENU, який метод може використовувати для додавання елементів в контекстне меню. Якщо користувач вибирає одну з команд, викликається IContextMenu.GetCommandString для отримання рядка-підказки, яка буде показана в статусному рядку Microsoft Windows Explorer. Якщо користувач клацає по одному з пунктів меню, оболонка викликає IContextMenu.InvokeCommand. Тоді обробник може виконати дії команди. Прочитайте це з іншого боку і ви побачите, що вам потрібно зробити, щоб самому використовувати (host) IContextMenu:
Керуючий IContextMenu спочатку викликає IContextMenu.QueryContextMenu. Він передає дескриптор HMENU, який метод може використовувати для додавання елементів в контекстне меню. Якщо користувач вибирає одну з команд, викликається IContextMenu.GetCommandString для отримання рядка-підказки, яка буде показана в рядку статусу викликає. Якщо користувач клацає по одному з пунктів меню, керуючий IContextMenu викликає IContextMenu.InvokeCommand. Тоді обробник може виконати дії команди. Вивчення наслідків цієї нової інтерпретації документації контекстного меню буде нашою увагою протягом наступних кількох тижнів.
Окей, давайте почнемо. Почнемо, як завжди, з пустого VCL-додатки. Я буду припускати, що ви вже знайомі з простором імен оболонки (shell namespace) і pidl, так що я сфокусується на проблемі контекстного меню.
Ця проста функція бере шлях і отримує UI-об'єкт оболонки (shell) для нього. Ми конвертуємо шлях в PIDL за допомогою SHParseDisplayName. потім прив'язуємося (bind) до батькові чи матері PIDL за допомогою SHBindToParent. після чого запитуємо у батька UI-об'єкт за допомогою IShellFolder.GetUIObjectOf. Я припускаю, що у вас достатньо досвіду роботи з простором імен, щоб цей код не викликав проблем.
(Допоміжні функції типу SHParseDisplayName і SHBindToParent не роблять нічого, чого б ви не змогли зробити самі. Вони просто економлять вам час на друк коду. Коли ви почнете використовувати простір імен оболонки постійно, ви зберете власну бібліотеку невеликих допоміжних функцій, типу цих).
Для нашого першого разу, все, що ми зробимо - просто викличемо дію (verb) "Play" на файлі, коли користувач клацне правою кнопкою (чому правої? Тому що в наступній версії ми покажемо контекстне меню).
Як зазначено в списку вище, спочатку ми створюємо IContextMenu, потім инициализируем його викликом IContextMenu.QueryContextMenu. Зауважте, що навіть хоча ми не збираємося показувати контекстне меню, нам все ще потрібно створити popup-меню, тому що цього вимагає IContextMenu.QueryContextMenu. Однак, ми взагалі не будемо показувати вийшло меню; замість того, щоб просити користувача зробити вибір з меню, ми самі робимо його за користувача, вибираючи дію "Play", заповнюючи запис TCMInvokeCommandInfo і викликаючи його.
Але як ми дізнаємося, що дія (verb) буде саме "Play"? У нашому випадку ми це знаємо тому що ми жорстко зашили в код шлях до файлу "clock.avi" і знаємо, що AVI файли мають дію "Play". Але, звичайно ж, це не спрацює в загальному випадку (прим. Пер. Якщо ви запускаєте приклад, то переконаєтеся, що у вас є цей файл або введіть туди будь-яке інше ім'я і подивіться, які дії є для цього типу файлів. Крім того, навіть для AVI-файлів дії можуть бути змінені, якщо якийсь програвач міняв асоціації). Перш ніж викликати дію за замовчуванням (default verb), давайте спочатку зробимо щаг простіше і попросимо користувача вибрати дію для виклику. Взагалі-то цю вправу відверне від нашого шляху, але в кінці-кінців ми повернемося до вибору дії за замовчуванням.
Якщо код вище - це все, що вам було потрібно (викликати фіксоване дію для файлу), то тоді вам не потрібно проходити через інші дії для контекстного меню. Код вище відповідає виклику функції ShellExecuteEx. передаючи їй прапор SEE_MASK_INVOKEIDLIST для вказівки того, що ви хочете, щоб виклик (invoke) йшов через IContextMenu.