Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Открытие выбранного файла в работающем приложении

Delphi , Программа и Интерфейс , MDI приложения

Открытие выбранного файла в работающем приложении

Автор: Пангин Дмитрий Викторович

При программировании MDI-приложений возникает следующая задача: Если пользователь кликнул на файле, тип которого поддерживается создаваемым приложением, то, если приложение уже запущено, не нужно запускать новую копию приложения, а нужно открыть выбранный файл в уже работающем приложении. Я сделал это так (возможно есть более красивое решение):


// В файле проекта:
var

  i: integer;
  hMainForm: hwnd;
  copyDataStruct: TCopyDataStruct;
  ParamString: string;
  WParam, LParam: integer;
begin
  // ищем главное окно приложения, вместо Caption - nil,
  // поскольку к заголовку главного окна может добавиться заголовок MDIChild
  // (нужно позаботиться об уникальности имени класса главной формы)

  hMainForm := FindWindow('TMainForm', nil);
  if hMainForm = 0 then
  begin
    Application.Initialize;
    Application.CreateForm(TFrmMain, frmMain);
    for i := 1 to ParamCount do
      TMainForm(Application.MainForm).OpenFile(ParamStr(i));
    Application.Run;
  end
  else
  begin
    ParamString := '';
    for i := 1 to ParamCount do
    begin
      // запихиваем все параметры в одну строку с разделителями ?13

      ParamString := ParamString + ParamStr(i) + #13;
    end;
    // создаем запись типа TCopyDataStruct

    CopyDataStruct.lpData := PChar(ParamString);
    CopyDataStruct.cbData := Length(ParamString);
    CopyDataStruct.dwData := 0;
    WParam := Application.Handle;
    LParam := Integer(@CopyDataStruct);
    // отсылаем сообщение WM_COPYDATA главному окну открытого приложения

    SendMessage(hMainForm, WM_CopyData, WParam, LParam);
    Application.Terminate;
  end;
end.

// Обработчик сообщения WM_COPYDATA

procedure TMainForm.CopyData(var Msg: TWMCopyData);
var

  ParamStr: string;
  CopyDataStructure: TCopyDataStruct;
  i: integer;
  len: integer;
begin

  CopyDataStructure := Msg.CopyDataStruct^;
  ParamStr := '';
  len := CopyDataStructure.cbData;
  for i := 0 to len - 1 do
  begin
    ParamStr := ParamStr + (PChar(CopyDataStructure.lpData) + i)^;
  end;

  i := 0;
  while not (Length(ParamStr) = 0) do
  begin
    if isDelimiter(#13, ParamStr, i) then
    begin
      OpenFile(Copy(ParamStr, 0, i - 1));
      ParamStr := Copy(ParamStr, i + 1, Length(ParamStr) - i - 1);
    end;
    inc(i);
  end;
  inherited;
end;

// проверено, работает.

Программа для открытия файла в уже запущенной приложении MDI, когда пользователь кликнет на файл, который поддерживается приложением. Вот шаг за шагом, как она работает:

  1. Основной программный код проверяет, есть ли уже основное окно формы (hMainForm) с помощью функции FindWindow. Если нет, то создает новый экземпляр приложения и запускает его.
  2. Если hMainForm найден, программа извлекает все параметры командной строки и конструирует строку с ними, разделяя их символами возврата (\r).
  3. Затем программа создает запись TCopyDataStruct и заполняет ее поля конструированной строкой, устанавливая WParam в handle основного окна формы (Application.Handle) и LParam в указатель на запись CopyDataStruct.
  4. Программа отправляет сообщение WM_COPYDATA в окно hMainForm с заполненной записью TCopyDataStruct, что вызывает процедуру CopyData в основной форме.

Процедура CopyData отвечает за обработку полученных данных. Она извлекает строку из записи TCopyDataStruct и перебирает ее, чтобы найти отдельные имена файлов, разделенные символами возврата. Для каждого найденного имени файла она открывает соответствующий файл с помощью метода OpenFile.

Вот некоторые предложения по улучшению:

  1. Вместо ручного конструирования параметров командной строки можно использовать библиотеку ShellAPI, чтобы получить список файлов, а затем перебирать их.
  2. Рассмотрите возможность использования более надежного метода для поиска основного окна формы, например, проверки, запущено ли приложение перед попыткой создания нового экземпляра.
  3. Вам может потребоваться добавление обработки ошибок в случаях, когда файл не может быть открыт или сообщение WM_COPYDATA не может быть отправлено.
  4. Вместо отправки сообщения WM__COPYDATA напрямую в окно основной формы можно использовать более централизованный подход, зарегистрировав обработчик событий, который получает уведомления о выборе файла.

Альтернативное решение:

Вместо использования WM_ COPYDATA можно использовать более современный подход с механизмами межпроцессной связи (IPC), такими как трубы или сокеты. Это позволит вашему приложению получать уведомления от оболочки о новых выбранных файлах, не требуя ручного вмешательства.

Например, вы можете создать трубу между вашим приложением и оболочкой, а затем иметь оболочку писать имена файлов в трубе, когда они выбираются. Ваши приложение будет читать из трубы и открывать файлы, какneeded. Этот подход будет более надежным и масштабируемым, чем использование WM_ COPYDATA, особенно в случаях, когда запущены несколько экземпляров вашего приложения одновременно.

Открытие выбранного файла в работающем приложении: программа на Delphi для открытия файлов в уже запущенном приложении MDI-приложения.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: MDI приложения ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 14:21:28/0.014509916305542/1