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

Вниз

Управление "чужим таймером"?   Найти похожие ветки 

 
Антон   (2004-06-15 18:52) [0]

Как найти и управлять "чужим" таймером.
Суть: нашел я чужое окно, нашел его child window (собственно оно и нужно) при его работе используется таймер (нажали кнопку время пошло) надо остановить сие действо. Или бред?


 
}{enon ©   (2004-06-15 20:27) [1]

Скорее уж "или". Таймер не является визуальным объектом, у него нет Handle, а потому к нему не применимо абсолютное большинство Windows"ских функций. Хотя по идее как-то это можно сделать, т.к. где-то в памяти хранится процедура OnTimer и ее можно каким-либо образом вызвать (DLL?)


 
Rouse_ ©   (2004-06-15 20:29) [2]

> Таймер не является визуальным объектом, у него нет Handle
Сам понял что сказал?


 
Антон   (2004-06-15 21:43) [3]

2}{enon  
Из Help Win32 Dev.. Reference:


The SetTimer function creates a timer with the specified time-out value.

UINT SetTimer(

   HWND hWnd, // handle of window for timer messages
   UINT nIDEvent, // timer identifier
   UINT uElapse, // time-out value
   TIMERPROC lpTimerFunc  // address of timer procedure
  );

Так что по идее, таймер можно найти по его идентификатору. Ищу дальше.


 
Антон   (2004-06-16 18:23) [4]

Точно бред. :(


 
}{enon ©   (2004-06-17 18:17) [5]


> Rouse_ ©   (15.06.04 20:29) [2]
> > Таймер не является визуальным объектом, у него нет Handle
> Сам понял что сказал?

Ладно, у него почти нет хэндла. Если залезть в ExtCtrls (там описан класс TTimer), то можно заметить, что handle таймера объявляется в разделе private. При создании таймера handle генерируется так:
FWindowHandle := Classes.AllocateHWnd(WndProc);
а потому я не знаю, откуда можно его выдрать (стандартные функции не найдут таймер).

Постараюсь откапать еще что-нибудь, но уверенности в успехе нет...

P.S. Если что-то найете - напишите (самому стало интересно).


 
Mim1 ©   (2004-06-17 21:57) [6]

Вообщем генерится не хендл, а окно с этим хендлом. А найти его можно стандартными функциями. Вот только если например есть два таких окна, то одно от другово отличить будет сложно.


 
Cobalt ©   (2004-06-17 23:11) [7]

1) Ловить сообщение WM_Timer
2) KillTimer для всех окон со всеми идентификаторами
3) Ловить callback-функцию довольно-таки затруднительно. Я даже не представляю себе, как.


 
Rouse_ ©   (2004-06-18 11:15) [8]

Ну раз уж тут разгорелся такой жаркий спор, тогда поясню:
Управлять таймером можно через
SetTimer, KillTimer
Вся проблема в том что нужно узнать Handle окна куда посылаются сообщения и ID таймера.
Узнать это до банального просто:
Ставим Hook на WH_GETMESSAGE и ловим WM_TIMER
в данном сообщении HWND будет содержать Handle окна а WParam - ID таймера.

Код ниже:

Библиотека

library Hook;

uses
 Windows,
 Messages;

const
 MapID = "Timer Global Hook Demo";
 WM_HOOK_NOTIFY = WM_USER + 1234;

type
 PData = ^TData;
 TData = record
   AppWnd: HWND;
   OldHook: HHOOK
 end;

var
 HMap: THandle = 0;
 Data: PData = nil;

procedure DLLEntryPoint(dwReason: DWORD); stdcall;
begin
 case dwReason of
   DLL_PROCESS_ATTACH:
   begin
     HMap := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TData), MapID);
     Data := MapViewOfFile(HMap, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TData))
   end;
   DLL_PROCESS_DETACH:
   begin
     UnMapViewOfFile(Data);
     CloseHandle(HMap)
   end
 end
