Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];

Вниз

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

 
Антон   (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 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.076 c
1-1090240379
Dmitry
2004-07-19 16:32
2004.08.01
MDI Application


14-1089408881
deep
2004-07-10 01:34
2004.08.01
Ко дню рождения Кэтмара


8-1084862377
Sapersky
2004-05-18 10:39
2004.08.01
Использование MMX в Delphi


14-1089302982
OSokin
2004-07-08 20:09
2004.08.01
Кто из какого города?


14-1090088579
Феликс
2004-07-17 22:22
2004.08.01
Тест для опытных камекадзе





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский