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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 17.06.2008, 22:26   #1
dr.Chas
***
Участник клуба
 
Аватар для dr.Chas
 
Регистрация: 30.07.2007
Сообщений: 1,162
По умолчанию Как передать данные уже в запущеную программу

Т.е. как в ноте пад, не запускаеться ещё одна копия, а открываеться вкладка.
Вот то что я написал в .dpr
Код:
begin
  CheckEvent:=TEvent.Create (nil, false, true, 'Program');
  If CheckEvent.WaitFor (10) <> wrSignaled then
// программа запущенна что тут написать? Что бы передать параметры
  else
// программа не запущенна
  begin
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  end;
end.
В событии create у меня есть такое:
Код:
if (paramcount>0) and fileexists(paramstr(1)) then
А если я передам в программу параметры какое это должно быть событие?
dr.Chas вне форума Ответить с цитированием
Старый 17.06.2008, 22:46   #2
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Для начала нужно предотвратить запуск копии
http://programmersforum.ru/showthread.php?t=21585

Далее нужно получить параметр, думаю так же через paramstr, но не в Create формы (это при запуске, второй раз этого события не будет) а получать сообщение от винды, но я точно не знаю какое. Или может из той копии, пока она не закрылась, передать сообщение своей программе.
Тут я точно не скажу.

p.s. Сразу не въехал, ты все это уже сделал )
Про SendMessage поищи темы может найдешь подходящее.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 17.06.2008 в 22:52.
mutabor вне форума Ответить с цитированием
Старый 17.06.2008, 23:39   #3
dr.Chas
***
Участник клуба
 
Аватар для dr.Chas
 
Регистрация: 30.07.2007
Сообщений: 1,162
По умолчанию

Цитата:
Сообщение от mutabor Посмотреть сообщение
p.s. Сразу не въехал, ты все это уже сделал )
Про SendMessage поищи темы может найдешь подходящее.
Ну с кем не бывает))
А темы я искал просмотрел нашёл, вот эту тему http://pblog.ru/?p=8
Честно скажу, многое я из неё не понимаю, но дело ещё даже не в этом, уж слишком там очень объёмно, поэтому решил спросить, может кто знает как можно подругому, а это как запасной вариант.
dr.Chas вне форума Ответить с цитированием
Старый 18.06.2008, 08:25   #4
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Статья очень хорошая. Ничего лишнего в ней нет, а как раз то что тебе надо, как передать сообщение в копию своей программы. Кода много, но и задача не из простых. Объемно, так это даже лучше, а что лучше если был бы только код и ни одного пояснения? Так что вникай потихоньку )

Пересказывать тебе все это по второму разу нет никакого смысла, лучше спроси именно то, что не понимаешь.

Там смотри внизу указали на ошибку с мьютексами, я мало в этом разбираюсь, но вроде у тебя более правильный вариант проверки на запущенную копию, есть задержка(10).
Насчет хранения хэндла окна, там тоже автор сказал что использует не лучший способ, а какой лучший даже не намекнул. Я могу еще предложить хранить в файле, в том же ini (WriteInteger), больше ничего на ум не приходит.
А вообще статья полная, есть код, так что у тебя все получится.

Я был прав насчет сообщения (WM_COPYDATA) и SendMessage, все таки немного разбираюсь в колбасных обрезках )
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 18.06.2008, 15:26   #5
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

dr.Chas, если задача состоит только в том, чтобы передать в другую копию командную строку, то WM_COPYDATA - проще всего.
Вот эта:
Код:
  CheckEvent:=TEvent.Create (nil, false, true, 'Program');
  If CheckEvent.WaitFor (10) <> wrSignaled then
конструкция не совсем правильна. После получения хендла нужно проверять GetLastError на предмет ошибки ERROR_ALREADY_EXISTS. Не нужно никаких WaitFor. Имя 'Program' абсолютно непригодное - чем длиннее, сложнее и случайнее будет имя объекта, вроде '__$$$_87876tyut_My_Executable_File _Name_hkjahjhk_###_EvEnT__', тем меньше вероятность, что он будет создан каким-то другим приложением, не имеющим с "нашим" ничего общего.
B_N вне форума Ответить с цитированием
Старый 18.06.2008, 16:30   #6
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

B_N, а как насчет того способа что в статье, ты согласен с критикой, или же все верно? И если там не совсем верно, как будет более правильно?
Код:
var HM: THandle;
function Check: boolean;
begin
HM := OpenMutex(MUTEX_ALL_ACCESS, false, ‘TestProjectMutex’);
Result := (HM <> 0);
if HM = 0 then HM := CreateMutex(nil, false, ‘TestProjectMutex’);
end;
Цитата:
Обращаю Ваше внимание на то, что в данной статье присутствует грубейшая ошибка, сводящая на “НЕТ” саму идею межпроцессной синхронизации, в следующем коде:
...
(сначала - OpenMutex. Потом принятие решения на основе OpenMutex - HM0 , а потом выводы на осное решения - CreateMutex. А что будет, если другой поток будет исполняться с опозданием, например, ровно на одну инструкцию процессора? ). В подобных случаях необходимо сразу создавать мьютекс (CreateMutex) и принимать решение на основании возвращённого значения и значения кода ошибки в GetLastError() (уничтожая его посредством CloseHandle, если он оказывается ненужным (т.е. во втором… (не первом) ) экземпляре запущенной программы).
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 18.06.2008, 16:51   #7
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

С этой критикой всё правильно. Типичная (и очень распространённая) ошибка, когда забывают, что работают под многозадачной ОС. Поэтому и рекомендуется в таких случаях не открывать именованые объекты, а создавать. ОС создаёт объекты атомарно, не более одного в любой момент, а два объекта с одинаковыми именами создать не даст - вернёт уже существующий объект и соответствующую ошибку - ERROR_ALREADY_EXISTS.

------------------------------

Код:
program Project1;
uses
  Forms,
  windows,
  system,
  dialogs,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

const
    pszMutantName : PWIDECHAR = '__$$$_TesT_lOCk_aPp_$$$__MuTaNt__';
var
    hMutant : THANDLE;

begin

    hMutant := CreateMutexW(nil, FALSE, pszMutantName);
    if hMutant = 0 then begin
        // Не удалось создать объект
        // Случай редкий и скорее всего говорит или о
        // неверных параметрах, или о нехватке памяти
        // Уточняется через GetLastError()
        ShowMessage('Ошибка создания объекта');
    end
    else if GetLastError() = ERROR_ALREADY_EXISTS then begin
        // Объект уже существует, значит, с высокой вероятностью,
        // при "хорошем" имени объекта, создан другой, уже
        // работающей копией приложения
        ShowMessage('Приложение уже запущено');
        exit;
    end;

  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Последний раз редактировалось B_N; 18.06.2008 в 17:08.
B_N вне форума Ответить с цитированием
Старый 18.06.2008, 17:03   #8
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

То есть все та же вероятность попасть на такое же название от чужой программы?

Но тогда и с созданием те же грабли, система же не даст создать мьютекс с тем же названием. В результате наша программа будет считать что это запущена ее копия. Получается единственный способ избежать этого - задать уникальное имя, к-рое наверняка не повторится.
Или я что-то неправильно понимаю?
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 18.06.2008, 17:15   #9
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Цитата:
Сообщение от mutabor Посмотреть сообщение
Получается единственный способ избежать этого - задать уникальное имя, к-рое наверняка не повторится.
Или я что-то неправильно понимаю?
Да. Примерно та же история, что с паролями. Конечно если "придумать" "хорошее" имя, эту ситуацию можно сделать практически невероятной. Тем более, что для такой прверки подходят любые именованые объекты, кроме дисковых файлов, пожалуй. Можно, например, создавать именованые секции в пейдж-файле и в них записывать какую-то уникальную для приложения информацию, но, в принципе, просто достаточно задать хорошее имя обычному синхрообъекту.
B_N вне форума Ответить с цитированием
Старый 18.06.2008, 18:15   #10
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Вот, написал программку по этой теме, сам заодно разобрался.
Использовались эта статья, этот форум, другие форумы и свои наработки.
Реализованы многие "чаво" вопросы:
- Проверка на наличие запущенной копии
- Передача сообщения копии своей программы
- Прием параметров командной строки
- Динамическое добавление вкладок
- Вывод программы на передний план

Программа просмотра изображений, путь к картинкам принимает из командной строки (перетащить файл на значок программы или из контекстного меню файла Открыть с помощью), если программа уже запущена, открывает картинку в новой вкладке и выводит окно на передний план. Закрыть вкладки можно правой кнопкой мыши.
Вложения
Тип файла: rar ImgViewer(D7).rar (52.2 Кб, 152 просмотров)
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как передать данные из SQL в файл _ozzy_ БД в Delphi 0 12.06.2008 16:50
Передать Канву Pedro Работа с сетью в Delphi 7 28.04.2008 17:38
Как записать данные в другую программу? Спартак Общие вопросы Delphi 23 19.04.2008 22:33
как из dll передавать данные в основную программу? andrey4623 Общие вопросы Delphi 5 06.08.2007 10:15
передать данные другому приложению vasya_pupkin Win Api 1 16.02.2007 20:17