| 
| 
 | Вопрос # 5 486/ вопрос решён / | 
 |  Здравствуйте эксперты!Столкнуля с такой проблемой: при открытии нескольких файлов через мою программу открывается несколько копий моей программы, что посоветуете?
 Примечание #1 (7 июля 2011, 14:43): В данном случае при открытие файла в листбокс заносится полное имя файла.Но получается что все открытые файлы по одному заносятся в разные лситбоксы из разных копий програмы
 
 
|  |   Вопрос задал: ierihon1 (статус: 1-ый класс)Вопрос отправлен: 7 июля 2011, 14:40
 Состояние вопроса: решён, ответов: 2.
 |  Ответ #1. Отвечает эксперт: Вадим К Здравствуйте, ierihon1!идем по этой ссылке и читаем о использовании WM_COPYDATA
 
|  | Ответ отправил: Вадим К (статус: Академик)Время отправки: 7 июля 2011, 14:53
 Оценка за ответ: 5
 |  Ответ #2. Отвечает эксперт: min@y™ Эта задача состоит из нескольких частей:
 
 Регистрация расширения файла в реестре, чтобы по клику на такой файл запускалась именно твоя прога.
Недопущение запуска второй копии программы.
Активация (разворот, вывод на передний план) окна 1-й копии программы.
Передача 1-й копии программы имени файла от 2-й копии для открытия после завершения.
 1-й пункт - я тут выкладывал модуль в функциями для этого. Воспользуйся.
 
 2-й пункт настолько уже заезжен и пережёван, что в интернете примеры валяются на каждом углу. Могу дать свой пример, если нужно.
 
 3-й пункт делается так: от второй копии программы для первой копии посылается специальное сообщение, а его обработчик в первой копии активизирует главное окно приложения примерно так:
 
 procedure TSourceEditorMainForm.AppEventsMessage(var Msg: tagMSG;
  var Handled: Boolean);
begin
  // Активирование первой копии приложения по сообщению от второй копии
  if Msg.message = ActivateMessage
    then begin
           Application.Restore();
           Application.BringToFront();
         end;
end;Так как это сообщение является межпрограммным, прога должна отличать такие сообщения от чужих. Поэтому ему надо присвоить уникальный идентификатор:
 ActivateMessage:= RegisterWindowMessage(OneInstActivateMessage); 4-й пункт с лёгкостью делается с помощью посылки имени файла через сообщение WM_COPYDATA. У меня это выглядит так:
 
 // Передача командной строки в первую копию программы
procedure SendCommandLine;
var
  PrevMainFormHandle: THandle; // Хэндл формы предыд. копии программы
  FileName: string;
  Len: Integer;
  Data: TCopyDataStruct; // Структура для передачи
  Buffer: array[0..MAX_PATH - 1] of Char; // Буфер для передачи
begin
  FileName:= ParamStr(1);
  Len:= Length(FileName);
 
  if not FileExists(FileName) or (Len > MAX_PATH)
    then Exit;
 
  PrevMainFormHandle:= FindWindow('TSourceEditorMainForm', nil);
 
  if PrevMainFormHandle = 0
    then Exit;
 
  //Buffer:= FileName;
  FillChar(Buffer, SizeOf(Buffer), #0);
  Move(FileNAme[1], Buffer[0], Len);
  Data.dwData:= 0;
  Data.cbData:= SizeOf(Buffer);
  Data.lpData:= @Buffer;
  SendMessage(PrevMainFormHandle, WM_COPYDATA, 0, Integer(@Data));
end;
 
// Обработчик сообщения WM_COPYDATA для принятия
// командной строки из второй копии программы
procedure TSourceEditorMainForm.WmCopyData(var Msg: TWMCopyData);
var
  AFileName: string;
  Buffer: PChar;
  UserCancelled: Boolean;
begin
 
  Buffer:= PChar(Msg.CopyDataStruct.lpData);
  AFileName:= string(Buffer);
 
  // Открытие проекта или файла
  if AnsiLowerCase(ExtractFileExt(AFileName)) = ProjectFileExt
    then ProjectTreeView.OpenProject(AFileName)
    else ProjectTreeView.OpenFile(AFileName, UserCancelled);
end;Полностью dpr-файл программы лежит тут.
 
|  | Ответ отправил: min@y™ (статус: Доктор наук)Время отправки: 7 июля 2011, 15:17
 Оценка за ответ: 5
 |  
 Мини-форум вопросаВсего сообщений: 12; последнее сообщение — 7 июля 2011, 15:40; участников в обсуждении: 3. 
|   | Вадим К (статус: Академик), 7 июля 2011, 14:50 [#1]:по запросу "недопустить запрос второй копии программы delphi" гуглится очень много, пробовали? Галочка "подтверждения прочтения" - вселенское зло. |  
|   | ierihon1 (статус: 1-ый класс), 7 июля 2011, 14:51 [#2]:да пробовал но там только запрет на создание второй копии.. это не совсем то.. если просто запретить то прога больше одного файл не примет. |  
|   | Вадим К (статус: Академик), 7 июля 2011, 14:55 [#3]:Статья там правда о билдере, но это не меняет сути. Галочка "подтверждения прочтения" - вселенское зло. |  
|   | ierihon1 (статус: 1-ый класс), 7 июля 2011, 14:56 [#4]:что то я не совсем понял... Можете пояснить? только на делфи) |  
|   | Вадим К (статус: Академик), 7 июля 2011, 14:57 [#5]:я тоже не понимаю, что Вы не понимаете  . Галочка "подтверждения прочтения" - вселенское зло. |  
|   | ierihon1 (статус: 1-ый класс), 7 июля 2011, 14:59 [#6]:во первых не понял как использовать WM_COPYDATA в делфи и не понял с какими параметрами нужно передать данные в в программу из копии) |  
|   | Вадим К (статус: Академик), 7 июля 2011, 15:02 [#7]: Цитата (ierihon1): во первых не понял как использовать WM_COPYDATAэто такое сообщение, через которое можно послать указатель в другое приложение и он будет действительным  единственное (на сколько мне известно) 
 Цитата (ierihon1): и не понял с какими параметрами нужно передать данные в в программу из копии) а передать нужно всего то один параметр - файл, который нужно открыть.
 Посмотрите ещё на этот пример http://www.delphisources.ru/pages/faq/base/wm_cd_link.html
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | ierihon1 (статус: 1-ый класс), 7 июля 2011, 15:08 [#8]:Ну попробую воплотить этот пример в жизнь и кажется начинает доходить) |  
|   | ierihon1 (статус: 1-ый класс), 7 июля 2011, 15:23 [#9]:Как отправить информацию в программу я разобрался осталось отследить запуск копии) |  
|   | min@y™ (статус: Доктор наук), 7 июля 2011, 15:26 [#10]:Кстати, к такой проге не мешало бы добваить ещё и обработчик сообщения WM_DROPFILES для комплекта. Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | ierihon1 (статус: 1-ый класс), 7 июля 2011, 15:27 [#11]:Уже есть) Но с ним проблем нет) |  
|   | ierihon1 (статус: 1-ый класс), 7 июля 2011, 15:40 [#12]:Ура заработало))) Всем спасибо) |  7 июля 2011, 15:41: Статус вопроса изменён на решённый (изменил автор вопроса — ierihon1) Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |