Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2011.07.24;
Скачать: [xml.tar.bz2];

Вниз

реально ли в рантайме поменять classname формы или я делаю не так   Найти похожие ветки 

 
Jan   (2011-04-06 14:43) [0]

в общем делаю редактор для специального формата. есть задача - запретить запуск второй копии приложения той же версии. понятно, что ищем через findwindow и если находим то программу не запускаем, а активируем предыдущее приложение, но менять для каждой версии classname руками, имхо, бред. вот и возникла злая мысль в рантайме менять classname на уникальный, зависящий от версии приложения, что бы я мог его корректно искать через findwindow (через кэпшн не подходит - он меняется)


 
Ega23 ©   (2011-04-06 14:45) [1]


> понятно, что ищем через findwindow


Вообще-то умные люди ставят мьютекс, а не занимаются извратами с изменением class-name


 
TUser ©   (2011-04-06 14:46) [2]

Посылать найденному окну сообщение, и пусть оно возвращает номер версии, не?


 
Jan   (2011-04-06 14:47) [3]

Мютекс ничего не решит, искать запущенное приложение нужной версии все-равно нужно будет


 
Kerk ©   (2011-04-06 14:48) [4]

http://forum.chertenok.ru/TStringList_i_TThread-t8280-v2


 
Jan   (2011-04-06 14:48) [5]

TUser, можно, но как-то кривовато, если честно:)


 
Kerk ©   (2011-04-06 14:48) [6]


> Jan   (06.04.11 14:47) [3]
>
> Мютекс ничего не решит, искать запущенное приложение нужной
> версии все-равно нужно будет

А для чего ты его ищешь? Нужно передать какие-то данные?


 
asail ©   (2011-04-06 14:49) [7]


> понятно, что ищем через findwindow и если находим то программу
> не запускаем

Нифига не понятно! Так делать не стоит... Лучше посмотри на Mutex.


 
Jan   (2011-04-06 14:50) [8]

Kerk, спасибо, это знаю. Вопрос не только в запрете


 
Ega23 ©   (2011-04-06 14:52) [9]


> Мютекс ничего не решит, искать запущенное приложение нужной
> версии все-равно нужно будет


Мьютекс решит проблему повторного запуска приложения. А вот если он установлен - ищи свой className и активизируй его. Только className у тебя один будет.


 
Jan   (2011-04-06 14:56) [10]

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


 
Германн ©   (2011-04-06 14:57) [11]


> Jan   (06.04.11 14:47) [3]
>
> Мютекс ничего не решит, искать запущенное приложение нужной
> версии все-равно нужно будет
>

А кто мешает записать номер версии в имя мьютекса?


 
Jan   (2011-04-06 14:58) [12]

> Мьютекс решит проблему повторного запуска приложения
это уже решил:)
>А вот если он установлен - ищи свой className и активизируй его. Только
>className у тебя один будет
вооот!:) как сделать класс нэйм уникальным для каждой версии? руками все время менять - изврат


 
Ega23 ©   (2011-04-06 15:00) [13]


> вооот!:) как сделать класс нэйм уникальным для каждой версии?
>  руками все время менять - изврат

Зачем Class Name менять? Меняй мьютекс


 
Kerk ©   (2011-04-06 15:01) [14]


> Jan   (06.04.11 14:56) [10]

Так и думал :)
Можно попробовать использовать TEvent, а данные передавать через memory-mapped file. И первому и второму можно уникальное имя задать, привязанное к версии, если это так важно.


 
Jan   (2011-04-06 15:05) [15]

>Зачем Class Name менять? Меняй мьютекс
если запущенно два приложения разных версий, то нужно найти именно определенной версии. так задача стоит :-/ поэтому через класснейм искать не получится, а через кэпшн окна тоже - он меняется. TUser посоветовал опрашивать номер версии через сообщение - может так и сделаю. но кривовато как-то. ребят, подскажите, а можно ли найти перебрать все окна с нужным класснеймом и по хенду окна найти где лежит exe? тогда я через GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue найду версию сразу в exe? Или бред?:)


 
Jan   (2011-04-06 15:06) [16]

Kerk, спасибо


 
Kerk ©   (2011-04-06 15:09) [17]

Понадобится отдельный поток, который будет ждать Event. Когда приложение запускается повторно и видит, что оно является дубликатом, то все нужное кладется в MMF и устанавливается Event, который принимается первым приложением и обрабатывается. Как-то так оно мне видится.


 
Jan   (2011-04-06 15:17) [18]

Kerk, точно, отличная мысль. Спасибо


 
Jan   (2011-04-06 15:24) [19]

