Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Ограничение числа экземпляров


Страницы:   1 2 3 4 5

TStas ©   (2006-03-20 14:51:00) 

Читал сегодня статью с форума на эту тему, много это обсуждалось. ОДно мне непонятно: чем вариант с инишкой плох. СПециально только что провери - все отлично работает.
Вот файл проекта:
program Project1;

uses
 Forms,
 Unit1 in 'Unit1.pas', {Form1}
 IniFiles, SysUtils;
{$R *.res}

var
 ini: TINiFile;
 b: Boolean;
begin

 ini:=TINiFile.Create(ExtractFilePath(Application.ExeName)+'Run.ini');
 B:=Ini.ReadBool('Runned', 'Already', false);
 Ini.WriteBool('Runned', 'Already', true);
 if b then
   begin
   Ini.Free;
   Halt;
   end;
 Ini.Free;

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

end. //В нем -то и чииается инишка
А вот файл формы, в нем инишка ставится на место
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs;

type
 TForm1 = class(TForm)
   procedure FormDestroy(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation
uses IniFiles;
{$R *.dfm}

procedure TForm1.FormDestroy(Sender: TObject);
var
 ini: TIniFile;
begin
ini:=TINiFile.Create(ExtractFilePath(Application.ExeName)+'Run.ini');
Ini.WriteBool('Runned', 'Already', false);
Ini.Free;
end;

end.
ВСе работает. МОжет, в каких-то сложных случаях что-то не так?


Leonid Troyanovsky   (2006-04-02 11:11:00) [1]


> Defunct ©   (02.04.06 04:23) [94]


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

Не можно, а нужно.

> Но тут мне кажется могут возникнуть трудности с show.. Imho
> не очень красиво получится, т.к. только что запущенная программа
> не знает в каком состоянии находится предыдущая копия (вдруг

Здесь, видимо, важно состояние не столько первой копии, как запускаемой.
Т.е., то, что юзер выбрал (в параметрах ярлыка, start & etc: развернутое
на весь экран, свернутое в значок и др.) задать первой копии.

--
Regards, LVT.


Alexander Panov   (2006-04-02 05:40:00) [2]

>Defunct ©   (02.04.06 04:23) [94]

С Broadcast еще одна проблема возникает - приложения в разных сессиях...


Defunct   (2006-04-02 04:23:00) [3]

Leonid Troyanovsky ©   (02.04.06 03:36) [93]

Может вы и правы. Хоть в старом MSDN нет таких условий, возможно стоит сделать так чтобы новая копия сама выдвигала окно старой копии наперед, тем более Handle окна известен и приходит ответным сообщением.

Но тут мне кажется могут возникнуть трудности с show.. Imho не очень красиво получится, т.к. только что запущенная программа не знает в каком состоянии находится предыдущая копия (вдруг она свернута и в тоже время видима), тогда будет глюк с миганием в таскбаре вместо отображения окна формы.

Я все-таки за то, чтобы программа (в данном случае старая копия программы) сама отвечала за корректность отображения своих окон.


Leonid Troyanovsky   (2006-04-02 03:36:00) [4]


> Defunct ©   (01.04.06 23:25) [89]

> - косвенно - there is not foreground window (после Halt(0)).


Нет, конечно. Halt выполняется после SentMessage,
т.е. первая копия пытается активизировать себя тогда,
когда вторая foreground.

По поводу других true, можно сказать, что они необходимы,
но, все же, не достаточны.

--
Regards, LVT.


Defunct   (2006-04-02 01:37:00) [5]

Alexander Panov ©   (02.04.06 00:35) [90]

> Только Broadcast вынести в dpr до создания главной формы, и будет все красиво.

Появится некоторая сложность в организации двухстороннего обмена.. Расчитывать только на MSG.Result нельзя, как раз из-за вероятности присутствия в системе таких программ, о которых вы говорили. (которые могут использовать номер нашего сообщения).

> Остаются консольные приложения.
Тут, я - пас. ;>


Piter   (2006-04-02 01:12:00) [6]

Alexander Panov ©   (02.04.06 0:35) [90]
Только Broadcast вынести в dpr до создания главной формы, и будет все красиво


угу, а перед этим ручками создать сигнальное окно?

Нет, я уж лучше мьютексами...


Alexander Panov   (2006-04-02 00:35:00) [7]


> Defunct ©   (01.04.06 23:25) [89]


Хорошо, согласен. Ты меня убедил. В принципе, такой метод для оконных программ подходит.
Только Broadcast вынести в dpr до создания главной формы, и будет все красиво.

Остаются консольные приложения.


Defunct   (2006-04-01 23:25:00) [8]

Alexander Panov ©   (01.04.06 15:06) [88]

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

Да все верно.

> Если программа использует сообщение внутри приложения, не регистрируя его в системе(что вполне возможно - такое вижу сплошь и рядом), то при посылке сообщения из твоей программы широковещательного сообщения эта программа его получит и обработает в соответствии со своими понятиями. Вплоть до AV.

Из моей программы посылается броадкаст с сообщением, уникальный номер которого получен в результате регистрации сообщения. Соответвенно, номер этого сообщения НЕ ИЗ ПОЛЬЗОВАТЕЛЬСКОГО диапазона.

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

Leonid Troyanovsky ©   (01.04.06 11:40) [87]
A process can set the foreground window only if one of the following conditions is true
переводится как:
"процесс может установть окно на передний план только если одно из перечисленных условий справедливо".
В моем случае как минимум несколько условий True:
- нет активных меню,
- foreground not locked
- косвенно - there is not foreground window (после Halt(0))..


Alexander Panov   (2006-04-01 15:06:00) [9]


> Defunct ©   (31.03.06 20:08) [86]
> Регистрировать не обязательно, но и использовать любые номера
> сообщений "от фонаря" тоже нельзя. В Windows отводится непомню
> сколько точно номеров начиная с номера WM_USER как раз для
> такого внутрипрограммного взаимодействия.


Я не о том говорил. Любая программа может использовать сообщения из пользовательского диапазона свободно, как для внетреннего, так и для межпрограммного взаимодействия.

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


Leonid Troyanovsky   (2006-04-01 11:40:00) [10]


> Defunct ©   (31.03.06 09:10) [76]

> тогда либо вы, либо я неправильно понимаем написанное в
> MSDN. Конкретно мое приложение не использует LockSetForegroudWindow,
>  соответственно никаких проблем на которые вы так упорно
> уже 4-й раз намекаете, но прямо ничего не говорите, быть
> не может.


Starting with Microsoft Windows 98 and Windows 2000, the system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true:

The process is the foreground process.
The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The foreground process is being debugged.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
Windows 2000/XP: No menus are active.

Это перечень условий, для тех кто может set.

Прошу указать на такое условие:
окно процесса получило (бродкаст) сообщение.

--
Regards, LVT.


Defunct   (2006-03-31 20:08:00) [11]

> Ну почему. Для внутрипрограммного взаимодействия совсем необязательно регистрировать сообщение. Вот для межпрограммного - да.

Регистрировать не обязательно, но и использовать любые номера сообщений "от фонаря" тоже нельзя. В Windows отводится непомню сколько точно номеров начиная с номера WM_USER как раз для такого внутрипрограммного взаимодействия.

> Так что никакого криминала в использовании номерв незарегистрированных сообщений нет.

Конечно нет, если только не используются номера системных и зарезервированных под регистрацию сообщений в целях внутрипрограммного взаимодейтсвия.


Alexander Panov   (2006-03-31 18:19:00) [12]


> Приложения, которые используют "отфонарные" номера сообщений
> для своих нужд, IMHO нужно сразу отправлять в корзину.


Ну почему. Для внутрипрограммного взаимодействия совсем необязательно регистрировать сообщение. Вот для межпрограммного - да.

Так что никакого криминала в использовании номерв незарегистрированных сообщений нет.

Поэтому Broadcast с любым номер, в принципе, чреват вылетом некоего случайного приложения.


Defunct   (2006-03-31 18:03:00) [13]

Alexander Panov ©   (31.03.06 17:06) [83]

Дык, грамотные приложения не будут использовать сообщения с номерами, зарезервированными под регистрацию без предварительной регистрации. Они будут использовать сообщения WM_USER + .. для своих нужд не так ли?

Приложения, которые используют "отфонарные" номера сообщений для своих нужд, IMHO нужно сразу отправлять в корзину.


Alexander Panov   (2006-03-31 17:06:00) [14]

>
> Defunct ©   (31.03.06 16:47) [81]
>
> Alexander Panov ©   (31.03.06 09:38) [79]
>
> > Если это твое приложение. А если чужое, но использует
> тот же номер сообщения?
>
> Уже ответил на этот вопрос [73]


Ведь не обязательно чужое приложение использует сообщение с регистрацией по имени?


Defunct   (2006-03-31 16:51:00) [15]

> Я пока не пытался работать с консольными приложениями. Если бы они ничем не отличались от оконных, тогда никаких проблем не было бы.-)

Дык, консольные приложения в подавляющем большинстве случаев используеются с перенапраленным выводом, и "резидентно" не висят в памяти долго ;>


Defunct   (2006-03-31 16:47:00) [16]

Alexander Panov ©   (31.03.06 09:38) [79]

> Если это твое приложение. А если чужое, но использует тот же номер сообщения?

Уже ответил на этот вопрос [73]

> Ситуация маловероятна, но возможна. А то, что возможно, бывает происходит чаще, чем хотелось бы.

Ситуация действительно очень маловероятна. Можно попробовать задать сообщение строкой с русскими символами ;> что еще сильнее снизит вероятность появления такой ситуации.


Alexander Panov   (2006-03-31 09:40:00) [17]


> Defunct ©   (31.03.06 09:36) [78]
>
> Alexander Panov ©   (31.03.06 09:31) [77]
>
> должно быть просто:
> или консольное приложение отнести к "безоконным",
> или создав невидимое окошко - перевести в разряд "оконных"
> ;>


Проблема во второй части задачи: вывести на передний план.

Я пока не пытался работать с консольными приложениями. Если бы они ничем не отличались от оконных, тогда никаких проблем не было бы.-)


Alexander Panov   (2006-03-31 09:38:00) [18]


> Defunct ©   (31.03.06 09:10) [76]


Ну я вообще не просто так написал в [66] ( 2. Пример выдвижения программы самой себя тоже неплохо бы увидеть;)). Выдвижение окна самого себя на передний план не такая тривиальная задача-). Просто покритиковать хотелось;)

В MSDN написано про not foreground winndow, но там есть одна мальнькая деталь. Я ее, например, не уловил сразу, из-за чего было сломано немало копий в споре.


> Defunct ©   (31.03.06 03:34) [71]
>
> Alexander Panov ©   (31.03.06 02:05) [68]
>
> Ничего страшного не произойдет.. Windows все равно один
> broadcast разошлет раньше другого, а дальше там сплошной
> блок (с помощью SendMessage). Одно приложение тихо удалится,
>  и на второй броадкаст просто некому будет "отвечать".


Если это твоеприложение. А если чужое, но использует тот же номер сообщения?

Ситуация маловероятна, но возможна. А то, что возможно, бывает происходит чаще, чем хотелось бы.


Defunct   (2006-03-31 09:36:00) [19]

Alexander Panov ©   (31.03.06 09:31) [77]

должно быть просто:
или консольное приложение отнести к "безоконным",
или создав невидимое окошко - перевести в разряд "оконных"
;>


Alexander Panov   (2006-03-31 09:31:00) [20]

И все-таки...

Думаю, что существуют 3 универсальных решения. Одно для безоконных приложений(с этим как раз проблем нет), второе для оконных, третье для консольных.

Задача для безоконного приложения тривиальна. Задача для оконного не так тривиальна, но решаема вполне.

А вот для консольного(эта мысль возникла только сейчас) - не знаю. Даже не занимался вопросом. Хотя стоит подумать.


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо