понедельник, 19 октября 2009 г.

Простые вещи, которые вы можете делать с ShellExecuteEx

Это перевод Simple things you can do with the ShellExecuteEx function. Автор: Реймонд Чен.

Вот малюсенькая программка.

program ShEx;

{$APPTYPE CONSOLE}

uses
  Windows, SysUtils, ShellAPI;

procedure Work;
var
  sei: TShellExecuteInfo;
  Verb, Target: String;
begin
  if ParamCount = 2 then
  begin
    Verb := ParamStr(1);
    Target := ParamStr(2);

    FillChar(sei, SizeOf(sei), 0);
    sei.cbSize := SizeOf(sei);
    sei.fMask := SEE_MASK_FLAG_DDEWAIT;
    sei.nShow := SW_SHOWNORMAL;
    sei.lpVerb := PChar(Verb);
    sei.lpFile := PChar(Target);

    ShellExecuteEx(@sei);
  end;
end;

begin
  try
    Work;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
Эта маленькая программа принимает два параметра, первый из которых является действием (verb), а второй - именем файла, над которым действие выполняется. Заметьте, что поскольку мы немедленно выходим, нам нужно установить флаг SEE_MASK_FLAG_DDEWAIT: в обычных условиях функция ShellExecuteEx предполагает, что после её выхода у вас будет работать цикл выборки сообщений (message pump). Это позволит ей быстро завершить работу, а все необходимые сообщения DDE будут обработаны позже по мере поступления от DDE сервера. Но если поток сразу же завершает свою работу или же он вообще не является GUI потоком (в нашей программе верно и то и другое), то вы захотите подавить это поведение, потому что у вас нет цикла выборки сообщений, чтобы закончить DDE-общение. Установка флага SEE_MASK_FLAG_DDEWAIT указывает на то, что функция ShellExecuteEx должна закончить всю необходимую работу с DDE до того, как вернуть управление.

В любом случае, я написал эту маленькую программку для иллюстрации двух канонических действий (canonical verbs), которые вы можете использовать. Похоже люди не осознают, что ShellExecuteEx можно использовать для выполнения таких действий, потому что они часто спрашивают, как это сделать...
shex find %windir%
Открывает окно поиска с указанной папкой в поле "Искать в".
shex openas C:\AUTOEXEC.BAT
Отображает диалог "Открыть с помощью" для файла.

Читать далее: не используйте ShellExecute.

4 комментария:

  1. В MSDN пишут, что вместо SEE_MASK_FLAG_DDEWAIT нужно использовать SEE_MASK_NOASYNC.

    ОтветитьУдалить
  2. Оба флага численно равны. Просто ввели псевдоним для более ясной семантики. Флага SEE_MASK_NOASYNC не существовало в то время, когда была написана эта заметка.

    ОтветитьУдалить
  3. Может кто в курсе... Начиная с какой версии Делфи появилась константа SEE_MASK_NOASYNC?

    ОтветитьУдалить
    Ответы
    1. В RAD Studio 2010, модуль ShellAPI.

      const
      SEE_MASK_NOASYNC = $00000100;
      SEE_MASK_FLAG_DDEWAIT = SEE_MASK_NOASYNC;

      Удалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.