end;

function TimerHook(Code: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
begin
 Result:=CallNextHookEx(Data^.OldHook, Code, WParam, LParam);
 if Code = HC_ACTION then
   if TMsg(Pointer(LParam)^).message = WM_TIMER then
     SendMessage(Data^.AppWnd, WM_HOOK_NOTIFY,
       TMsg(Pointer(LParam)^).WParam, TMsg(Pointer(LParam)^).hwnd);
end;

function SetTimerHook(Wnd: HWND): BOOL; stdcall;
begin
 if Assigned(Data) then
 begin
   Data^.AppWnd := Wnd;
   Data^.OldHook := SetWindowsHookEx(WH_GETMESSAGE, @TimerHook, HInstance, 0);
   Result := Data^.OldHook <> 0
 end
 else
   Result := False
end;

function RemoveTimerHook: BOOL; stdcall;
begin
 Result := UnhookWindowsHookEx(Data^.OldHook)
end;

exports
 SetTimerHook,
 RemoveTimerHook;

begin
 DLLProc := @DLLEntryPoint;
 DLLEntryPoint(DLL_PROCESS_ATTACH)
end.


Программа:

unit uMain;

interface

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

const
 WM_HOOK_NOTIFY = WM_USER + 1234;

type
 TTimerStruct = packed record
   WindowName: ShortString;
   WindowHandle: Cardinal;
   TimerID: Cardinal;
 end;
 TTimerArray = array of TTimerStruct;

 TForm1 = class(TForm)
   ListBox1: TListBox;
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   TimersList: TStringList;
   TimerArray: TTimerArray;
   Hooked: Boolean;
 public
   procedure HookNotify(var Message: TMessage); message WM_HOOK_NOTIFY;
 end;

 function SetTimerHook(Wnd: HWND): BOOL; stdcall; external "Hook" name "SetTimerHook";
 function RemoveTimerHook: BOOL; stdcall; external "Hook" name "RemoveTimerHook";

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 TimersList := TStringList.Create;
 Hooked := SetTimerHook(Handle);
end;

procedure TForm1.HookNotify(var Message: TMessage);
var
 Buf: array of Char;
 Size: Cardinal;
 TmpStr: String;
begin  
 with Message do
 begin
   Result := 0;
   if TimersList.IndexOfName(IntToStr(LParam)) > -1 then Exit;
   TimersList.Values[IntToStr(LParam)] := IntToStr(WParam);
   SetLength(TimerArray, Length(TimerArray) + 1);
   Size := GetWindowTextLength(LParam);
   SetLength(Buf, Size);
   Inc(Size);
   GetWindowText(LParam, @Buf[0], Size);
   TmpStr := String(Buf);
   if TmpStr = "" then TmpStr := "Без заголовка";
   while TmpStr[Length(TmpStr)] = #0 do Delete(TmpStr, Length(TmpStr), 1);
   with TimerArray[Length(TimerArray) - 1] do
   begin
     WindowName := TmpStr;
     WindowHandle := LParam;
     TimerID := WParam;
   end;
   ListBox1.Items.Add(Format("Окно: %s, хэндл окна: %d, ID таймера: %d",
       [TmpStr, LParam, WParam]));
 end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 if Hooked then RemoveTimerHook;
 TimersList.Free;
end;

end.


---
Желаю успехов



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

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

Наверх




Память: 0.5 MB
Время: 0.045 c
14-1089669484
KilkennyCat
2004-07-13 01:58
2004.08.01
Notebook


3-1089358855
==x==
2004-07-09 11:40
2004.08.01
Ado-dBase не работает после переустановки системы


3-1089285508
Punker
2004-07-08 15:18
2004.08.01
Запрос для удаления дублирующихся записей


14-1090117107
Думкин
2004-07-18 06:18
2004.08.01
С днем рождения! 18 июля


14-1089785501
sniknik
2004-07-14 10:11
2004.08.01
Кому нравятся командировки?