Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.02.26;
Скачать: CL | DM;

Вниз

Вторая копия программы !   Найти похожие ветки 

 
gdaujk ©   (2005-12-07 19:01) [40]

Leonid Troyanovsky ©   (07.12.05 18:48) [36]

Приемущества семафора понял, объяснять не надо.

PS: автор врядли сам справится что с семафорами, что с мутексами, что с маппингами, так что [29] для него сасое то. А я щас семафоры-то наверное попробую...


 
Leonid Troyanovsky ©   (2005-12-07 19:07) [41]


> Alexander Panov ©   (07.12.05 19:00) [39]

> С учетом [38] вообще-то не все;)


Если уж его залочили, то, видимо, не без для этого оснований.
Т.е., в этом случае он и рассчитывал на лишь поморгать.

--
Regards, LVT.


 
Alexander Panov ©   (2005-12-07 19:10) [42]

Leonid Troyanovsky ©   (07.12.05 19:07) [41]
Если уж его залочили, то, видимо, не без для этого оснований.


Захватывается он системой, и в MSDN описано, для чего.
У нас больше оснований снять блокировку.


 
Leonid Troyanovsky ©   (2005-12-07 19:24) [43]


> Alexander Panov ©   (07.12.05 19:10) [42]

> Захватывается он системой, и в MSDN описано, для чего.


Это немного не то.

Зато я нашел подтверждение своей мысли,
в описалове к  AllowSetForegroundWindow:

Windows 95/98/Me: This function is not implemented. Therefore, processes must cooperate to manage the foreground window. For example, an application may wish to support only one instance. When the second instance starts up, it should detect the previous instance and call SetForegroundWindow on the window of the previous instance. It should not post a message to the window of the previous instance asking it to call SetForegroundWindow on itself, because the previous instance will not necessarily have permission to call SetForegroundWindow.

--
Regards, LVT.


 
gdaujk ©   (2005-12-07 19:36) [44]

Leonid Troyanovsky ©   (07.12.05 18:48) [36]

Это конечно полный offtop, но возникла проблемма: где взять констатны SEMAPHORE_ALL_ACCESS, SEMAPHORE_MODIFY_STATE, и т. п. для OpenSemaphore?  У меня в Windows.pas их нет.

PS: Можно хотябы их значения...


 
Джо ©   (2005-12-07 19:38) [45]


SEMAPHORE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $3);
 SEMAPHORE_MODIFY_STATE  = $0002;

Из windows.pas для D2005. Могу выслать или уточни "и т.п.".


 
Alexander Panov ©   (2005-12-07 19:44) [46]

SEMAPHORE_ALL_ACCESS = $01f0003
SEMAPHORE_MODIFY_STATE = 2
SYNCHRONIZE            = $0100000


 
gdaujk ©   (2005-12-07 20:10) [47]

Джо ©   (07.12.05 19:38) [45]

SEMAPHORE_MODIFY_STATE уже сам догадался :-) Но спасибо.

Alexander Panov ©   (07.12.05 19:44) [46]

Спасибо.


 
gdaujk ©   (2005-12-07 21:01) [48]

А с семафорами точно намного лучше, вроде полная независимость от версии Windows!!! Хотя пробовал только на XP.

Выкладывать не стану, кто хочет - сам напишет. А написать очень советую...

PS: Leonid Troyanovsky, спасибо, что просвятили дурака...


 
Джо ©   (2005-12-07 21:04) [49]


> [48] gdaujk ©   (07.12.05 21:01)

Так вроде и CreateMutex независим от версии Windows?


 
gdaujk ©   (2005-12-07 21:13) [50]

Джо ©   (07.12.05 21:04) [49]

Только с семафорами всё равно намного лучше.


 
Джо ©   (2005-12-07 21:14) [51]


>  [50] gdaujk ©   (07.12.05 21:13)
> Только с семафорами всё равно намного лучше.

Попробую поверить на слово :)


 
gdaujk ©   (2005-12-07 22:47) [52]

Leonid Troyanovsky ©   (07.12.05 18:44) [35]

С маппингами тоже сделал, в принципе оптимальный вариант. А кусок

if IsIconic(h) then
   ShowWindow(h, SW_RESTORE);
SetForegroundWindow(h);


под Win98/ME точно будет работать?

PS: Зачем

SendMessage(h, WM_COPYDATA, ..);


 
Eraser ©   (2005-12-07 23:40) [53]


> gdaujk ©   (07.12.05 22:47) [52]


> PS: Зачем
>
> SendMessage(h, WM_COPYDATA, ..);

Чтобы, например, передать параметр командной строки в существующую копию программы.


 
gdaujk ©   (2005-12-08 06:46) [54]

>Eraser ©   (07.12.05 23:40) [53]

Вобщем-то да, я об этом не подумал.

>gdaujk ©   (07.12.05 22:47) [52]

>А кусок ... под Win98/ME точно будет работать?

С учётом Leonid Troyanovsky ©   (07.12.05 18:48) [36] вопрос снимается, ибо "The process was started by the foreground process" => "A process can set the foreground window"...


 
Leonid Troyanovsky ©   (2005-12-08 09:12) [55]


> gdaujk ©   (07.12.05 21:01) [48]
> А с семафорами точно намного лучше, вроде полная независимость
> от версии Windows!!! Хотя пробовал только на XP.
>
> Выкладывать не стану, кто хочет - сам напишет. А написать
> очень советую...


С семафором я пошутил.
Дело в том, что параметр там LONG >= 0.
А хендлы, скажем, в 98, могут иметь значения и больше $7FFFFFFF.
Насчет XP, w2k не уверен, но и про гарантии ничего не слышал.

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

Ну, а вариант с маппингом я бы советовал выложить.
Во-первых, взгляд со стороны в нашем деле не лишний.
А, во-вторых, это, IMHO, довольно частый вопрос.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2005-12-08 09:15) [56]


> gdaujk ©   (07.12.05 18:52) [37]

> А говорили: "... ни с кем не поделюсь" :-)



Я имел ввиду только реализации ForceForeground.
И даже обосновал :)

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2005-12-08 09:18) [57]


> gdaujk ©   (07.12.05 22:47) [52]

> PS: Зачем
> SendMessage(h, WM_COPYDATA, ..);


Кста,  я хотел написать ahwnd, т.е., то, что сохранялось в мапинге.
Ну и SetForeground, видимо, ему же.

--
Regards, LVT.


 
Defunct ©   (2005-12-08 10:14) [58]

Извините если повторю чей-то ответ, всю ветку не читал.

> Подскажите пожалуйста исключение варианта запуска второй копии программы

"Механизм прост как Мир" (C) Ордынская
Регистрируется сообщение с уникальной идентификационной строкой, и отправляется всем окнам. Если в системе присутствует Ваша программа, то она ловит это сообщение и шлет ответ, мы получаем этот ответ, шлем назад конкретному окну требование "всплыть", а сами потихому уходим (Application.Terminate либо Halt). Пример:

unit unit1;

interface

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

const
 WM_DONTINITIALIZE = WM_USER + 0;
 WM_BRINGTOFRONT = WM_USER + 1;

type
 TForm1 = class(TForm)
   procedure FormCreate(Sender: TObject);
 protected
   procedure WndProc(var Message: TMessage);override;
 end;

implementation

{$R *.dfm}

var
 STARTUP_MSG : Integer;
 CanInitialize : boolean;

procedure TForm1.FormCreate(Sender: TObject);
begin
 CanInitialize := true;
 STARTUP_MSG := RegisterWindowMessage("SAT_SERVER StartUP message");

 if STARTUP_MSG = 0 then
    ShowMessage("Не удалось зарегистрировать сообщение"+#13+#10+
                "для пресечения повторного запуска программы");
 SendMessage(HWND_BROADCAST, STARTUP_MSG, Handle, 0);

 if CanInitialize then
    begin
       ShowMEssage("запуск программы возможен");
       //Initializing
    end
 else
    begin
       ShowMessage("Обнаружена ранее запущенная копия программы, фокус передан ей");
       Application.Terminate;
    end;
end;

procedure TForm1.WndProc(var Message: TMessage);
begin
 if Handle <> Message.WParam then
 if Message.Msg = STARTUP_MSG then
       SendMessage(Message.WParam , WM_DONTINITIALIZE, Handle, 0)
 else
 case Message.MSG of
    WM_DONTINITIALIZE:
       begin
          CanInitialize := False;
          SendMessage( Message.WParam, WM_BRINGTOFRONT, Handle, 0);
       end;
    WM_BRINGTOFRONT:
       begin
          Show;
          Application.BringToFront;
       end;
 end;
 inherited WndProc(Message);
end;

end.


 
Defunct ©   (2005-12-08 10:24) [59]

Defunct ©   (08.12.05 10:14) [58]

Пример можно значительно сократить, выбросив переменную CanInitialize и все что с ней связано, если Application.Terminate вставить непосредственно в обработчик WM_DONTINITIALIZE.


 
Leonid Troyanovsky ©   (2005-12-08 10:33) [60]


> Defunct ©   (08.12.05 10:14) [58]


> "Механизм прост как Мир" (C) Ордынская

Простота мира зависит от простоты наблюдателя.
Скажем, слабый антропный принцип (в моем упрощении).

> Регистрируется сообщение с уникальной идентификационной
> строкой, и отправляется всем окнам. Если в системе присутствует
> Ваша программа, то она ловит это сообщение и шлет

Ну, видимо, почитать предыдущее следовало бы.
Во-первых, ничего регистрировать не надо.
Во-вторых, никаких бродкастов.
В-третьих, на сайте Анатолия Подгорецкого есть фак fido7.delphi,
в котором все подробно разложено, какое д.б. окно, как его
искать, как послать WM_COPYDATA и т.д., все в одном юните.

Q-142: Как избежать повторного запуска моего приложения?

--
Regards, LVT.


 
Defunct ©   (2005-12-08 10:50) [61]

Leonid Troyanovsky ©   (08.12.05 10:33) [60]

> Во-первых, ничего регистрировать не надо.
> Во-вторых, никаких бродкастов.

это во-первых на любителя, а во-вторых зависит от конкретной задачи..

> В-третьих, на сайте Анатолия Подгорецкого есть фак fido7.delphi,
в котором все подробно разложено, какое д.б. окно, как его
искать, как послать WM_COPYDATA и т.д., все в одном юните.

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

Вам тоже Regards


 
Владислав ©   (2005-12-08 11:21) [62]


> Игорь Шевченко ©   (07.12.05 18:27) [32]
> А вот народу нифига непонятно, почему, собстна нельзя просто
> вызвать SetForegroundWindow ?


После нескольких часов напряженной работы я устаю и становлюсь раздражительным. Поэтому мне лучше не садиться за управление танком, иначе я бы с удовольствием переехал бы несколько раз того программиста, который устанавливает фокус ввода на окошко своей любимой и глубокоуважаемой им программы в то время, когда я работаю с другой, не менее любимой мной, программой.
И вообще, господа, если вы хотите привлечь мое внимание, совсем не обязательно бить меня кувалдой по голове. Достаточно будет назвать мое имя, ну или тронуть меня за плечо, если я в глубокой задумчивости.
К чему это все?.. Моргания вполне бы хватило...


 
Leonid Troyanovsky ©   (2005-12-08 11:28) [63]


> Defunct ©   (08.12.05 10:50) [61]
> > Во-вторых, никаких бродкастов.

> это во-первых на любителя, а во-вторых зависит от конкретной
> задачи..


Я и высказался о конкретно этой задаче.
Особенно в конкретном исполнении.

--
Regards, LVT.


 
Defunct ©   (2005-12-08 11:35) [64]

Владислав ©   (08.12.05 11:21) [62]

С бОльшим удовольствием можно переехать того программиста, чья программа при запуске не всплывет, а либо молчит либо просто "моргает в таскбаре".


 
Leonid Troyanovsky ©   (2005-12-08 11:36) [65]


> Владислав ©   (08.12.05 11:21) [62]

> > А вот народу нифига непонятно, почему, собстна нельзя
> просто
> > вызвать SetForegroundWindow ?

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


Надеюсь, пару минут у нас еще есть? ;)

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

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

--
Regards, LVT.


 
Defunct ©   (2005-12-08 11:56) [66]

Leonid Troyanovsky ©   (08.12.05 11:28) [63]

Поясните пожалуйста Вашу точку зрения, а именно чем связка RegisterMessage+broadcast будет хуже связки "FindGUID(FindWindow+GetProp/SetProp)? Хотелось бы услышать обоснованный ответ.

Пример с мьютексом в FAQ-Q142 вообще imho недостоин внимания, т.к. возможны сбои в работе из-за проверки по "заголовку программы".


 
Владислав ©   (2005-12-08 12:02) [67]


> Leonid Troyanovsky ©   (08.12.05 11:36) [65]


Да живите, чего уж там :) Я танком управлять не умею :о)

Останусь при своем, все таки...


 
Leonid Troyanovsky ©   (2005-12-08 12:18) [68]


> RegisterMessage+broadcast будет хуже связки "FindGUID
>  Хотелось бы услышать обоснованный ответ.


В общем: SendMessage vs SendMessageTimeout.
В частности: в приложениях Delphi даже таймеры имеют top-level окно.
И каждое должно ответить, т.е., с переключением контекста.

Т.е., FindWindow лучше, хотя, возможно, еще лучше - EnumWindows.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2005-12-08 12:27) [69]


> Defunct ©   (08.12.05 11:56) [66]

> Пример с мьютексом в FAQ-Q142 вообще imho недостоин внимания,
>  т.к. возможны сбои в работе из-за проверки по "заголовку
> программы".


Он вполне достоин.
Просто выбор имени оставлен заинтересованным лицам.
Бо, пусть каждый решает оную проблему сам.

--
Regards, LVT.


 
Plotnick   (2005-12-08 13:07) [70]

Также, извиняюсь, если повтор. Просто мне кажется, что у меня написано покороче.

В dpr проекта.


var
 g_hAppMutex: THandle;

function OneInstance: boolean;
begin
 g_hAppMutex:=CreateMutex(nil,false,PChar("MyCoolProga"+IntToStr(GetDesktopWindow)));
 Result:=(WaitForSingleObject(g_hAppMutex,0)<>WAIT_TIMEOUT);
end;

begin
 if OneInstance then begin
   // Здесь код по созданию окон и запуска приложения
 end;
end.


Что касается того, можно ли вытащить приложение на передний экран, то в MSDN я где-то читал, что этого сделать нельзя. То есть в 2000 и ХР приложение будет мигать в таскбаре, но на передний план не выйдет.
Однако есть способ обойти эту проблему - одно приложение может вытащить другое приложение на передний план.  Для этого создается утиля со следующим кодом:


var
 PrevInstHandle: THandle;
 dw: DWord;
 hCurrWnd: HWnd;
 iMyTID,iCurrTID: Integer;

 S: String;
 c: Integer;
begin
 S := ParamStr(1);
 val(S,PrevInstHandle,C);

 SendMessage(PrevInstHandle, WM_SYSCOMMAND, SC_RESTORE, 0);

 SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @dw, 0);
 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, 0);
 SetForegroundWindow(PrevInsthandle);
 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(dw), 0);

 hCurrWnd := GetForegroundWindow();
 iMyTID   := GetCurrentThreadId();
 iCurrTID := GetWindowThreadProcessId(hCurrWnd,nil);

 AttachThreadInput(iMyTID, iCurrTID, TRUE);
 SetForegroundWindow(PrevInsthandle);
 AttachThreadInput(iMyTID, iCurrTID, FALSE);
end.


При запуске этой утилиты ей надо в параметрах передать Hanlde гавного окна того приложения, которое надо вытащить на передний план (в строковом виде, ессно). И все. Это работает с гарантией.

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


 
Leonid Troyanovsky ©   (2005-12-08 13:46) [71]


> Plotnick   (08.12.05 13:07) [70]
> Также, извиняюсь, если повтор. Просто мне кажется, что у


Читать топик c самого начала.
Вдумчиво, внимательно.

--
Regards, LVT.


 
gdaujk ©   (2005-12-08 14:09) [72]

Plotnick   (08.12.05 13:07) [70]

Просто мне кажется, что у меня написано покороче.


У кого "короче", тот сидит дома и методически наращивает. Помни: размер имеет значение :-)))

PS: кстати, на счёт "политики M$" и обидчивости некоторых юзеров (Владислав ©   (08.12.05 11:21) [62]). Проанализируйте действия в подобной ситуации Windows Media Player"а (8)...



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

Текущий архив: 2006.02.26;
Скачать: CL | DM;

Наверх




Память: 0.63 MB
Время: 0.046 c
2-1139506864
nirvana
2006-02-09 20:41
2006.02.26
Очень ажный вопрос по DBCombobox или DBListEdit


2-1139171652
asd
2006-02-05 23:34
2006.02.26
действие ActionManager1


9-1125566867
rsy
2005-09-01 13:27
2006.02.26
Главное меню на DELPHIX


15-1139291447
DelphiN!
2006-02-07 08:50
2006.02.26
Соединение с сервером происходит только после его пинга


15-1139292218
syte_ser78
2006-02-07 09:03
2006.02.26
Вопрос по HTM