Форум: "WinAPI";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];
ВнизJournalRecord Найти похожие ветки
← →
OSokin © (2004-04-24 21:02) [0]Извините за дурацкий вопрос, но как сделать запись и воспроизведение с помощью этих функций?
← →
Игорь Шевченко © (2004-04-24 23:18) [1]В MSDN Magazine RE была неплохая демка на эту тему, там же приводилась ссылка на пример.
← →
OSokin © (2004-04-26 18:38) [2]Да у меня у самого есть две демки, но исходников нет... Там компонент используется. Хотя, поищу на Torry.
← →
Игорь Шевченко © (2004-04-26 23:13) [3]Разбирайся:
unit JournalHooks;
interface
uses
Windows, Classes;
type
TJournalHook = (jhJournalPlayback, jhJournalRecord);
//Строка журнала
PEventItem = ^TEventItem;
TEventItem = record
Event: TEventMsg;
Code: Integer;
end;
//Журнал событий
TEventsJournal = class
private
FList: TList;
function GetEventsCount(): Integer;
function GetItems(I: Integer): PEventItem;
procedure SetItems(I: Integer; const Value: PEventItem);
public
constructor Create();
destructor Destroy(); override;
property Items[I: Integer]: PEventItem read GetItems write SetItems; default;
procedure Clear();
function IsEmpty(): Boolean;
property EventsCount: Integer read GetEventsCount;
function Add(AItem: PEventItem): Integer;
procedure SaveToFile(const AFileName: String);
procedure LoadFromFile(const AFileName: String);
end;
var
Journal: TEventsJournal;
CurrentEventIndex: Integer;
procedure InstallFilter(AJournalHook: TJournalHook; ACode: Boolean);
procedure InitHookStates();
implementation
uses
SysUtils, Messages, StrUtils, MarsMessages, Forms;
var
// Hook Handles
hhookHooks: array[TJournalHook] of THandle;
// State Table of my hooks
HookStates: array[TJournalHook] of Boolean = (False, False);
lpfnHookProcs: array[TJournalHook] of TFNHookProc = (nil, nil);
const
HookCodes: array[TJournalHook] of Integer = (
WH_JOURNALPLAYBACK,
WH_JOURNALRECORD );
function DecodeHookAction(const ACode: Integer): String;
const
HookCodes : array[HC_ACTION..HC_SYSMODALOFF] of String = (
"HC_ACTION", "HC_GETNEXT", "HC_SKIP", "HC_NOREMOVE", "HC_SYSMODALON",
"HC_SYSMODALOFF" );
begin
if ACode < HC_ACTION then
Result := "**less than zero"
else if ACode > High(HookCodes) then
Result := Format("Unknown_0x%.x", [ACode])
else
Result := HookCodes[ACode];
end;
procedure InstallFilter(AJournalHook: TJournalHook; ACode: Boolean);
const
MessArr: array[TJournalHook] of String =
("Идет воспроизведение журнала событий",
"Идет запись журнала событий (остановить запись - Shift+F11)");
begin
if ACode then begin
hhookHooks[AJournalHook] := SetWindowsHookEx(HookCodes[AJournalHook],
lpfnHookProcs[AJournalHook], hInstance, 0);
if hhookHooks[AJournalHook] = 0 then
RaiseLastWin32Error();
HookStates[AJournalHook] := True;
SendMessage(Application.MainForm.Handle, WM_SHOWSTATUS,
0, LPARAM(PChar(MessArr[AJournalHook])));
end else begin
UnhookWindowsHookEx(hhookHooks[AJournalHook]);
HookStates[AJournalHook] := False;
SendMessage(Application.MainForm.Handle, WM_SHOWSTATUS, 0, 0);
end;
end;
procedure InitHookStates();
var I: TJournalHook;
begin
for I:=Low(TJournalHook) to High(TJournalHook) do
HookStates[I] := False;
end;
procedure WriteToFile(const AFileName, S: String);
var
Exists: Boolean;
F: TextFile;
begin
Exists := FileExists(AFileName);
AssignFile(F, AFileName);
try
if Exists then
Append(F)
else
Rewrite(F);
WriteLn(F, S);
finally
CloseFile(F);
end;
end;
var
dwTimeAdjust: DWORD = 0;
function JournalPlaybackFunc(ACode: Integer; AwParam: WPARAM; AlParam: LPARAM): LRESULT; stdcall;
var
lpEvent: PEventMsg;
begin
if ACode > 0 then begin
if Journal.IsEmpty() or HookStates[jhJournalRecord] then begin
InstallFilter(jhJournalPlayback, False);
//Нет записей в журнале или идет запись журнала
Result := CallNextHookEx(hhookHooks[jhJournalPlayback], ACode, AWParam, ALParam);
Exit;
end;
//Это первый элемент списка?
if CurrentEventIndex = 0 then
dwTimeAdjust := GetTickCount() - Journal[CurrentEventIndex].Event.time;
if ACode = HC_SKIP then begin
//Список обработан?
if CurrentEventIndex >= Pred(Journal.EventsCount) then begin
InstallFilter(jhJournalPlayback, False);
CurrentEventIndex := 0;
end else begin
Inc(CurrentEventIndex);
end;
end else if ACode = HC_GETNEXT then begin
lpEvent := PEventMsg(AlParam);
lpEvent^.message := Journal[CurrentEventIndex].Event.message;
lpEvent^.paramL := Journal[CurrentEventIndex].Event.paramL;
lpEvent^.paramH := Journal[CurrentEventIndex].Event.paramH;
lpEvent^.time := Journal[CurrentEventIndex].Event.time + dwTimeAdjust;
Result := lpEvent^.time - GetTickCount();
if Result < 0 then begin
Result := 0;
lpEvent^.time := GetTickCount();
end;
Exit;
end;
end;
Result := CallNextHookEx(hhookHooks[jhJournalPlayback], ACode, AWParam, ALParam);
end;
продолжение следует
← →
Игорь Шевченко © (2004-04-26 23:14) [4]продолжение
function JournalRecordFunc(ACode: Integer; AwParam: WPARAM; AlParam: LPARAM): LRESULT; stdcall;
var
lpEvent: PEventMsg;
EventItem: PEventItem;
begin
if ACode >= 0 then begin
//
// Skip recording while playing back
// This is not a limitation of the hooks.
// This is only because of the simple event storage used in this example
//
if HookStates[jhJournalPlayback] then begin
Result := 0;
Exit;
end;
lpEvent := PEventMsg(AlParam);
// Stop recording ?
if (lpEvent^.message = WM_KEYDOWN) and
(LOBYTE(lpEvent^.paramL) = VK_F11) and
(GetKeyState(VK_SHIFT) < 0) then begin
InstallFilter(jhJournalRecord, False);
Result := 0;
Exit;
end;
New(EventItem);
with EventItem^, EventItem^.Event do begin
message := lpEvent^.message;
paramL := lpEvent^.paramL;
paramH := lpEvent^.paramH;
time := lpEvent^.time;
hwnd := lpEvent^.hwnd;
Code := ACode;
end;
Journal.Add(EventItem);
with lpEvent^ do
WriteToFile("default.jrn", Format("0x%.8x;0x%.8x;0x%.8x;%d;0x%.8x;%s",
[message, paramL, paramH, time, hwnd, DecodeHookAction(ACode)]));
Result := 0;
Exit;
end;
Result := CallNextHookEx(hhookHooks[jhJournalRecord], ACode, AWParam, ALParam);
end;
{ TEventsJournal }
function TEventsJournal.Add(AItem: PEventItem): Integer;
begin
Result := FList.Add(AItem);
end;
procedure TEventsJournal.Clear();
var
I: Integer;
EI: PEventItem;
begin
for I:=Pred(FList.Count) downto 0 do begin
EI := PEventItem(FList[I]);
Dispose(EI);
FList.Delete(I);
end;
end;
constructor TEventsJournal.Create();
begin
FList := TList.Create();
end;
destructor TEventsJournal.Destroy();
begin
Clear();
FList.Free();
inherited;
end;
function TEventsJournal.GetEventsCount(): Integer;
begin
Result := FList.Count;
end;
function TEventsJournal.IsEmpty(): Boolean;
begin
Result := FList.Count = 0;
end;
procedure TEventsJournal.SaveToFile(const AFileName: String);
var
I: Integer;
F: TextFile;
begin
AssignFile(F, AFileName);
try
Rewrite(F);
for I:=0 to Pred(EventsCount) do
with Items[I]^, Items[I]^.Event do
Writeln(F, Format("0x%.8x;0x%.8x;0x%.8x;%d;0x%.8x;%s",
[message, paramL, paramH, time, hwnd, DecodeHookAction(Code)]));
finally
CloseFile(F);
end;
end;
function HexStrToDec(const S: String): Longint;
var
HexStr: String;
L: Integer;
begin
L := Length(S);
if Copy(S, 1, 2) = "0x" then begin
HexStr := Copy(S, 3, L -2 );
HexStr := "$" + HexStr;
end;
Result := StrToIntDef(HexStr, 0);
end;
procedure TEventsJournal.LoadFromFile(const AFileName: String);
var
F: TextFile;
S, W: String;
EI: PEventItem;
begin
Clear();
if not FileExists(AFileName) then
raise Exception.CreateFmt("Файл %s не найден", [AFileName]);
AssignFile(F, AFileName);
try
Reset(F);
while not EOF(F) do begin
ReadLn(F, S);
New(EI);
try
W := ExtractDelimited(1, S, [";"]);
EI^.Event.message := HexStrToDec(W);
W := ExtractDelimited(2, S, [";"]);
EI^.Event.paramL := HexStrToDec(W);
W := ExtractDelimited(3, S, [";"]);
EI^.Event.paramH := HexStrToDec(W);
W := ExtractDelimited(4, S, [";"]);
EI^.Event.time := StrToInt(W);
W := ExtractDelimited(5, S, [";"]);
EI^.Event.hwnd := HexStrToDec(W);
except
Dispose(EI);
end;
Add(EI);
end;
finally
CloseFile(F);
end;
end;
function TEventsJournal.GetItems(I: Integer): PEventItem;
begin
Result := PEventItem(FList[I]);
end;
procedure TEventsJournal.SetItems(I: Integer; const Value: PEventItem);
begin
with Items[I]^ do begin
Event := Value^.Event;
Code := Value^.Code;
end;
end;
initialization
lpfnHookProcs[jhJournalPlayback] := JournalPlaybackFunc;
lpfnHookProcs[jhJournalRecord] := JournalRecordFunc;
Journal := TEventsJournal.Create;
finalization
Journal.Free;
end.
Использование:procedure TfMain.JournalRecordActionExecute(Sender: TObject);
begin
Journal.Clear();
InstallFilter(jhJournalRecord, True);
end;
procedure TfMain.JournalPlaybackActionExecute(Sender: TObject);
begin
CurrentEventIndex := 0;
InstallFilter(jhJournalPlayback, True);
end;
procedure TfMain.JournalLoadActionExecute(Sender: TObject);
begin
OpenDialog.InitialDir := FOptions.WorkingDir;
if OpenDialog.Execute() then
Journal.LoadFromFile(OpenDialog.FileName);
end;
procedure TfMain.JournalSaveActionExecute(Sender: TObject);
begin
SaveDialog.InitialDir := FOptions.WorkingDir;
if SaveDialog.Execute() then
Journal.SaveToFile(SaveDialog.FileName);
end;
procedure TfMain.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.message = WM_CANCELJOURNAL then begin
SendMessage(Application.MainForm.Handle, WM_SHOWSTATUS, 0, 0);
InitHookStates();
Handled := True;
end;
end;
← →
OSokin © (2004-05-03 13:35) [5]Спасибо огромное!!!
← →
Andrushk (2004-05-21 18:09) [6]Извините что влезаю в чужую тему,но мне показалось что мой вопрос близок ней.
Мне надо Журнал событий (поправте меня если я неправильно называю то что отображается в SystemTools->EventViewer) записывать в текстовый файл. Т.е., появилось новое событие в журнале - записать в файл. Где можно почитать на эту тему поподробнее?
← →
Cobalt © (2004-05-21 19:01) [7]http://delphimaster.net/view/7-1083574310/
← →
OSokin © (2004-06-08 16:55) [8]Кстати, а что за MarsMessages???
← →
Игорь Шевченко © (2004-06-08 18:13) [9]OSokin © (08.06.04 16:55)
> Кстати, а что за MarsMessages???
Unit, где описаны пользовательские сообщения. Можно выбросить
← →
OSokin © (2004-06-13 17:40) [10]А где его можно достать (Torry etc.)?
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.033 c