Текущий архив: 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.48 MB
Время: 0.042 c