Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.01.2009, 15:27   #11
Zerone
++
Пользователь
 
Регистрация: 26.01.2009
Сообщений: 92
По умолчанию

Код:
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;
ITIL/ITSM
Zerone вне форума Ответить с цитированием
Старый 27.01.2009, 15:27   #12
Zerone
++
Пользователь
 
Регистрация: 26.01.2009
Сообщений: 92
По умолчанию

Код:
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.
вот посмотри сорец) Здесь в котекстом меню появится пункт меню при выборе которого компилятор дельфы откомпилит выбранный файл.
ITIL/ITSM
Zerone вне форума Ответить с цитированием
Старый 27.01.2009, 17:25   #13
Ragnarek
Пользователь
 
Регистрация: 26.01.2009
Сообщений: 13
По умолчанию

это тоже DLL?
Ragnarek вне форума Ответить с цитированием
Старый 27.01.2009, 18:59   #14
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

Да, длл, но оно, скорее всего, тебе не нужно. Через COM можно рисовать в меню свои пиктограммы, менять их в зависимости от выбранного файла, выводить инфу из файла прямо в меню и т.п.

Чтоб просто добавить своё действие ко всем файлам - добавить в реестр
Код:
путь HKEY_CLASSES_ROOT\*\shell\Это будет видно в меню\command
значение C:\proga.exe "%1"
Для конкретного типа файлов (*.txt)
Код:
HKEY_CLASSES_ROOT\txtfile\shell\Это будет видно в меню\command
C:\proga.exe "%1"
Создать свой тип файлов (*.ххх) и ассоциировать его с прогой
Код:
путь HKEY_CLASSES_ROOT\.xxx
значение my_cool_xxx_file

путь HKEY_CLASSES_ROOT\my_cool_xxx_file\shell\open\command
значение C:\proga.exe "%1"
где proga.exe - твоя программа, а %1 - превратится в полный путь к файлу, который открыли, его можно будет получить в программе через paramstr(1)
пыщь
JTG вне форума Ответить с цитированием
Старый 27.01.2009, 20:31   #15
Ragnarek
Пользователь
 
Регистрация: 26.01.2009
Сообщений: 13
По умолчанию

Спасибо,сейчас попробую, а то я добавлял ключ реестра но только в LoCAL_MACHINE\shell\DIRECTORY..... и пункт появился в контекстном меню папок. Надо значит *, типа любой файл.
Ragnarek вне форума Ответить с цитированием
Старый 28.01.2009, 01:23   #16
Ragnarek
Пользователь
 
Регистрация: 26.01.2009
Сообщений: 13
По умолчанию

очень интересно,с реестром получилось,спасибо. У меня возник следующий вопрос: А можно ли сделать так, чтобы не запускалась программа, а параметр передавался в уже запущенную программу?
Ragnarek вне форума Ответить с цитированием
Старый 28.01.2009, 02:03   #17
goblinyara
Форумчанин
 
Аватар для goblinyara
 
Регистрация: 02.01.2009
Сообщений: 340
По умолчанию

в DelphiWorld6 есть множество статей(около 20, кажется, точно не помню) как не допустить запуск второй копии программы, вроде бы там было и про перехват параметров этих запусков...

p.s. точно сказать не могу - сижу сейчас с телефона, так что проверить негде
DelphiWorld 6. Скачай, поставь, и будет тебе счастье=)
Программирование, как и любовь -- одно слово, за которым скрывается бесконечное множество занятий.
goblinyara вне форума Ответить с цитированием
Старый 28.01.2009, 02:07   #18
Ragnarek
Пользователь
 
Регистрация: 26.01.2009
Сообщений: 13
По умолчанию

нет,я уже отказался от этой затеи. Просто в пользовательском сообщении (я имею в виду TMessage) передаются только целые параметры, а мне надо было послать строку (имя файла). Я решил это другим способом.
Ragnarek вне форума Ответить с цитированием
Старый 12.08.2011, 00:57   #19
eclipse_99
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 10
По умолчанию

Цитата:
Сообщение от KORN Посмотреть сообщение
нет, можно и без DLL, и можно что бы было контекстное меню и твоя программа как у WinRar
Подскажи пожалуйста как сделать чтоб было как у WinRAR со сторокой параметров передавалось все выделенные файлы (которые открываю)
eclipse_99 вне форума Ответить с цитированием
Старый 21.03.2012, 13:22   #20
Fornit
Пользователь
 
Регистрация: 16.11.2011
Сообщений: 11
По умолчанию

Без длл можно?
Я же правильно понимаю, что для добавления в контекстное меню мы создаём ветку CLSID (например HKEY_CURRENT_USER\Software\Classes\ AIMP.wav\CLSID) со сгенерированным параметром( например {0041494D-5033-4472-6F70-546172676574}).
Как вручную-то? Было б круто.
Fornit вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Контекстное меню mar4elo Общие вопросы Delphi 19 18.09.2009 14:30
Контекстное меню (удалить строчку) Air Свободное общение 1 06.11.2008 21:56
Контекстное меню окон Ntlegend Общие вопросы Delphi 0 06.10.2008 19:06
Встраивание в контекстное меню проводника Никки Общие вопросы Delphi 3 25.06.2008 23:17
Контекстное меню файла... Altera Общие вопросы Delphi 3 29.02.2008 16:57