Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Отследить активизацию приложения


Автор: SlaUr 15.6.2004, 07:57
Как правильно оследить ,то что мое приложение активизировано.Возможно я делаю неправильно:

В таймере отслеживаю property Application.Active, и если оно меняется с False на True выполняю свои действия.
Возможно есть более правильное решение(например существует какое-нибудь событие).

Автор: Alex 15.6.2004, 08:09
Используй события OnActivate и OnDeactivate объекта Application, если не поможет, то за место таймера событие OnIdle объекта Application.

Автор: SlaUr 15.6.2004, 09:41
Код
Используй события OnActivate



Извените,опять чайниковский вопрос (стыдно задавать).

Если кликнуть на событии onActivate в форме , возникает следующий код:

Код

type
 TForm1 = class(TForm)
   procedure FormActivate(Sender: TObject);
   .....


procedure TForm1.FormActivate(Sender: TObject);
begin
тут пишем свой код
end;


А что я должен написать , чтобы поймать событие Application.onActivate?
(мне нужно с этим наконец-то разобраться)





Автор: Maverick 15.6.2004, 09:58
Оформляешь отдельно процедуру, называешь как хочешь, желательно. чтоб потом понял что это.... Включаешь ее в класс формы, может необязательно, но я всегда так делаю....

Будет в разделе interface
(в зависимости от целей процедуры выбери private или public)
вот такое объявление

procedure MyProcedure(Sender : TObject);

А в разделе implementation

procedure TfmMain.MyProcedure(Sender:TObject);
begin
//вот тут должен быть твой код...
end;

После этого событию OnActivate необходимо присвоить эту процедуру... Это можно сделать с Дельфийской простотой... Лучше в OnCreate главной формы, но, в принципе, где захочешь... Можно в коде главного проекта....
Project->ViewSource...

procedure TfmMain.FormCreate(Sender: TObject);
begin
Application.OnActivate := MyProcedure;
end;

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

Автор: SlaUr 15.6.2004, 10:53
Maverick Спасибо за подробный ответ.

Автор: Maverick 15.6.2004, 11:39
Всегда рад....

Вспомнил еще один способ... Может проще будет...
Есть такой компонент - ApplicationEvents на вкладке Additional.... Он, по-моему, тоже может на события Application влиять... Но я им не пользовался никогда, говорить не буду...

Автор: x77 15.6.2004, 13:04
есть ещё третий способ:

procedure MWActivateApp (var Msg: TMessage); message WM_ACTIVATEAPP;
...

Автор: SlaUr 15.6.2004, 15:08
x77 Спасибо ,вроде тоже работает.Только оно (сообщение) возникает еще и при деактивации формы (но мне это не важно).

Автор: x77 15.6.2004, 15:37
SlaUr, всё верно. wParam, он же fActive (boolean) определяет, что произошло: активация или деактивация, а второй параметр - lParam, он же dwThreadId, содержит идентификатор потока - владельца окна, которое активируется при fActive = TRUE или деактивируется, если fActive = FALSE. При смене активного окна сообщение посылается дважды: сначала приложению, которое теряет фокус (fActive = FALSE), потом приложению, которое его получает (fActive = TRUE).

строго говоря, оно не "тоже работает", а только оно и работает. если ты посмотришь код TApplication, там есть процедурина, переопределяющая WndProc. в ней прописан case Msg of. погляди на этот кейс. все события уровня приложения, то, что висит в AppEvents, отрабатываются именно в нём:

Код

       ...
       WM_ACTIVATEAPP:
         begin
           Default;
           FActive := TWMActivateApp(Message).Active;
           if TWMActivateApp(Message).Active then
           begin
             RestoreTopMosts;
             PostMessage(FHandle, CM_ACTIVATE, 0, 0)
           end
           else
           begin
             NormalizeTopMosts;
             PostMessage(FHandle, CM_DEACTIVATE, 0, 0);
           end;
         end;
         ...


а AppEvents просто присваивает собственные Notifier'ы событиям внутренней переменной Application.

так что на самом деле, способ всего один - WM_ACTIVATEAPP, всё остальное - для удобства smile.gif
Добавлено @ 15:41

пока писал, забыл, что хотел сказать. чтобы двойной сработки не было, проверяй Msg.wParam на 0 (деактивация) или >0 (активация). т.е., по сути, boolean.

Автор: bear 17.6.2004, 05:49
Вот еще пример, отслеживание запуска любого риложения через глобальную ловушку:
library Project2;


{$R *.res}

uses
windows,
SysUtils,
messages,
Dialogs,Unit2;

var
SaveExitProc : Pointer;
ClassName:array[0..255] of AnsiChar;
// дескрипторы ловушек
HKill: hHook = 0;


function CBTProc(code: integer; wParam: integer; lParam: integer): integer stdcall;
var Hour,Min,Sec,NSec:word;FlagName,FlagTime:boolean;
begin
FlagTime:=false;FlagName:=false;
if code >= 0 then begin
if Code=HCBT_CREATEWND then begin
Result:=1;
GetClassName(wParam, ClassName, 256);//На примере"Косынки"
if AnsiStrComp(ClassName, PChar('Solitaire'))=0 then FlagName:=true;
//Закрываем приложение
if FlagName then PostMessage(wParam,WM_CLOSE,0,0)end end
end;
Result:=CallNextHookEx(hKill, Code, wParam, lParam);
end;
procedure KillGame;stdcall;
begin
DestroyWindow((FindWindow(ClassName,nil)))
end;

procedure StartKill;stdcall;
// установка ловушки
begin
HKill :=SetWindowsHookEx(WH_CBT, @CBTProc, hInstance, 0);
if HKill = 0 then
MessageBox(0, 'Ловушка не установилась!', 'Ошибка', mb_Ok);
end;

procedure RemoveHookKill;stdcall;
// удаление ловушки
begin
if HKill<>0 then
begin
UnhookWindowsHookEx(HKill);
HKill := 0
end;
end;

procedure RemoveAllHooks;stdcall;
// удаление всех установленных ловушек
begin
OKBottomDlg.Free;
if HKill<>0
then UnhookWindowsHookEx(HKill);
ExitProc := SaveExitProc;
end;

exports
StartKill,
KillGame,
RemoveHookKill;

begin
// задание процедуры выхода, снимающей ловушки
SaveExitProc := ExitProc;
ExitProc := @RemoveAllHooks;
end.

Автор: x77 17.6.2004, 13:25
bear, речь шла не о запуске приложения, а об активации уже запущенного. т.е., по сути, о преключениях между главными формами разных приложений.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)