"Когда приложение запускается повторно и видит, что оно является дубликатом"
хотя тут момент. если приложение ненормально, через диспетчер и не вызывался ReleaseMutex (или освобождение Атома, как у меня), то могут быть нюансы. Ну ладно, буду смотреть:)


 
Jan   (2011-04-06 15:25) [20]

"если приложение ненормально"
хотел написать завершилось ненормально


 
oxffff ©   (2011-04-06 15:30) [21]

TForm5 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 procedure CreateParams(var Params: TCreateParams); override;
 end;

var
 Form5: TForm5;

implementation

{$R *.dfm}

procedure TForm5.Button1Click(Sender: TObject);
var buf:array[1..100] of char;
begin
GetClassName(Handle,@buf,100);
showmessage(buf);
end;

procedure TForm5.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.WinClassName:="В рот Вам ноги";
end;


 
Jan   (2011-04-06 15:36) [22]

oxffff, спасибо!


 
Eraser ©   (2011-04-06 15:36) [23]

> [0] Jan   (06.04.11 14:43)

а если вторая копия в другой терминальной сессии?


 
sniknik ©   (2011-04-06 15:39) [24]

> сделал через Атом - там в тексте уникальное имя с номером версии
не особо хорошо... мьютекс сам отвалится если приложение глюкнет/повиснет/просто снимут через таск менеджер, в общем он привязан к процессу, а атом нет.
т.е. в нестандартной ситуации запуск может блокироваться "пустым местом".


 
Jan   (2011-04-06 15:50) [25]

> не особо хорошо... мьютекс сам отвалится если приложение
> глюкнет/повиснет/просто снимут через таск менеджер
знаю. но чем не нравятся мютексы, они не сразу освобождаются, а делать на старте что-то вроде
if WaitForSingleObject(Mutex,10000) = WAIT_TIMEOUT <...>
не хотелось бы. ну в общем тут уже кучу вариантов предложили :) буду пробовать. отличный сайт!


 
Игорь Шевченко ©   (2011-04-06 15:54) [26]


>  но чем не нравятся мютексы, они не сразу освобождаются


??????????????????


 
Jan   (2011-04-06 16:00) [27]

Игорь Шевченко, я имею ввиду, что если повисло приложение


 
asail ©   (2011-04-06 16:14) [28]


> Jan   (06.04.11 16:00) [27]
> Игорь Шевченко, я имею ввиду, что если повисло приложение

Повисшее приложение <> закрытому приложению...
Т.е. если повисло, то мьютекс не даст запустить вторую копию, что пральна весьма...
А вот, ежели убить процесс, то мьютекс освободится, и можно запустить заного. В чем проблема?


 
asail ©   (2011-04-06 16:15) [29]


> asail ©   (06.04.11 16:14) [28]

"Заного", читать как заново...


 
Ega23 ©   (2011-04-06 16:31) [30]

что-то мне напоминает
http://www.gunsmoker.ru/2008/10/x-y-z.html


 
sniknik ©   (2011-04-06 16:37) [31]

> они не сразу освобождаются
как раз наоборот, это если атом явно не освободить то он будет висеть до перезагрузки, что ни делай.
т.что твоя нелюбовь не по адресу.


 
Jan   (2011-04-08 14:07) [32]

> asail
>Т.е. если повисло, то мьютекс не даст запустить вторую копию, что пральна весьма
тут правильно будет опросить приложение и если видим, что висит, то запускать вторую копию
несмотря на мютекс
> Ega23
> что-то мне напоминает
искренне за вас рад:)

Kerk, спасибо за наводку!:) возник такой вот шаблон

в dpr

program test;

uses
 checkprogramrun in "checkprogrammrun.pas" // модуль проверки первым в списке, что бы не ждать инициализации остальных модулей
...

модуль

unit checkprogramrun;

interface

var
 WorkExist: boolean;
 BusyExist: boolean;
 SignaledExist: boolean;
 ProgramExist: boolean;
 MutexProgramRun: THandle;
 EventWork: THandle;
 EventBusy: THandle;
 EventSignaled: THandle;
 Timeout: integer;

implementation

uses Windows, xconst;

