![]() |
[СТАТЬЯ] Создание расширения для Windows Explorer при помощи C++ Builder
[ИНТРО]
Привет всем. Сегодня я расскажу вам об программном расширении оболочки Форточек при помощи C++ Builder’а. Сразу говорю, что это моя первая статья. Так что не обессудьте если что-то не совсем правильно будет написано. А теперь немного истории. Решил я написать данную статью, так как сам просидел очень долгое время, собирая по кусочкам информацию, разбросанную по всем уголкам интернета. Может быть и сильно громко сказано, но это в действительности так и было. Итак, начнем-с, пожалуй… [ЧТО НАМ ПОНАДОБИТСЯ] Ну во-первых конечно же сама установленная среда C++ Builder. Во-вторых, прямые (желательно длинные) руки и здравомыслящая голова :). А, в третьих, упорство и терпение. Вот пожалуй и весь набор начинающего программера… [ЧЕГО МЫ ХОТИМ ДОБИТЬСЯ] Именно в данной статье мы рассмотрим простой пример создания расширения для Эксплорера, дополняющий некоторые возможности к контекстному меню, появляющегося при клике на определенный файл, как это показано на рисунке: http://savepic.ru/545203.jpg [ПОДГОТОВКА] Итак, запускаем С++ Builder. В-принципе не играет особой роли какой он версии (только будет некоторые различия в интерфейсе). Но я использую Codegear C++ Builder 2007. http://savepic.ru/524723m.jpg Нажимаем File->New->Other->ActiveX->ActiveX Library. Мы увидим уже стандартный уже написанный за нас код, являющийся основой для любого ActiveX-контрола. Теперь снова заходим File->New->Other->ActiveX. Сейчас здесь уже появились дополнительные пункты. Но нам из них нужен только Com Object. Выбираем его из списка и видим следующее диалоговое окно: http://savepic.ru/584114.jpg Вводим в качестве CoClassName MyFirstContextMenu. Вы конечно можете другое имя, но, чтобы не было каких-либо дальнейших вопросов по написанию кода, рекомендую написать там все же именно это. Теперь сохраняем проект в любую папку и идем дальше. [Main.h (по другому не назовешь :) )] http://savepic.ru/588210.jpg Немного оглянувшись по файлам проекта, заходим Main.h и в самый нижний паблик добавляем следующий код: Код:
public:Initialize – инициализирует наше расширение. Из нее мы можем прочитать такие параметры имя файла, дополнительные флаги, переданные нам для дальнейшего их использования нами. QueryContextMenu – возвращает проводнику наши созданные пункты меню. InvokeCommand – задает команду для каждого пункта меню. GetCommandString – возвращает провднику строку-подсказку, которая затем появляется в строке состояния при наведении курсора на какой-либо пункт меню. Теперь поднимемся немного выше и под строчкой COM_INTERFACE_ENTRY(IMyFirstContextMenu) пишем: Код:
COM_INTERFACE_ENTRY(IShellExtInit)Код:
class ATL_NO_VTABLE TMyFirstContextMenuImpl :Эти строчки сообщают проводнику, что «эта DLL есть не что иное, как расширение контекстного меню». Также необходимо заиклудить shlobj.h: #include <shlobj.h> Во избежание лишних проблем и ошибок типа Multiple Declaration заходим в Project->Options и добавляем в Conditional Defines дефайн NO_WIN32_LEAN_AND_MEAN. http://savepic.ru/580018m.jpg Ну с Main.h мы вроде как закончили пока что. Теперь переходим к редактированию не менее важного файла Main.cpp ^)… [Main.cpp] Ну как обычно не забываем сохранять проект… А то… мало ли что?... ? Открываем Main.cpp и сначала инклудим файлы: Код:
#include "stdio.h"Теперь нужно прописать метод initialize. Начнем мы именно с нее, так как эта функция является первой, на которую ссылается эксплорер при загрузке DLL. Код:
UINT uNumFiles=0; // количество переданных файловКод:
…С инициализацией закончили. Теперь перейдем к построению нашего меню. Но для начала рассмотрим формат функции InsertMenu. Вот как она объявлена в winuser.h: Код:
InsertMenuW(Ну этого хватит для общего ознакомления с данной функцией. Если же есть желание «поизучать» и узнать более конкретные вещи о ней , то тебе прямая дорога на мсдн: [URL]. Теперь напишем долгожданную функцию QueryContextMenu. Код:
HRESULT _stdcall TMyFirstContextMenuImpl::QueryContextMenu(HMENU Menu,UINT IndexMenu,UINT IDCmdFirst,UINT idCmdLast,UINT uFlags)Теперь напишем функции InvokeCommand и GetCommandString. Код:
HResult _stdcall TMyFirstContextMenuImpl::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)С GetCommandString все еще проще. Только здесь необходимо переводить строчку в уникод-формат. Вот где нам и пригодился atlconv.h. Код:
HRESULT _stdcall TMyFirstContextMenuImpl::GetCommandString (UINT idCmd,UINT uFlags,UINT* pwReserved,LPSTR pszName,UINT cchMax )[ПОДГОТОВКА К РЕГИСТРАЦИИ РАСШИРЕНИЯ В СИСТЕМЕ] Прежде чем регистрировать наше расширение мы должны прописать определенный тип файла, соответствующий для него. Откроем для ознакомления реестр форточек. Если ты уже знаешь, как регистрируются такие расширения, то можешь спокойно пропустить этот абзац. Итак, открываем реестр: Пуск->Выполнить->regedit. Заходим в HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers http://savepic.ru/577970.jpghttp://savepic.ru/572850.jpg Что мы здесь видим? А видим мы здесь все расширения, зарегистрированные для данного типа файла (* - говорит о том, что расширение нужно зарегистрировать для всех типов файлов). Таким образом, регистрируются расширения для антивирей (куда не нажмешь везде Сканировать файл и т.п.), архиваторов, асек и т.д. Теперь, если поискать (Правка->Поиск если кто в танке) данную ссылку в реестре, мы наткнемся на раздел, в котором будет храниться описание для данного расширение, а также путь для его загрузки. http://savepic.ru/567730.jpg Если с этим разобрались, то переходим непосредственно к нашему расширению. Открываем файлик MyFirstContextMenu.cpp и ищем там функции DllRegisterServer и DllUnregisterServer. Эти функции вызываются соответственно при регистрации и удалении расширения. DllRegisterServer автоматически запишет в реестр путь до библиотеки, поэтому нам придется только сделать ссылку и зарегистрировать ее для конкретного типа файла. Изменяем код DllRegisterServer и DllUnregisterServer таким образом: Код:
STDAPI __export DllRegisterServer(void)А вместо иксов нужно написать нашу ссылку. Заходим в билдере MyFirstContextMenu.tlb, нажимаем на MyFirstContextMenu и копируем оттуда поле GUID. Это и есть идентификатор нашей библиотеки И ИМЕННО ЕГО НУЖНО ПРОПИСАТЬ В РЕЕСТР ДЛЯ ОТОБРАЖЕНИЯ НАШИХ ПУНКТОВ В МЕНЮ ЭКСПЛОРЕРА. Теперь возвращаемся к нашим иксам. Вставляем везде просто вместо них только что скопированную строчку. Компилируем библиотеку по Ctrl+F9. [РЕГИСТРАЦИЯ РАСШИРЕНИЯ] Процесс этот невероятно прост. За нас все сделает волшебный экзишник с именем regsvr32.exe. Открываем командную строку. Переходим с помощью cd и cd ../ к нашей папке cо скомпилированной DLL. И пишем regsvr32 MyFirstContextMenu.dll. И СОБСТВЕННО ВСЕ! http://savepic.ru/560562.jpg Для удаления следует просто добавить аргумент –U, т.е. regsvr32 -U MyFirstContextMenu.dll Теперь заходим в любую папку, тыкаем по любому файлу и видим наш Test Item! http://savepic.ru/563634.png [КАК ДОБАВИТЬ КАРТИНКИ К ПУНКТАМ] Если разобраться, то это тоже просто ;) Так-с… Начнем с начала… А для этого начала необходимо сперва нарисовать иконки в формате BMP с размером 16x16 (желательно использовать как можно меньше бит при сохранении). Cрисовали ^) ?.. Тогда открываем Main.cpp и в глобальных переменных записываем: HBITMAP bitmap1; HBITMAP bitmap2; Рядом с проектом создаем файлик res.rc, а в него копируем: Код:
10000 BITMAP DISCARDABLE "yourbitmap1.bmp"В очередной раз открываем Main.cpp и пишем в функции TMyFirstContextMenuImpl::Initialize после всех проверок следующее: Код:
Теперь в TMyFirstContextMenuImpl::QueryContextMenu после вызова функции InsertMenu копируем: Код:
if ( NULL != bitmap1 )P.S. bitmap2 вставите в другой раз ? [СОЗДАНИЕ ПОДМЕНЮ (SUBMENU)] Вот над этим, честно говоря, просидел дня два. Но как всегда оказалось, что «все гениальное - просто» ?. Для создания подменю достаточно в QueryContextMenu добавить следующие строки: Код:
HMENU HSUBMENU = CreatePopupMenu ();Код:
….[ЗАКЛЮЧЕНИЕ] Ну что?... Научились мы изменять и дополнять меню эксплорера. В качестве дополнительной литературы очень советую прочитать: http://www.rsdn.ru/article/winshell/shlext1.xml. Так как некоторый код в данной статье взят именно оттуда + там же можно увидеть как создавать страницы свойств для файла, подсказки и многое другое. Только придется чуть переделать код для билдера. Так как мы пишем именно для него ;) Скачать пример проекта можно отсюда: http://depositfiles.com/ru/files/xtyae5rud Пароль к архиву: by_dobby007_for_antichat.ru Bye-bye… ;) |
Молодец.
Перенесите пожалуйста в раздел мини - статьи имхо достойная статья. |
Цитата:
Не знаю, вам решать конечно... |
| Время: 13:35 |