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

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

проблемы с активизацией приложения [D6, Win2k]


Страницы:   1 2

Андрусь ©   (2002-09-24 17:00:00) 

Привет всем! Тут вот мучаюсь со следующей проблемой:необх. ограничить число запущенных экземпляров прогр. на одном компьютере до 1-го.Порылся на сайте тут и начал делать так:в проекте создал новый модуль,который в сорсе указал 1-м(будет подгружен 1-м).В нём в секции initialization
пытаюсь создать мютекс с уник. именем собр. из пути к файлу.Если он уже есть,сл-но один экз. уже запущен.( http://delphi.mastak.ru/articles/limit.html)
Далее я хочу активизировать запущенное ранее приложение. Вот здесь у меня чего-то не отрабатывает.Я делаю так:

Function FindLastAppl(WndText,ClName:String):hWnd;
Var Wnd : hWnd; buff: Array [0..127] Of Char;WTxt:Boolean;
Begin
Result:=0;
Wnd := GetWindow(Application.Handle, gw_HWndFirst);
While Wnd <> 0 Do
Begin {Не показываем:}
If //(Wnd <> Application.Handle) And {-Собственное окно}
IsWindowVisible(Wnd) And {-Невидимые окна}
(GetWindow(Wnd, gw_Owner) = 0) And {-Дочернии окна}
(GetWindowText(Wnd, buff, sizeof(buff)) <> 0){-без заголовков} Then
Begin
If Pos(WndText, StrPas(buff)) > 0 Then Wtxt:=True
Else Wtxt:=False;
GetClassName(Wnd, buff, sizeof(buff));
If (ClName<>"")Then
If (Pos(ClName, StrPas(buff)) > 0)And Wtxt Then
Begin
Result:=Wnd;
Break;
End;
End;
Wnd := GetWindow(Wnd, gw_hWndNext);
End;
(на основании FAQ)
Затем активизируем найденное окно:

//BringWindowToTop(Wnd); тоже как вариант пробовал
ShowWindow(Wnd,SW_ShowNormal);
SetForegroundWindow(Wnd);

Вот. Но почему-то не отрабатывает.Под дебагером смотрел - всё находит,только почему-то не активизируется приложение.
Может кто решал подобную проблему. Может что я делаю не так. Посоветуйте как лучше. Зараннее всем большое спасибо.


Андрусь   (2002-09-25 15:43:00) [21]

Извините пожалуйста,но чего то не въезжаю - причем здесь Application, который не создан. Я нашёл handle окна,приложения,запущенного раньше. Затем BringWindowToTop-виндозная ф-я.
Простите,мастер,но я не въезжаю - поясните.


Song   (2002-09-25 14:12:00) [22]

Потому что объект TApplication не создан ещё на тот момент, устал Вам объяснять. :(


Андрусь   (2002-09-25 14:05:00) [23]

Честно говоря немного не до конца въехал чего вы хотите посоветовать. Скорей всего так я делаю..

program Experimentation;

uses
UOneHInst in "UOneHInst.pas",
Forms,
Unit1 in "Unit1.pas" {Form1};

{$R *.res}

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

У меня проверка в Initialization модуля UOneHinst.
Вот и этого. Чего-то там не отрабатывает BringWindowToTop. Хотя внутри приложения работает.


Song   (2002-09-25 13:42:00) [24]

Я бы порекомендовал поместить проверку не в Initialization главного модуля, а в dpr


Андрусь   (2002-09-25 13:32:00) [25]

> Мастер Song ©
Хотябы то чудненько отрабатывает,как с другими виндами.
Отрабатывает в приложении,но в секции Initialization - нет. Делаю я по одной статье(упоминалась выше),так вот там мютекс и проверка идут в initialization отд. модуля, который в программе указан перевым.

unit UOneHInst;
interface
uses
Windows,SysUtils,Forms;
................
initialization
If StopLoading then
Begin
ShowErrMsg;
Wnd:=FindLastAppl("Experimentation", "TApplication")
BringWindowToTop(Wnd);
ShowWindow(Wnd,SW_SHOW);
halt;
End;
finalization
if Mutex <> 0 then
CloseHandle(Mutex);}
end.


Song   (2002-09-25 12:41:00) [26]

Ну если хэндл нашли, пол дела сделано.
Вот попробуйте хотя бы это: BringWindowToTop()


qube   (2002-09-25 12:39:00) [27]

нашёл handle нужного окна,осталось одно - активизировать его.
Может быть пойти другим путём?..

А может, послать ему сообщение?


Андрусь   (2002-09-25 12:34:00) [28]

>DiamondShark
Чего-то в этом духе я и подозревал.

Но всё же.Как мне быть.Необх. исключить вызов второй копии программы - с чем прекрасно справляются мютексы, плюс переключится после попытки запуска второй копии приложения на старую. и чтобы корректно отрабатывала во всех Виндах - тут тоже вроде бы всё победил:нашёл handle нужного окна,осталось одно - активизировать его.
Может быть пойти другим путём?..


DiamondShark   (2002-09-25 11:05:00) [29]

Ваша проблема -- в особенностях SetForegroundWindow под Win2k.
Там она сделана так, что процесс не может установить окно переднего плана для другого процесса.


kerk   (2002-09-24 19:05:00) [30]

в RX есть функция ActivatePrevInstance она находится в VCLUtils, она прекрасно работает.


AL2002   (2002-09-24 18:47:00) [31]

Тогда временный файл в памяти создать и хватит.


handra   (2002-09-24 18:42:00) [32]

AL2002 ©> в целях совместимости с Win16, M$ не рекомендует использовать


AL2002   (2002-09-24 18:32:00) [33]

А к hPrevInst ты как относишься?


handra   (2002-09-24 18:29:00) [34]

объяви обработчик сообщения в окне проги и шли его ему:

const
MY_MSG_SHOW = WM_USER + 5563

TForm1=class(TForm)
...
private
procedure FMyMsgShow(var Msg: TMessage); message MY_MSG_SHOW;

...

procedure TForm1.FMyMsgShow(var Msg: TMessage);
begin
//восстанавливаешь здесь свое приложение
end;


В другом приложении SendMessage(НайденныйHWND,MY_MSG_SHOW,0,0);


Андрусь   (2002-09-24 18:16:00) [35]

А класс окна у всех TApplication... По крайней мере GetClassName давал мне такие(для моих приложений).
Ну про титл: а если он не постоянен.


Song   (2002-09-24 18:07:00) [36]

2Андрусь © (24.09.02 18:01)
По классу окна.

А я, заметьте про окно ничего и не говорил.
Я говорил про Application.Handle.
Дык вот. Если Вы в программе зададите Application.Title можете по этому Title искать через FindWindow()


Андрусь   (2002-09-24 18:01:00) [37]

>Song
Это понятно. Но вот у меня ситуация (как и в одном из FAQ),когда нет полного текста окна.Как быть здесь...


Song   (2002-09-24 17:42:00) [38]

В качестве дискриптора на SetForeGroundWindow() надо передавать Application.Handle того приложения, т.е. просто найти его через FindWindow(). Весь этот цикл не нужен.


Андрусь   (2002-09-24 17:24:00) [39]

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


Дежавюев   (2002-09-24 17:13:00) [40]

Фигня. Используй Mutex-ы. Просто и сердито!


Страницы:   1 2

Наверх

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