initialization
 // проверка запущенной программы
 MutexProgramRun := CreateMutex(nil, False, _EventClassName+_EventProgramRun);
 if MutexProgramRun = 0 then halt;
 ProgramExist := GetLastError = ERROR_ALREADY_EXISTS;

 EventSignaled := CreateEvent(nil, True, False, _EventClassName+_EventSignaled); // состояние сбрасываем руками
 if EventSignaled = 0 then halt;
 SignaledExist := GetLastError = ERROR_ALREADY_EXISTS;

 EventBusy := CreateEvent(nil, True, False, _EventClassName+_EventBusy);
 if EventBusy = 0 then halt;
 BusyExist := GetLastError = ERROR_ALREADY_EXISTS;

 EventWork := CreateEvent(nil, True, False, _EventClassName+_EventWork);
 if EventWork = 0 then halt;
 WorkExist := GetLastError = ERROR_ALREADY_EXISTS;

 Timeout := 0;
 if ProgramExist then
 begin
   // если запущенная программа без сигнального мютекса, то сбой
   if not(SignaledExist) or not(BusyExist) or not(WorkExist) then halt;
   // установим сигнальный эвент
   SetEvent(EventSignaled);
   // ждем 10 секунд пока основная программа не сбросит эвент
   while Timeout < 1000 do
   begin
     if WaitForSingleObject(EventSignaled,0) = WAIT_TIMEOUT then break; // основная программа отвечает
     Sleep(10);
     Inc(Timeout);
   end;
   if Timeout < 1000 then // если нет таймаута передаем данные в программу, иначе запуск в аварийном режиме
   begin
     Timeout := 0;
     while Timeout < 1000 do
     begin
       if WaitForSingleObject(EventBusy,0) = WAIT_TIMEOUT then // основная программа не обрабатывает данные
       begin
        SetEvent(EventBusy); // начали обработку
        break;
       end;
       Sleep(10);
       Inc(Timeout);
     end;
     if Timeout < 1000 then
     begin
       // работа с mmf
       //...
       SetEvent(EventWork); // запускаем обработку
       halt;
     end;
   end;
 end;

finalization
 if MutexProgramRun <> 0 then CloseHandle(MutexProgramRun);
 if EventSignaled <> 0 then CloseHandle(EventSignaled);
 if EventBusy <> 0 then CloseHandle(EventBusy);
 if EventWork <> 0 then CloseHandle(EventWork);
end.

главная форма

const
wm_ParamStr = WM_APP+2;
wm_AfterShow = WM_APP+1;

type
 TfmMain = class(TForm)
 private
   procedure WmParamStr(var Msg: TMessage); message wm_ParamStr;
   procedure WmAfterShow(var Msg: TMessage); message wm_AfterShow;
...

type
 TSyncThread = class(TThread)
 private
   FHandle: THandle;
 protected
   procedure Execute; override;
 public
   constructor Create(CreateSuspended: boolean; handle: THandle);
 end;

...

constructor TSyncThread.Create(CreateSuspended: boolean; handle: THandle);
begin
 inherited Create(CreateSuspended);
 FHandle := handle;
end;

procedure TSyncThread.Execute;
begin
 while true do
 begin
   if WaitForSingleObject(EventSignaled,0) = WAIT_OBJECT_0 then // кто-то опрашивает программу
     ResetEvent(EventSignaled); // ответил
   if WaitForSingleObject(EventWork,0) = WAIT_OBJECT_0 then // запускаем обработку
   begin
     ResetEvent(EventWork);
     PostMessage(FHandle, wm_ParamStr, 0, 0); // именно пост, чтобы не ждать обработки
   end;
   Sleep(1);
end;
end;

procedure TfmMain.FormCreate(Sender: TObject);
begin
 // именно пост, что бы стал в конец стека сообщений
 PostMessage(Handle, wm_AfterShow, 0, 0);
end;

procedure TfmMain.WmAfterShow(var Msg: TMessage);
var SyncThread: TSyncThread;
begin
 inherited;
 SyncThread := TSyncThread.Create(True,Handle);
 SyncThread.FreeOnTerminate := True;
 SyncThread.Priority := tpLower;
 SyncThread.Resume;
end;

procedure TfmMain.WmParamStr(var Msg: TMessage);
begin
 // работа с mmf
 //...
 Application.Restore;
 Application.BringToFront;
 ResetEvent(EventBusy); // закончили обработку
end;



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2011.07.24;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.004 c
2-1303364820
jacksotnik
2011-04-21 09:47
2011.07.24
засечь время работы процедуры


15-1302498254
pavlodar
2011-04-11 09:04
2011.07.24
swf 2 exe со своим флеш плеером


2-1303387690
PiterPen
2011-04-21 16:08
2011.07.24
Показать окно


2-1302852892
OlegM
2011-04-15 11:34
2011.07.24
Как не дать запустить моё приложение из другова приложения ?


2-1302930981
mefodiy
2011-04-16 09:16
2011.07.24
Как отключить F12 в Delphi 2010





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский