| 
							MS
							
						 | 
						
							
								  | 
								
									
									 «  : 12-07-2007 09:35 »   | 
								
								 | 
							  
							 
							Подскажите как добавить в контекстное меню проводника пункт для запуска своего приложения. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Ничто так не ограничивает полёт мысли программиста, как компилятор 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алексей++
							
								глобальный и пушистый 
								Глобальный модератор
								
								 
								  Offline
								
								Сообщений: 13
								
								
								
								
								
							  
						 | 
						
							
								  | 
								
									
									 « Ответ #1 : 12-07-2007 09:39 »   | 
								
								 | 
							  
							 
							MS, вопрос неясен )  Может ты имеешь в виду меню Пуск ? Уточни...
  потому что из контекстного меню проводника обычно вызываются инструменты (хотя, в принципе, это тоже ведь программы )
  в любом случае - надо копаться в реестре. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							MS
							
						 | 
						
							
								  | 
								
									
									 « Ответ #2 : 12-07-2007 09:51 »   | 
								
								 | 
							  
							 
							Алексей1153++, нужно чтобы привыделении файлов и клике на правую клавишу мыши в контекстном меню отображался пункт при щелчке на котором запускалась моя прога и в listbox добавлялись пути к выделенным файлам. Вот    
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Ничто так не ограничивает полёт мысли программиста, как компилятор 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							zubr
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #3 : 12-07-2007 14:11 »   | 
								
								 | 
							  
							 
							Этот вопрос решается через шелл. Набери в поисковике слово ShellExt и думаю, найдешь готовый пример. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							MS
							
						 | 
						
							
								  | 
								
									
									 « Ответ #4 : 13-07-2007 06:05 »   | 
								
								 | 
							  
							 
							нашел стандартный пример в Delphi. Непонятна одна строка. Что она значит
  Result := ExpandFileName(ReadString('RootDir') + '\bin\dcc32.exe'); 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Ничто так не ограничивает полёт мысли программиста, как компилятор 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алексей++
							
								глобальный и пушистый 
								Глобальный модератор
								
								 
								  Offline
								
								Сообщений: 13
								
								
								
								
								
							  
						 | 
						
							
								  | 
								
									
									 « Ответ #5 : 13-07-2007 06:29 »   | 
								
								 | 
							  
							 
							MS, всё решение в студию     Нам же тоже интересно  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							zubr
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #6 : 13-07-2007 06:48 »   | 
								
								 | 
							  
							 
							Ms, это определение полного пути к файлу-компилятору Delphi (работающему из командной строки). Дело в том, что в этом примере из созданного пункта контекстного меню должен вызываться компилятор Delphi, который скомпилирует выделенный файл (естественно если это файл проекта Delphi). Алексей1153++, вот код примера: unit ContextM;
  interface
  uses   Windows, ActiveX, ComObj, ShlObj, Dialogs;
  type   TContextMenu = class(TComObject, IShellExtInit, IContextMenu)   private     FFileName: array[0..MAX_PATH] of Char;   protected     { IShellExtInit }     function IShellExtInit.Initialize = SEIInitialize; // Avoid compiler warning     function SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;       hKeyProgID: HKEY): HResult; stdcall;     { IContextMenu }     function QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast,       uFlags: UINT): HResult; stdcall;     function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; stdcall;     function GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;       pszName: LPSTR; cchMax: UINT): HResult; stdcall;   end;
  const   Class_ContextMenu: TGUID = '{EBDF1F20-C829-11D1-8233-0020AF3E97A9}';
  implementation
  uses ComServ, SysUtils, ShellApi, Registry;
  function TContextMenu.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;   hKeyProgID: HKEY): HResult; var   StgMedium: TStgMedium;   FormatEtc: TFormatEtc; begin   // Fail the call if lpdobj is Nil.   if (lpdobj = nil) then begin     Result := E_INVALIDARG;     Exit;   end;
    with FormatEtc do begin     cfFormat := CF_HDROP;     ptd      := nil;     dwAspect := DVASPECT_CONTENT;     lindex   := -1;     tymed    := TYMED_HGLOBAL;   end;
    // Render the data referenced by the IDataObject pointer to an HGLOBAL   // storage medium in CF_HDROP format.   Result := lpdobj.GetData(FormatEtc, StgMedium);   if Failed(Result) then     Exit;   // If only one file is selected, retrieve the file name and store it in   // FFileName. Otherwise fail the call.   if (DragQueryFile(StgMedium.hGlobal, $FFFFFFFF, nil, 0) = 1) then begin     DragQueryFile(StgMedium.hGlobal, 0, FFileName, SizeOf(FFileName));     Result := NOERROR;   end   else begin     FFileName[0] := #0;     Result := E_FAIL;   end;   ReleaseStgMedium(StgMedium); end;
  function TContextMenu.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst,           idCmdLast, uFlags: UINT): HResult; begin   Result := 0; // or use MakeResult(SEVERITY_SUCCESS, FACILITY_NULL, 0);
    if ((uFlags and $0000000F) = CMF_NORMAL) or      ((uFlags and CMF_EXPLORE) <> 0) then begin     // Add one menu item to context menu     InsertMenu(Menu, indexMenu, MF_STRING or MF_BYPOSITION, idCmdFirst,       'Compile...');
      // Return number of menu items added     Result := 1; // or use MakeResult(SEVERITY_SUCCESS, FACILITY_NULL, 1)   end; end;
  function GetCompilerPath: string; // Returns string containing path to Delphi command line compiler var   Reg: TRegistry; begin   Reg := TRegistry.Create;   try     with Reg do begin       RootKey := HKEY_LOCAL_MACHINE;
        OpenKey('\SOFTWARE\Borland\Delphi\6.0', False);       Result := ExpandFileName(ReadString('RootDir') + '\bin\dcc32.exe');     end;     if AnsiPos(' ', Result) <> 0 then       Result := ExtractShortPathName(Result);     Result := Result + ' "%s"';   finally     Reg.Free;   end; end;
  function TContextMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; resourcestring   sPathError = 'Error setting current directory';
  var   H: THandle;   PrevDir: string;    begin   Result := E_FAIL;   // Make sure we are not being called by an application   if (HiWord(Integer(lpici.lpVerb)) <> 0) then   begin     Exit;   end;
    // Make sure we aren't being passed an invalid argument number   if (LoWord(lpici.lpVerb) <> 0) then begin     Result := E_INVALIDARG;     Exit;   end;
    // Execute the command specified by lpici.lpVerb   // by invoking the Delphi command line compiler.   PrevDir := GetCurrentDir;   try     if not SetCurrentDir(ExtractFilePath(FFileName)) then       raise Exception.CreateRes(@sPathError);
      H := WinExec(PChar(Format(GetCompilerPath, [FFileName])), lpici.nShow);
      if (H < 32) then       MessageBox(lpici.hWnd, 'Error executing Delphi compiler.', 'Error',         MB_ICONERROR or MB_OK);     Result := NOERROR;   finally     SetCurrentDir(PrevDir);   end; end;
  function TContextMenu.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;   pszName: LPSTR; cchMax: UINT): HRESULT; begin   if (idCmd = 0) then begin     if (uType = GCS_HELPTEXT) then       // return help string for menu item       StrCopy(pszName, 'Compile the selected Delphi project');     Result := NOERROR;   end   else     Result := E_INVALIDARG; end;
  type   TContextMenuFactory = class(TComObjectFactory)   public     procedure UpdateRegistry(Register: Boolean); override;   end;
  procedure TContextMenuFactory.UpdateRegistry(Register: Boolean); var   ClassID: string; begin   if Register then begin     inherited UpdateRegistry(Register);
      ClassID := GUIDToString(Class_ContextMenu);     CreateRegKey('DelphiProject\shellex', '', '');     CreateRegKey('DelphiProject\shellex\ContextMenuHandlers', '', '');     CreateRegKey('DelphiProject\shellex\ContextMenuHandlers\ContMenu', '', ClassID);
      if (Win32Platform = VER_PLATFORM_WIN32_NT) then       with TRegistry.Create do         try           RootKey := HKEY_LOCAL_MACHINE;           OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions', True);           OpenKey('Approved', True);           WriteString(ClassID, 'Delphi Context Menu Shell Extension Example');         finally           Free;         end;   end   else begin     DeleteRegKey('DelphiProject\shellex\ContextMenuHandlers\ContMenu');     DeleteRegKey('DelphiProject\shellex\ContextMenuHandlers');     DeleteRegKey('DelphiProject\shellex');
      inherited UpdateRegistry(Register);   end; end;
  initialization   TContextMenuFactory.Create(ComServer, TContextMenu, Class_ContextMenu,     '', 'Delphi Context Menu Shell Extension Example', ciMultiInstance,     tmApartment); end.
   
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							MS
							
						 | 
						
							
								  | 
								
									
									 « Ответ #7 : 13-07-2007 07:29 »   | 
								
								 | 
							  
							 
							zubr, откомпилировал проект, с dllкой что делать? 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Ничто так не ограничивает полёт мысли программиста, как компилятор 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							zubr
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #8 : 13-07-2007 08:20 »   | 
								
								 | 
							  
							 
							Надо зарегистрировать сом-сервер. Для этого: 1. Создай батник с текстом: regsvr32.exe Твоя.dll 2. Сохрани его в каталог, где лежит твоя dll. 3. Запусти его. Если все правильно, в проводнике должен появиться новый пункт в контекстном меню.
  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							MS
							
						 | 
						
							
								  | 
								
									
									 « Ответ #9 : 13-07-2007 08:51 »   | 
								
								 | 
							  
							 
							Все успешно компилируется, но пункт не появляется.Вот код. Исправьте пожалуйста что не так. unit ContextM;
  interface
  uses   Windows, ActiveX, ComObj, ShlObj, Dialogs;
  type   TContextMenu = class(TComObject, IShellExtInit, IContextMenu)   private     FFileName: array[0..MAX_PATH] of Char;   protected     { IShellExtInit }     function IShellExtInit.Initialize = SEIInitialize; // Avoid compiler warning     function SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;       hKeyProgID: HKEY): HResult; stdcall;     { IContextMenu }     function QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast,       uFlags: UINT): HResult; stdcall;     function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; stdcall;     function GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;       pszName: LPSTR; cchMax: UINT): HResult; stdcall;   end;
  const   Class_ContextMenu: TGUID = '{EBDF1F20-C829-11D1-8233-0020AF3E97A9}';
  implementation
  uses ComServ, SysUtils, ShellApi, Registry;
  function TContextMenu.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;   hKeyProgID: HKEY): HResult; var   StgMedium: TStgMedium;   FormatEtc: TFormatEtc; begin   // Fail the call if lpdobj is Nil.   if (lpdobj = nil) then begin     Result := E_INVALIDARG;     Exit;   end;
    with FormatEtc do begin     cfFormat := CF_HDROP;     ptd      := nil;     dwAspect := DVASPECT_CONTENT;     lindex   := -1;     tymed    := TYMED_HGLOBAL;   end;
    // Render the data referenced by the IDataObject pointer to an HGLOBAL   // storage medium in CF_HDROP format.   Result := lpdobj.GetData(FormatEtc, StgMedium);   if Failed(Result) then     Exit;   // If only one file is selected, retrieve the file name and store it in   // FFileName. Otherwise fail the call.   if (DragQueryFile(StgMedium.hGlobal, $FFFFFFFF, nil, 0) = 1) then begin     DragQueryFile(StgMedium.hGlobal, 0, FFileName, SizeOf(FFileName));     Result := NOERROR;   end   else begin     FFileName[0] := #0;     Result := E_FAIL;   end;   ReleaseStgMedium(StgMedium); end;
  function TContextMenu.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst,           idCmdLast, uFlags: UINT): HResult; begin   Result := 0; // or use MakeResult(SEVERITY_SUCCESS, FACILITY_NULL, 0);
    if ((uFlags and $0000000F) = CMF_NORMAL) or      ((uFlags and CMF_EXPLORE) <> 0) then begin     // Add one menu item to context menu     InsertMenu(Menu, indexMenu, MF_STRING or MF_BYPOSITION, idCmdFirst,       'Добавить в Renamer');
      // Return number of menu items added     Result := 1; // or use MakeResult(SEVERITY_SUCCESS, FACILITY_NULL, 1)   end; end;
  function GetCompilerPath: string; // Returns string containing path to Delphi command line compiler var   Reg: TRegistry; begin   Reg := TRegistry.Create;   try     with Reg do begin       RootKey := HKEY_LOCAL_MACHINE;
        OpenKey('\SOFTWARE\Renamer\1.0', False);       Result := ExpandFileName(ReadString('RootDir') + '\bin\dcc32.exe');     end;     if AnsiPos(' ', Result) <> 0 then       Result := ExtractShortPathName(Result);     Result := Result + ' "%s"';   finally     Reg.Free;   end; end;
  function TContextMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; resourcestring   sPathError = 'Error setting current directory';
  var   H: THandle;   PrevDir: string;
  begin   Result := E_FAIL;   // Make sure we are not being called by an application   if (HiWord(Integer(lpici.lpVerb)) <> 0) then   begin     Exit;   end;
    // Make sure we aren't being passed an invalid argument number   if (LoWord(lpici.lpVerb) <> 0) then begin     Result := E_INVALIDARG;     Exit;   end;
    // Execute the command specified by lpici.lpVerb   // by invoking the Delphi command line compiler.   PrevDir := GetCurrentDir;   try     if not SetCurrentDir(ExtractFilePath(FFileName)) then       raise Exception.CreateRes(@sPathError);
      H := WinExec(PChar(Format(GetCompilerPath, [FFileName])), lpici.nShow);
      if (H < 32) then       MessageBox(lpici.hWnd, 'Ошибка загрузки программы Renamer', 'Error',         MB_ICONERROR or MB_OK);     Result := NOERROR;   finally     SetCurrentDir(PrevDir);   end; end;
  function TContextMenu.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;   pszName: LPSTR; cchMax: UINT): HRESULT; begin   if (idCmd = 0) then begin     if (uType = GCS_HELPTEXT) then       // return help string for menu item       StrCopy(pszName, 'Переименовать с помощью Renamer');     Result := NOERROR;   end   else     Result := E_INVALIDARG; end;
  type   TContextMenuFactory = class(TComObjectFactory)   public     procedure UpdateRegistry(Register: Boolean); override;   end;
  procedure TContextMenuFactory.UpdateRegistry(Register: Boolean); var   ClassID: string; begin   if Register then begin     inherited UpdateRegistry(Register);
      ClassID := GUIDToString(Class_ContextMenu);     CreateRegKey('Renamer\shellex', '', '');     CreateRegKey('Renamer\shellex\ContextMenuHandlers', '', '');     CreateRegKey('Renamer\shellex\ContextMenuHandlers\ContMenu', '', ClassID);
      if (Win32Platform = VER_PLATFORM_WIN32_NT) then       with TRegistry.Create do         try           RootKey := HKEY_LOCAL_MACHINE;           OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions', True);           OpenKey('Approved', True);           WriteString(ClassID, 'Renamer');         finally           Free;         end;   end   else begin     DeleteRegKey('Renamer\shellex\ContextMenuHandlers\ContMenu');     DeleteRegKey('Renamer\shellex\ContextMenuHandlers');     DeleteRegKey('Renamer\shellex');
      inherited UpdateRegistry(Register);   end; end;
  initialization   TContextMenuFactory.Create(ComServer, TContextMenu, Class_ContextMenu,     '', 'Renamer', ciMultiInstance,     tmApartment); end.
 
   
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Ничто так не ограничивает полёт мысли программиста, как компилятор 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алексей++
							
								глобальный и пушистый 
								Глобальный модератор
								
								 
								  Offline
								
								Сообщений: 13
								
								
								
								
								
							  
						 | 
						
							
								  | 
								
									
									 « Ответ #10 : 13-07-2007 09:40 »   | 
								
								 | 
							  
							 
							MS, ребутнуть для начала надоть 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							MS
							
						 | 
						
							
								  | 
								
									
									 « Ответ #11 : 13-07-2007 11:36 »   | 
								
								 | 
							  
							 
							Алексей1153++, бестолку    
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Ничто так не ограничивает полёт мысли программиста, как компилятор 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							zubr
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #12 : 13-07-2007 14:33 »   | 
								
								 | 
							  
							 
							Надо твой Renamer связать с определенным типом файлов: procedure TContextMenuFactory.UpdateRegistry(Register: Boolean); var   ClassID: string; begin   if Register then begin     inherited UpdateRegistry(Register);
      ClassID := GUIDToString(Class_ContextMenu);     CreateRegKey('.mytip', '', 'Renamer');//связываем     CreateRegKey('Renamer\shellex', '', '');     CreateRegKey('Renamer\shellex\ContextMenuHandlers', '', '');     CreateRegKey('Renamer\shellex\ContextMenuHandlers\ContMenu', '', ClassID);
      if (Win32Platform = VER_PLATFORM_WIN32_NT) then       with TRegistry.Create do         try           RootKey := HKEY_LOCAL_MACHINE;           OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions', True);           OpenKey('Approved', True);           WriteString(ClassID, 'Renamer');         finally           Free;         end;   end   else begin     DeleteRegKey('.mytip');     DeleteRegKey('Renamer\shellex\ContextMenuHandlers\ContMenu');     DeleteRegKey('Renamer\shellex\ContextMenuHandlers');     DeleteRegKey('Renamer\shellex');
      inherited UpdateRegistry(Register);   end; end;  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							MS
							
						 | 
						
							
								  | 
								
									
									 « Ответ #13 : 14-07-2007 06:21 »   | 
								
								 | 
							  
							 
							zubr, спасибо разобрался. Осталось только одно. Подскажи как добавить выделенные файлы в listbox на форме 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Ничто так не ограничивает полёт мысли программиста, как компилятор 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							zubr
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #14 : 14-07-2007 19:04 »   | 
								
								 | 
							  
							 
							Так а в чем проблема, в переменной FFileName и будет полное имя выделенного файла. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							MS
							
						 | 
						
							
								  | 
								
									
									 « Ответ #15 : 15-07-2007 06:29 »   | 
								
								 | 
							  
							 
							zubr, тут вообще все очень странно. Когда я задаю типы файлов * или .*, dll не срабатывает, т.е. в реестре есть а в контекстном меню нет и удалить ее можно. Когда же задаю какой-либо определенный тип файла например .jpg, все отлично. Что делать? Неужели предется ко всем расширениям отдельно прописывать? 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Ничто так не ограничивает полёт мысли программиста, как компилятор 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							zubr
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									«  Ответ #16 : 15-07-2007 11:01 »    | 
								
								 | 
							  
							 
							Придется. Скорее всего это надо сделать программно, то есть программно просканировать реестр на типы файлов и для всех обнаруженных создать свои ключи. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	 |