I would like to create menu item in windows explorer content menu (for all file types) which after click will open my application and pass the selected file name to it. Is there any tutorial for this ? I know there is ShellPlus component available but it’s a bit outdated.
Lars Truijens
42.5k6 gold badges126 silver badges141 bronze badges
asked Sep 26, 2010 at 12:43
0
Registry
This method is easy since it comes down to adding some registry keys. The downside is that you can’t put any logic in it. You can read about it here and here a simple example in Delphi. You get a bit more control if you are using DDE to execute the menu items. See here for a Delphi example.
Shell Extension
This method is a bit more work, but you can completely control the context menu from code. You would have to write a DLL, implement IContextMenu (or others) and register the dll with Windows Explorer. You can read about it here. You already mentioned Shell+.
answered Sep 26, 2010 at 14:11
Lars TruijensLars Truijens
42.5k6 gold badges126 silver badges141 bronze badges
2
Delphi includes a demo project for shell extensions. Look in the DemosActiveXShellExt folder.
answered Sep 26, 2010 at 16:17
Rob KennedyRob Kennedy
161k21 gold badges276 silver badges463 bronze badges
2
This is possible independendly from the programming language by setting up shortcut menu handlers for the desired filetype(s) in the registry. There you can call your application with the correct path, the correct options and the right file-placeholders.
See the MSDN article on Creating Shortcut Menu Handlers for more detailled information.
answered Sep 26, 2010 at 12:53
Kosi2801Kosi2801
21.7k13 gold badges38 silver badges44 bronze badges
Обычно, когда Вы создаёте меню в приложении, то код выглядит примерно так:
- Подробности
- Родительская категория: VCL
- Категория: Menu
Автор: MAD Rodrguez
Вы, наверное, задавались вопросом, почему системное меню постоянно одно и тоже ? Пример показывает, как добавить туда такие пункты как «About» или «Information», или что-нибудь ещё.
Нам понадобится две вещи, первая это Item ID, который может быть любым целым числом. Второе это Описание(Caption) для нашего пункта меню. Нам понадобится также процедура, которая будет принимать сообщения Window для определения нажатия на наш пункт меню.
- Подробности
- Родительская категория: VCL
- Категория: Menu
Допустим, у Вас есть TMainMenu MainMenu1 и HelpMenuItem в конце панели меню (Menubar). Если Вызвать следующий обработчик события OnCreate, то HelpMenuItem сместится вправо.
- Подробности
- Родительская категория: VCL
- Категория: Menu
Ниже мы покажем вариант кода
- Подробности
- Родительская категория: VCL
- Категория: Menu
Следующий пример демонстрирует добавление битмапа в пункт PopUpMenu при помощи API функции SetMenuItemBitmaps(). Эта функция имеет следующие параметры: дескриптор всплывающего меню, номер (начиная с нуля) пункта меню в который мы хотим добаить битмап, и два дескриптора битмапов (одна картинка для меню в активном состоянии, а вторая для неактивного состояния).
- Подробности
- Родительская категория: VCL
- Категория: Menu
nmWindow — это Name пункта меню «Окна»
(этот код я писал для добавления открытых окон в пункт меню «Окна», главного меню своего приложения)
- Подробности
- Родительская категория: VCL
- Категория: Menu
В примере показано как показать меню и выбрать в нем какой-то пункт, эмулируя нажатие «быстрой кдавиши» пункта меню. Если у Вашего пункта меню нет «быстрой клавиши» Вы можете посылать комбинации VK_MENU, VK_LEFT, VK_DOWN, и VK_RETURN, чтобы программно «путешествовать» по меню.
- Подробности
- Родительская категория: VCL
- Категория: Menu
Как в контекстное меню системы Windows?
Может быть, вы можете использовать Keybd_event для eumlate ALT + пробел. Может быть, вы можете использовать TPopupmenu.
Но у них всегда есть какие-то проблемы. Метод ниже является идеальным решением!
BTW: если ваша форма имеет borderstyle = bsNone, пожалуйста, сделайте это так:
Набор форм стиль = bsSingle; и использовать код ниже, чтобы установить бодер форма:
SetWindowLong(ручки, GWL_STYLE,GetWindowLong(ручки, GWL_STYLE) и (не WS_CAPTION) или WS_DLGFRAME или WS_OVERLAPPED);
- Подробности
- Родительская категория: VCL
- Категория: Menu
Eugeny Sverchkov показывает как это можно сделать
- Подробности
- Родительская категория: VCL
- Категория: Menu
В примере создается обработчик события Application.Hint — подсказки меню изображаются на status Panel:
- Подробности
- Родительская категория: VCL
- Категория: Menu
1. Разместите на форме TControlBar. (закладка Additional) Установите Align = Client.
2. Разместите TToolBar (закладка Win32) внутри TControlBar.
3. Установите в True свойства Flat и ShowCaptions этого TToolBar.
- Подробности
- Родительская категория: VCL
- Категория: Menu
-
Как сделать пункты меню с картинками?
-
Как узнать о нажатии non-menu клавиши в момент когда меню показано?
-
Как узнать статус меню?
-
Кнопка в MainMenu с правой стороны
-
Пишем свой текст в Меню
-
Элементы меню на основе изображений
How to add a right click context menu in Windows Explorer for all kind of file extension?
From what I read on the internet, I read a way to do this for certain file extension.
My question, how can we do this for all kind of file extension?
I saw some software did this, for example: WinRar, Notepad++, etc.
PS: I am targeting Delphi 7.0 compatible code.
Thank you.
asked Nov 18, 2011 at 12:44
Kawaii-HachiiKawaii-Hachii
1,0176 gold badges22 silver badges36 bronze badges
The simplest way to do this is to add a registry entry like this:
HKEY_CLASSES_ROOT
*
shell
YourAppName
Command C:FullPathToYourApp.exe "%1"
When the user clicks on this menu item your app will be executed and passed the file name as the first command line argument.
Whilst you can write a shell extension for this, that is more difficult. What’s more, if you are using Delphi 7 then you will not be able to write a shell extension for 64 bit Windows.
answered Nov 18, 2011 at 12:56
David HeffernanDavid Heffernan
596k42 gold badges1054 silver badges1470 bronze badges
1
At «HKEY_CLASSES_ROOT*shell» add key «open with my app» and then add «command» and set Default (REG_SZ) to what you want to run (%1 parameter — filename)
Rob Kennedy
161k21 gold badges276 silver badges463 bronze badges
answered Nov 18, 2011 at 12:56
0
How to add a right click context menu in Windows Explorer for all kind of file extension?
From what I read on the internet, I read a way to do this for certain file extension.
My question, how can we do this for all kind of file extension?
I saw some software did this, for example: WinRar, Notepad++, etc.
PS: I am targeting Delphi 7.0 compatible code.
Thank you.
asked Nov 18, 2011 at 12:44
Kawaii-HachiiKawaii-Hachii
1,0176 gold badges22 silver badges36 bronze badges
The simplest way to do this is to add a registry entry like this:
HKEY_CLASSES_ROOT
*
shell
YourAppName
Command C:FullPathToYourApp.exe "%1"
When the user clicks on this menu item your app will be executed and passed the file name as the first command line argument.
Whilst you can write a shell extension for this, that is more difficult. What’s more, if you are using Delphi 7 then you will not be able to write a shell extension for 64 bit Windows.
answered Nov 18, 2011 at 12:56
David HeffernanDavid Heffernan
596k42 gold badges1054 silver badges1470 bronze badges
1
At «HKEY_CLASSES_ROOT*shell» add key «open with my app» and then add «command» and set Default (REG_SZ) to what you want to run (%1 parameter — filename)
Rob Kennedy
161k21 gold badges276 silver badges463 bronze badges
answered Nov 18, 2011 at 12:56
0
Delphi — как можно добавить свой пункт в контекстное меню проводника
Для иллюстрации объектов — расширений контекстного меню — выберем пример ContMenu (поставляется с Delphi в папке DEMOSACTIVEX SHELLEXT). В этом примере для объектов типа «проект Delphi» добавляется возможность запуска компилятора в командной строке. При вызове метода QueryContextMenu нужный пункт добавляется с помощью функции
InsertMenu!
function TContextMenu.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst,
idCmdLast, uFlags: UINT): HResult;
begin
Result := 0; // или использовать MakeResult(SEVERITY_SUCCESS, // FACILITY_NULL, 0);
if ( (uFlags and $OOOOOOOF) = CMF__NORMAL)
or
((uFlags and CMF_EXPLORE) о 0) then begin
// Добавить один пункт меню во всплывающее меню
InsertMenu(Menu, indexMenu, MF__STRING or MF_BYPOSITION, idCmdFirst,
'Compile...');
Result := 1;
// или использовать MakeResult(SEVERITY_SUCCESS, //
FACILITY_NULL, 1)
end;
end;
Метод Getcornmandstring предоставляет системе данные о пункте меню, в частности, текст подсказки; эта подсказка будет отображаться в строке состояния Проводника, когда курсор находится в нужном месте меню.
Параметры Getcommandstring просты. Первый — idCmd — соответствует идентификатору пункта меню, второй — uType — запрос на тип информации (GCS_HELPTEXT — текст подсказки, GCS_VERB — полное название пункта меню). Наконец, параметры pszName и cchMax задают буфер, в который будут копироваться текстовые данные. Полное название необходимо системе, чтобы с его помощью вызывать предусмотренные в пункте действия программно. В примере ContMenu возврат названия (т. е. обработка запроса GCS_VERB) не предусмотрен, а в ответ на запрос GCS_HELPTEXT возвращается текстовая строка «Compile the selected Delphi project».
Наиболее сложным является метод Invokecommand. Он вызывается при выборе пользователем вставленного вами пункта меню. По сути дела метод InvokeCommand представляет собой прямой аналог обработчика onclick обычных пунктов меню (объектов TMenuitem) в Delphi.
Единственным параметром метода является структура типа TCMinvoke-commandinfo, поля которой имеют такое предназначение:
cbsize — размер структуры в байтах;
hwnd — задает дескриптор окна, которое будет владельцем диалоговых окон, вызываемых из метода;
fMask — определяет, заданы ли параметры dwHotkey/hicon;
Ipverb — вызываемая команда;
IpFarameters — параметры (если есть);
IpDirectory — рабочая папка (поле не обязательно);
nShow — флаг состояния окна, который будет передан в функцию ShowWindow (SW_*);
dwHotKey — «горячая» комбинация клавиш, которая будет сопоставляться приложению, запускаемому из этого пункта меню (только если в параметре fMask установлен флаг CMIC_MASK_HOTKEY);
hIсоn — значок, который будет сопоставляться приложению, запускаемому из этого пункта меню (только если в параметре fMask установлен флаг CMIC_MASK_ICON);
Monitor — монитор по умолчанию (поле не обязательно).
Отдельно следует остановиться на описании параметра ipverb. Как уже говорилось, он может представлять из себя как идентификатор пункта меню, так и его текст — строку, заканчивающуюся нулем. Чтобы выяснить это, нужно проверить старшее слово этого 32-разрядного параметра на равенство нулю. В примере ContMenu вызов по тексту не предусмотрен:
if (HiWord(Integer(Ipici.IpVerb)) <> 0) then
begin
Exit;
end;
Для создания расширения контекстного меню мы должны породить объект, поддерживающий эти интерфейсы. К сожалению, мастера, предусмотренные в Delphi, не позволяют в автоматизированном режиме создавать объекты, реализующие уже существующие интерфейсы. Поэтому и описание, и реализацию методов придется делать «по старинке», вручную. В примере ContMenu описание объекта таково:
TContextMenu = class(TComObject, IShellExtlnit, IContextMenu) private
FFileName: array[0..MAX_PATHj of Char;
protected
( IShellExtlnit }
function IShellExtlnit.Initialize = SEIInitialize;
function SEIInitialize(pidlFolder: PItemlDList; Ipdobj: IDataObject;
hKeyProgID: HKEY): HResult; stdcall; { IContextMenu }
function QueryContextMenufMenu: HMENU;
indexMenu, idCmdFirst, idCmdLast,
uFlags: UINT): HResult;
stdcall;
function InvokeCommand(var Ipici: TCMInvokeCommandlnfo): HResult; stdcall;
function GetCommandString(idCmd, uType: UINT; pwReserved: POINT;
pszName: LPSTR; cchMax: UINT): HResult;
stdcall;
end;
Вас может насторожить конструкция, описывающая переименование метода initialize интерфейса ishellExtinit. На самом деле одноименный метод имеется у объекта TComObject, и приведенный синтаксис как раз и предназначен для выхода из подобных ситуаций.
Последняя часть работы — регистрация созданного обработчика. Самое подходящее место для этого — метод updateRegistry фабрики класса. Разработчики примера ContMenu породили класс TContextMenuFactory, который при регистрации СОМ-сервера регистрирует создаваемые фабрикой объекты:
Classic := GUIDToString(Class_ContextMenu);
CreateRegKey('DelphiProjectXshellex', '', '')/'
CreateRegKey
('DelphiProjectshellexContextMenuHandlers', '', '');
CreateRegKey
('DelphiProjectshellex
ContextMenuHandlersContMenu', '',
ClassID);
Пример ContMenu иллюстрирует «дельфийский» подход к созданию серверов СОМ через соответствующие объекты из иерархии объектов Delphi. Но в папке SHELLEXT вы найдете еще один пример создания расширения для контекстного меню, сделанный целиком и только с использованием интерфейсов и функций СОМ. Присмотритесь к этому примеру внимательнее, если хотите глубже понимать внутреннюю структуру СОМ-объектов.
Обновлено: 01 декабря, 2018
Есть несколько способов добавления своего пункта в системное меню формы.
Способ 1
var SMenu : THandle; begin SMenu := GetSystemMenu(Handle, False); InsertMenu(SMenu, 1, MF_Byposition, ID_NEW, 'NEW'); end;
Способ 2
type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} const SC_MyMenuItem = WM_USER + 1; procedure TForm1.FormCreate(Sender: TObject); begin AppendMenu(GetSystemMenu(Handle, false), MF_SEPARATOR, 0, ''); AppendMenu(GetSystemMenu(Handle, false), MF_STRING,SC_MyMenuItem,'My Item'); end; procedure TForm1.WMSysCommand(var Msg: TWMSysCommand); begin if Msg.CmdType = SC_MyMenuItem then ShowMessage('Got the message') else inherited; end;
Способ 3
type TMyForm=class(TForm) procedure wmSysCommand(var Message:TMessage); message WM_SYSCOMMAND; end; const ID_ABOUT = WM_USER+1; ID_CALENDAR=WM_USER+2; ID_EDIT = WM_USER+3; ID_ANALIS = WM_USER+4; implementation procedure TMyForm.wmSysCommand; begin case Message.wParam of ID_CALENDAR: DatBitBtnClick(Self) ; ID_EDIT : EditBitBtnClick(Self); ID_ANALIS : AnalisButtonClick(Self); end; inherited; end; procedure TMyForm.FormCreate(Sender: TObject); var SysMenu:THandle; begin SysMenu:=GetSystemMenu(Handle,False); InsertMenu(SysMenu,Word(-1),MF_SEPARATOR,ID_ABOUT,''); InsertMenu(SysMenu,Word(-1),MF_BYPOSITION,ID_Calendar, 'Calendar'); InsertMenu(SysMenu,Word(-1),MF_BYPOSITION,ID_Analis, 'Analis'); InsertMenu(SysMenu,Word(-1),MF_BYPOSITION,ID_Edit, 'Edit'); end;
Автор статьи
Программист Delphi, MySQL. Образование: высшее. Специальность: программное обеспечение информационных технологий.
(1 оценок, среднее: 5,00 из 5)
Загрузка…
Назло блокноту. Или всё для работы с расширениями в Windows с помощью Delphi
Статья показывает на конкретных примерах, как ассоциировать вашу программу с каким-либо расширением Windows, самому зарегистрировать свое расширение в системе и как добавить пункт в контекстном меню Windows (типа «открыть в…») для открытия документов вашей прогой (по-видимому текстовым редактором:)
Небольшое вступление, которое надо прочитать
Привет всем кодерам! Эта статья посвящается широкому кругу читателей — будь вы новичок в программировании на Delphi или продвинутый кодер. Я надеюсь, информация, представленная здесь мной, будет вам интересна. Ну да ладно, это так — отступление, приступим к главному, то бишь к кодингу! Но сначала я расскажу вам, зачем стал писать это пособие…
Недавно я закончил делать текстовый редактор. А когда закончил, то подумал, неплохо было бы встроить в Maks Editor (в дальнейшем за этим названием будет подразумеваться мой текстовый процессор) функции ассоциации с различными расширениями Windows, заодно сделать так, чтобы можно было самому регистрировать расширения и прописывать пункты в контекстном меню Windows, отвечающие за запуск документов (типа «открыть в…») моим текстовым процессором!!!
Кто разобрался в том, что я сказал, может пропускать следующие 3 параграфа и читать дальше, кто нет — сейчас объясню суть вышесказанных слов… Помните, когда вы создаете текстовый файл (неважно каким способом), то перед вами раскрывается блокнот (раскрываться может и что-либо другое), и значок вашего файла заменяется значком блокнота (или программы, отвечающей за обработку файлов с расширением .txt). Так вот, за каждое расширение в Windows отвечает одна программа, называемая «программой по умолчанию». Эту программу конечно можно легко изменить для любого расширения: выбираете пункт «открыть с помощью», находите нужную прогу и ставьте галочку — использовать её для всех файлов такого типа.
С ассоциацией расширений вроде бы разобрались — едем дальше. Что значит — самому регистрировать расширения? А это значит, вы должны сказать Windows: «Вот тебе новое расширение, засоси, подруга!» и прописать прогу, которая будет работать с этим расширением — будет «прогой по умолчанию». То есть: зарегистрируете вы расширение .maks, и теперь при каждом открытия файла типа *.maks, будет открываться ваша прога (которую вы, наверное, сами создали) и появляться значок, соответствующий значку проги.
С этим тоже вроде бы всё ясно — прем вперед…Прописка пункта контекстного меню. Ну тут всё легко — в главном контексте Windows создается ваш пункт, при нажатии по которому открывается ваше приложение с содержимым того файла, относительно которого находилось меню. Прогу тоже можно сделать любой.
Так вот, все эти вещи могут понадобиться вам, если вы, например, создаете текстовый редактор. Причем, не обязательно стараться над кодингом редактора — можно просто положить какой-нибудь RichEdit на форму и все… прописать пункт в контекстном меню Виндоуз типа «Открыть с MyEditor». И написать вот это в событие onshow формы:
if (ParamCount > 0) and FileExists(ParamStr(1)) then
RichEdit.LoadFromFile(ParamStr(1));
// если мы сразу открываем файл из Windows, то загружаем его в эдитор
Теперь вы можете легко и быстро работать с документами с помощью вашего эдитора без предварительного инсталлирована его в систему!!! Виндоуз сама опознает поле для редактирования и будет заносить туда данные после открытия!
И запомните, все, что я вам сейчас покажу, требует знаний работы с реестром — но это в принципе не главное. Просто я все делал под Windows XP, а реестр XP и реестр «Леноллиума» — это разные вещи. Поэтому я не даю никакой гарантии, что у вас все будет нормально в другой операционке (я даже с уверенностью говорю, что кроме XP, у вас ассоциация и прочая белиберда вообще не пойдет в другой системе :~(. Так что если вы читаете это пособие, уютно расположившись в Win 3.1, то можете завязывать чтение (что я вам, конечно не рекомендую, так как материал полезен для упрочнения знаний о строении и работе реестра). И не думайте, что я в этой маленькой статейке расскажу о том, как сделать текстовый редактор, я просто покажу вам по 1 примеру на каждый из этих пунктов:
- Как ассоциировать стандартное расширение с прогой
- Зарегистрировать свое расширение
- Добавить пункт в контексте
И все это сотворить програмно с помощью нашей любимой Delphi.
Объяснять я буду, исходя из устройства Delphi 7, но в других средах этот процесс совсем не будет отличаться, так как модуль Registry действует везде.
Начинаем кодинг (или немного про реестр)
Итак начнем. Запускаем Delphi, создаем приложение, у нас появляется форма. На неё мы ложим RichEdit и изменяем его свойство align на alclient. Тем самым мы растянули его по всей форме. Также лучше стереть надпись «RichEdit1» в его свойстве Lines. Теперь создайте еще 1 форму: нажмите file->new->form. Но эта форма (буду называть её form2) у нас пока что не как не связана с главной формой (form1). Для того, что их хоть как-то связать, откройте окно редактора кода у form1 и добавьте модуль с вашей второй формой: пишете слово unit и идентификатор формы (в данной случае 2).
uses unit2; //обязательно!!!
Соединили, ну все равно, form2 нигде не будет у нас видна при запуске проги. Для этого её надо вызвать. Как вы будете её вызывать, решать вам. Можно создать главное меню сверху и оттуда, но я не буду объяснять, как это делать. Я просто взял и поместил обычную кнопку на RichEdit1 — не слишком правильно, но на виду. Теперь обрабатываем событие onclick кнопки button1 (для этого щелкаем по ней 2 раза).
procedure TForm1.Button1Click(Sender: TObject);
begin
// вызываем форму так, чтобы она оставалась в фокусе, пока мы ее не вырубим
form2.ShowModal;
end;
Все, теперь на form2 ложем несколько компонент: 2 edit’a, 2 checkbox’a, 3 button’a.
Первый Edit будет служить у нас полем ввода для расширения, которое мы хотим зарегистрировать, так что изменим его свойство name на extension. А первая кнопка будет у нас регистрировать это расширение — назовем её createext, вторая кнопка будет это расширение дизинтегрировать (какое слово умное я придумал:) — назовем её deleteext.Первый CheckBox будет служить у нас расширением .txt (я покажу вам пример только с одним расширением, так как работа с остальными расширениями идентична), т.е. если чекбокс включен — стоит крестик, то ассоциируем нашу прогу с расширением *.txt, если выключен — крестика нет, то отменяем интеграцию, прописав блокнот «прогой по умолчанию» (как в начале было:). Так что изменяем его имя на txt. Второй CheckBox будет работать совместно с edit2: в edit2 мы будем вводить пункт в контекстном меню, который нам надо зарегистрировать, а флажок будет указывать нам, создавать этот пункт или удалять (включен — создаем, выключен — удаляем:). Изменяем имя второго флажка на context, а имя второго edit’a на contextstr. Изменения имен я сделал только для удобства (чтобы не запутаться:). И наконец последняя кнопка под именем Gues будет делать… потом узнаете что:)
Итак начнем кодить, но сначала я дам вам некоторую инфу про реестр:
Как вы, наверное, знаете, реестр — это большая база данных вашей системы, в котором очень легко напортачить, а исправить содеянное порой просто невозможно (вообще, я вам сразу советую открыть реестр и держать его открытым до конца кодинга). Так вот в реестре 6 главных разделов, а мы будем работать с разделом HKEY_CLASSES_ROOT — в нем хранятся настройки, отвечающие за регистрацию различных расширений, контекстных меню, названий системных программ (корзины, например) и еще куча всего прочего. Открыв раздел HKEY_CLASSES_ROOT, мы первым дело видим список из 18 зарегистрированных текстовых расширений, которые начинаются со знака ! (!txt, например). Спустившись чуть пониже мы, может найти эквиваленты этих расширений типа .txt (перед названием стоит точка). В этих расширениях мы ссылаемся на расширения типа !txt, которые находятся в самом начале и содержат основную информацию о «программе по умолчанию» и иконке этой проги. Так вот, открываем раздел !txt, с которым мы будем работать, и что же мы видим: раздел defaulticon, в котором содержится строковой параметр с адресом иконки проги + , 0 и раздел типа shell->open->command. В разделе command тоже строковой параметр со значением адреса «программы по умолчанию», после которой стоит «%1». Значит нам нужно только изменить адрес проги и иконки и готово дело. В принципе да, но посмотрите в раздел .txt — в нем хранится строковой параметр со значением, ссылающими на раздел !txt, т.е. параметр !txt.
Значит нам нужно, чтобы этот параметр тоже присутствовал — вдруг кто-нибудь нечаянно его удалит…
Действие 1: Ассоциация с расширением .txt
Короче приступаем к реализации функции, ассоциирующей нашу прогу и её иконку с расширением .txt. Для этого мы создадим процедуру под названием fileass,а также занесем модуль registry, отвечающий за работу с реестром.
uses registry;// это обязательно
private // заносим ее вот сюда
procedure fileass;
// функция заносит все параметры ассоциации
//с расширением .txt в реестр или удаляет
их
Она будет отвечать за интеграцию или дизинтеграцию расширения .txt. Ну впрочем, все понятно из листинга с подробными комментариями:
procedure tform9.fileass;
var reg:TRegistry; // переменная, инициализирующая реестр
begin
if txt.Checked then // если флафок включен, то
begin
// инициализируем реестр
reg := TRegistry.Create;
// устанавливаем главный раздел
reg.RootKey := HKEY_CLASSES_ROOT;
// создается ключ ".txt", если его нет
reg.OpenKey('.txt',true);
// создается параметр со значением "!txt", если его нет
reg.WriteString('', '!txt');
// закрываем этот ключ
reg.CloseKey;
// создается ключ "!txtDefaultIcon"
reg.OpenKey('!txtDefaultIcon',true);
// заносится значение параметра "имя приложения, 0" - пиктограмма нашей проги
reg.WriteString('', paramstr(0) + ', 0');
// выходим из ключа
reg.CloseKey;
// создается ключ "!txtshellopencommand"
reg.OpenKey('!txtshellopencommand', true);
// создается параметр со значением "имя файла "%1"" - адрес нашей проги
reg.WriteString('', ParamStr(0) + ' "%1"');
// закрываем ключ
reg.CloseKey;
// освобождаем реестр, но настройки сохраняем
reg.Free;
end;
if not txt.Checked then // если флажок отключен,то
begin
// инициализируем реестр
reg := TRegistry.Create;
// устанавливаем главный раздел
reg.RootKey := HKEY_CLASSES_ROOT;
// создается ключ ".txt"
reg.OpenKey('.txt',true);
// создается параметр со значением "!txt"
reg.WriteString('', '!txt');
// выходим
reg.CloseKey;
// создается ключ "!txtDefaultIcon"
reg.OpenKey('!txtDefaultIcon',true);
// заносится значение параметра "имя приложения, 0" - пиктограмма блокнота
reg.WriteString('', 'NOTEPAD.exe' + ', 0');
// выходим
reg.CloseKey;
// создается ключ "!txtshellopencommand"
reg.OpenKey('!txtshellopencommand', true);
// создается параметр со значением "имя файла %1" - адрес блокнота
reg.WriteString('', 'NOTEPAD.exe' + ' "%1"');
// закрываем ключ
reg.CloseKey;
// освобождаем реестр, но настройки сохраняем
reg.Free;
end;
end;
В принципе все… 1-я (и самая главная) функция готова. Только в адресе иконки я указал адрес программы (paramstr(0)) , потому что я уже подготовил новую иконку, которая обозначает мой текстовый эдитор. Если вы ничего не сделаете. Под расширением .txt будет подразумеваться ваша прога с иконкой Delphi. Так что укажите правильный путь в ключе Defaulticon.
Действие 2: Регистрация своего расширения
Теперь сделаем сами регистрацию расширений (за это, как мы помним, у нас отвечают компоненты extension, createext,deleteext). Для этого мы создадим процедуру newext. А за дизинтеграцию у нас будет отвечать процедура delext. Как всегда добавляем их в раздел PRIVATE и потом описываем.
Private
Procedure fileass;
Procedure newext; // интегрирует наше расширение
Procedure delext; // дизинтегрирует наше расширение
procedure tform2.newext;
var reg:tregistry; // наша переменная для работы с реестром
begin
// инициализируем её
reg:=tregistry.Create;
// устанавливаем начальный раздел
reg.RootKey:=Hkey_Classes_Root;
// создаем ключ типа ".наше расширение"
reg.OpenKey('.'+extension.Text,true);
// записываем в нем ссылку на ключ типа "!.наше расширение"
reg.WriteString('','!'+extension.Text);
// закрываем ключ
reg.CloseKey;
// создаем ключ типа "!.наше расширениеdefaulticon"
reg.OpenKey('!'+extension.Text+'defaulticon',true);
// записываем туда иконку нашей проги
reg.WriteString('',paramstr(0)+', 0');
// выходим
reg.CloseKey;
// создаем ключ типа "!.наше расширениеshellopencommand"
reg.OpenKey('!'+extension.Text+'shellopencommand',true);
// записываем в него адрес проги
reg.WriteString('',paramstr(0)+' "1"');
// закрываем ключ
reg.CloseKey;
// убираемся, но настройки сохраняем
reg.Free;
end;
Вторая процедура:
procedure tform2.delext;
var reg:tregistry; // инициализируем переменную для работы с реестром
begin
// создаем класс для работы с реестром
reg:=tregistry.Create;
// устанавливаем начальный раздел
reg.RootKey:=HKEY_CLASSES_ROOT;
// удаляем ключ типа ".наше расширение"
reg.DeleteKey('.'+extension.Text);
// удаляем ключ типа "!наше расширение"
reg.DeleteKey('!'+extension.Text);
// закрываемся
reg.CloseKey;
// вырубаем все, но настройки сохраняем
reg.Free;
end;
Действие 3: Добавление пункта в контекстное меню Windows
Вот и вторая часть нашего доброго дела готова. Осталась последняя, отвечающая за добавление, удаления пункта контекстного меню. За это у нас (а ну ка вспомнили:) отвечают компоненты context и contextstr. Ну я как всегда создал новую процедуру checkcontext и написал в ней…
Private
procedure fileass;
procedure newext;
procedure delext;
procedure checkcontext; // проверяет, нажат ли флажок,
//в случае успеха создает пункт контекста,
//в случае неуспеха удаляет его
procedure tform2.checkcontext;
var reg:tregistry;
// инициализируем переменную для работы с реестром
begin
// если флажок включен, то
if context.Checked then
begin
// создаем класс для работы с реестром
reg:=tregistry.Create;
// устанавливаем начальный раздел
reg.RootKey:=HKEY_CLASSES_ROOT;
// создаем ключ типа "*Shellлюбое ваше слово"
reg.OpenKey('*ShellOpenWithMaksEditor',true);
// записываем в него строковой параметр типа "любое ваше слово"
reg.WriteString('','OpenWithMaksEditor');
// записываем в него строковой параметр типа "пункт контекста"
reg.WriteString('',contextstr.Text);
// закрываем ключ
reg.CloseKey;
// создаем ключ типа "*ShellOpenWithMaksEditorcommand"
reg.OpenKey('*ShellOpenWithMaksEditorcommand',true);
// записываем в него строковой параметр типа "command"
reg.WriteString('','command');
// записываем в него также строковой параметр типа"адрес проги+" %1""
reg.WriteString('',paramstr(0)+' "1%"');
// закрываем ключ
reg.CloseKey;
// вырубаем весь контекстный плагин нахрен, а настройки оставляем
reg.Free;
end else
if not context.Checked then // иначе, если флажок отключен
begin
// инициализируем переменную для работы с реестром
reg:=tregistry.Create;
// устанавливаем начальнай раздел
reg.RootKey:=HKEY_CLASSES_ROOT;
// удаление ключа типа "*Shellлюбое слово"
reg.DeleteKey('*ShellOpenWithMaksEditor');
// закрываем реестр
reg.CloseKey;
// уходим
reg.Free;
end;
end;
Вот и последняя процедура готова, как видно, здесь проверяется, включен ли флажок: если включен, то пункт, введенный в context, создается, если выключен, то пункт, который был предварительно создан — удаляется. Но мы еще забыли самое главное: ведь у нас есть только процедуры: а ведь их еще надо подставить куда-нибудь, чтобы они работали. Короче, подставляем процедуру, отвечающую за создание нового расширения (newext) в компонент createext (кнопка), функцию, отвечающую за удаление расширения (delext) в компонент deleteext (кнопка). А процедуру, ассоциирующую вашу прогу с .txt (fileass) и процедуру создания, удаления пункта контекста (checkcontext) в компонент Gues (кнопка) — вот она и пригодилась, она будет закрывать форму, предварительно сделав некоторые изменения, продекларированные выше! Ну конечно все функции надо прописать в событии OnClick кнопок:
// реакция кнопки на клик мышью - создание расширения
procedure TForm2.createextClick(Sender: TObject);
begin
newext;
end;
// реакция кнопки на клик мышью - удаление расширения
procedure TForm2.deleteextClick(Sender: TObject);
begin
delext;
end;
Реакция кнопки на клик мышью — ассоциация с расширением .txt и создание/удаление пункта в контексте
procedure TForm2.GuesClick(Sender: TObject);
begin
fileass;
checkcontext;
close;
end;
Ну вот в принципе и все… конечно можно было просто записать коды 4 вышесказанных процедур в события onclick кнопок, но это не есть самый удобный способ…
И в заключение приведу весь код проги:
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,registry;
type
TForm2 = class(TForm)
extension: TEdit;
Gues: TButton;
txt: TCheckBox;
context: TCheckBox;
contextstr: TEdit;
createext: TButton;
deleteext: TButton;
procedure GuesClick(Sender: TObject);
procedure createextClick(Sender: TObject);
procedure deleteextClick(Sender: TObject);
private
procedure fileass;
procedure newext;
procedure delext;
procedure checkcontext;
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure tform2.fileass;
var reg:tregistry;
begin
reg:=tregistry.create;
if txt.Checked then
begin
reg := TRegistry.Create;
reg.RootKey := HKEY_CLASSES_ROOT;
// создается ключ ".my"
reg.OpenKey('.txt',true);
// создается параметр со значением "myfile"
reg.WriteString('', '!txt');
reg.CloseKey;
// создается ключ "myfileDefaultIcon"
reg.OpenKey('!txtDefaultIcon',true);
// заносится значение параметра "имя приложения, 0" - пиктограмма
reg.WriteString('', application.ExeName + ', 0');
reg.CloseKey;
// создается ключ "myfileshellopencommand"
reg.OpenKey('!txtshellopencommand', true);
// создается параметр со значением "имя файла %1"
reg.WriteString('', ParamStr(0) + ' "%1"');
reg.CloseKey;
reg.Free;
end;
if not txt.Checked then
begin
reg := TRegistry.Create;
reg.RootKey := HKEY_CLASSES_ROOT;
// создается ключ ".my"
reg.OpenKey('.txt',true);
// создается параметр со значением "myfile"
reg.WriteString('', '!txt');
reg.CloseKey;
// создается ключ "myfileDefaultIcon"
reg.OpenKey('!txtDefaultIcon',true);
// заносится значение параметра "имя приложения, 0" - пиктограмма
reg.WriteString('', 'NOTEPAD.exe' + ', 0');
reg.CloseKey;
// создается ключ "myfileshellopencommand"
reg.OpenKey('!txtshellopencommand', true);
// создается параметр со значением "имя файла %1"
reg.WriteString('', 'NOTEPAD.exe' + ' "%1"');
reg.CloseKey;
reg.Free;
end;
end;
procedure tform2.newext;
var reg:tregistry; // наша переменная для работы с реестром
begin
// инициализируем её
reg:=tregistry.Create;
// устанавливаем начальный раздел
reg.RootKey:=Hkey_Classes_Root;
// создаем ключ типа ".наше расширение"
reg.OpenKey('.'+extension.Text,true);
// записываем в нем ссылку на ключ типа "!.наше расширение"
reg.WriteString('','!'+extension.Text);
// закрываем ключ
reg.CloseKey;
// создаем ключ типа "!.наше расширениеdefaulticon"
reg.OpenKey('!'+extension.Text+'defaulticon',true);
// записываем туда иконку нашей проги
reg.WriteString('',paramstr(0)+', 0');
// выходим
reg.CloseKey;
// создаем ключ типа "!.наше расширениеshellopencommand"
reg.OpenKey('!'+extension.Text+'shellopencommand',true);
// записываем в него адрес проги
reg.WriteString('',paramstr(0)+' "1"');
// закрываем ключ
reg.CloseKey;
// убираемся, но настройки сохраняем
reg.Free;
end;
procedure tform2.delext;
var reg:tregistry; // инициализируем переменную для работы с реестром
begin
// создаем класс для работы с реестром
reg:=tregistry.Create;
// устанавливаем начальный раздел
reg.RootKey:=HKEY_CLASSES_ROOT
// удаляем ключ типа ".наше расширение"
reg.DeleteKey('.'+extension.Text);
// удаляем ключ типа "!наше расширение"
reg.DeleteKey('!'+extension.Text);
// закрываемся
reg.CloseKey;
// вырубаем все, но настройки сохраняем
reg.Free;
end;
procedure tform2.checkcontext;
var reg:tregistry; // инициализируем переменную для работы с реестром
begin
// если флажок включен, то
if context.Checked then
begin
// создаем класс для работы с реестром
reg:=tregistry.Create;
// устанавливаем начальный раздел
reg.RootKey:=HKEY_CLASSES_ROOT;
// создаем ключ типа "*Shellлюбое ваше слово"
reg.OpenKey('*ShellOpenWithMaksEditor',true);
// записываем в него строковой параметр типа "любое ваше слово"
reg.WriteString('','OpenWithMaksEditor');
// записываем в него строковой параметр типа "пункт контекста"
reg.WriteString('',contextstr.Text);
// закрываем ключ
reg.CloseKey;
// создаем ключ типа "*ShellOpenWithMaksEditorcommand"
reg.OpenKey('*ShellOpenWithMaksEditorcommand',true);
// записываем в него строковой параметр типа "command"
reg.WriteString('','command');
// записываем в него также строковой параметр типа"адрес проги"%1""
reg.WriteString('',paramstr(0)+' "1%"');
// закрываем ключ
reg.CloseKey;
// вырубаем весь контекстный плагин нахрен, а настройки оставляем
reg.Free;
end else
if not context.Checked then // иначе, если флажок отключен
begin
// инициализируем переменную для работы с реестром
reg:=tregistry.Create;
// устанавливаем начальнай раздел
reg.RootKey:=HKEY_CLASSES_ROOT;
// удаление ключа типа "*Shellлюбое слово"
reg.DeleteKey('*ShellOpenWithMaksEditor');
// закрываем реестр
reg.CloseKey;
// уходим
reg.Free;
end;
end;
procedure TForm2.GuesClick(Sender: TObject);
begin
fileass;
checkcontext;
end;
procedure TForm2.createextClick(Sender: TObject);
begin
newext;
end;
procedure TForm2.deleteextClick(Sender: TObject);
begin
delext;
end;
end.
Небольшое заключение, которое надо прочитать
Я рассказал вам несколько полезных функций, но не учитывал те глюки, которые вы сразу заметите — например, я не прописывал событие oncreate и onclose формы (ну надо же сохранять настройки, отвечающие за активность флажков в Инифайлах, чтобы не было никаких изменение:). Это все я оставляю вам… на ужин…