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

Вниз

Разработка универсального логгера всех действий на форме   Найти похожие ветки 

 
>|<   (2011-02-25 15:48) [0]

Суть задачи: есть много форм с разнообразными обработчиками, как то OnClick, OnChange, OnPropertyChanged etc.
Хочу разработать такого предка для всех этих форм, который будет встраивать в эти обработчики свой логгер.
Подскажите, как лучше это сделать.
На ум приходит только перехват сообщений, и в их очередь встроить сообщения моему логгеру с описанием всех действий.

Поделитесь соображениями по этому поводу, как кто реализовал бы этот механизм.


 
Jeer ©   (2011-02-25 15:53) [1]

В голове нужно все проигрывать :)


 
Dimka Maslov ©   (2011-02-25 15:57) [2]

Событие не всегда возникает как реакция на сообщение


 
Омлет ©   (2011-02-25 16:03) [3]

Кому такой лог нужен будет? Необходимо логировать только то, что необходимо.


 
>|<   (2011-02-25 16:10) [4]


> Кому такой лог нужен будет

мне такой лог нужен, чтобы воспроизвести последовательность действий, которые привели к возникновению ошибки


> В голове нужно все проигрывать :)

Проиграйте, плиз. И потом сюда черкните Ваши соображения.
Заранее признателен:)


 
oxffff ©   (2011-02-25 16:17) [5]


> >|<   (25.02.11 15:48)  
> Суть задачи: есть много форм с разнообразными обработчиками,
>  как то OnClick, OnChange, OnPropertyChanged etc.
> Хочу разработать такого предка для всех этих форм, который
> будет встраивать в эти обработчики свой логгер.
> Подскажите, как лучше это сделать.
> На ум приходит только перехват сообщений, и в их очередь
> встроить сообщения моему логгеру с описанием всех действий.
>
>
> Поделитесь соображениями по этому поводу, как кто реализовал
> бы этот механизм.


Events не обязаны быть напрямую связаны с сообщениями.
Перехватывать обработчики run time. То есть переназначить при создании формы на логер.


 
clickmaker ©   (2011-02-25 16:20) [6]

> который будет встраивать в эти обработчики свой логгер

руками не встроить одну строчку?
LogMethodCall(sender, "OnClick", ...);


 
>|<   (2011-02-25 16:26) [7]


> руками не встроить одну строчку?
> LogMethodCall(sender, "OnClick", ...);

так и думал делать вначале.
Но как представил себе, что надо пройтись по всем формам(порядка 100 штук)
и на каждой форме десятки обработчиков, то как-то желание пропало)


> Events не обязаны быть напрямую связаны с сообщениями.
> Перехватывать обработчики run time. То есть переназначить
> при создании формы на логер.

Вот это уже интересней.
Покажите, плиз, на примере, как перехватить обработчики в runtime?


 
Dimka Maslov ©   (2011-02-25 16:33) [8]

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


 
oxffff ©   (2011-02-25 16:37) [9]


> Вот это уже интересней.
> Покажите, плиз, на примере, как перехватить обработчики
> в runtime?


Я бы написал универсальный. Но писать лень. Думай свой головой.


 
asail ©   (2011-02-25 17:09) [10]

Можно создать одну базовую форму, во всех ее обработчиках прописать лог, а все остальные формы наследовать от базовой...
Типа такого:

unit BaseFormU;

TBaseForm = class(TForm)
 ...
 procedure FormClose(Sender: TObject; var Action: TCloseAction);
 ...
end;
...

procedure TBaseForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 Log(Self.ClassName, "OnClose called");
...

unit MyFormU;

TMyForm = class(TBaseForm)
 ...
 procedure FormClose(Sender: TObject; var Action: TCloseAction);
 ...
end;

procedure TMyForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 inherited;
...


Идея, думаю, понятна...


 
Dimka Maslov ©   (2011-02-25 17:21) [11]


> Можно создать одну базовую форму, во всех ее обработчиках
> прописать лог, а все остальные формы наследовать от базовой.
> ..


Обработчик события не является виртуальным методом. В потомке о нём может быть ничего неизвестно.


 
>|<   (2011-02-25 18:45) [12]


> Идея, думаю, понятна...

непонятно только, как перехватывать нажатия кнопок, которые появятся в наследнике...


 
asail ©   (2011-02-25 18:55) [13]


> >|<   (25.02.11 18:45) [12]

> непонятно только, как перехватывать нажатия кнопок

Э... А этого в ТЗ небыло. :)


 
asail ©   (2011-02-25 19:00) [14]


> Dimka Maslov ©   (25.02.11 17:21) [11]

Дык, работает...


 
_Юрий   (2011-02-25 19:13) [15]

Где-нибудь на OnShow формы-предка пробежаться по компонентам и их событиям, и переприсвоить на свои, не забыв запомнить для дальнейшего вызова старые события


 
_Юрий   (2011-02-25 19:24) [16]

Но в общем то предок тут не нужен, лучше сделать это снаружи.


 
>|<   (2011-02-25 19:40) [17]


> Где-нибудь на OnShow формы-предка пробежаться по компонентам
> и их событиям, и переприсвоить на свои, не забыв запомнить
> для дальнейшего вызова старые события


1. запомнили все обработчики
2. присвоили универсальный.
3. юзер нажимает на кнопку.
4. вызвали универсальный обработчик
5. обратно присвоили все старые обработчики
6. запомнили, что нажимал юзер
7. вызвали старый обработчик.

представляю себе эти тормоза...


 
_Юрий   (2011-02-25 20:01) [18]

1. запомнили все обработчики
2. присвоили универсальный.
3. юзер нажимает на кнопку.
4. вызвали универсальный обработчик
5. вызвали старый обработчик.

Где тут тормоза? От присвоения двух указателей в переменные?


 
Renderer   (2011-02-25 23:23) [19]

> Dimka Maslov ©   (25.02.11 17:21) [11] Обработчик события не является виртуальным методом. В потомке о нём может быть ничего неизвестно.

Однако, іnherited работает.


 
Гость   (2011-02-26 00:08) [20]

достаточно, имхо, логировать смену активного контрла, клик мышки и нажатие клавиш
для воспроизведения действий юзера мне в 99% хватает


 
asail ©   (2011-02-26 00:32) [21]


> _Юрий   (25.02.11 19:13) [15]
> Где-нибудь на OnShow формы-предка пробежаться по компонентам
> и их событиям, и переприсвоить на свои

Тута, имхо, загвоздка есть... У разных событий обработчики разного типа. У кого просто TNotifyEvent, а у кого TMouseEvent например... Как их всех учесть? Все с разным набором параметров. Имхо, не взлетит...


 
Inovet ©   (2011-02-26 00:45) [22]

Так может для этой задачи логировать надо весь ввод на уровне приложения а не обработчиков во всех дырах, что там может быть - клавиатура, устройство указания из обычных?


 
_Юрий   (2011-02-26 10:41) [23]


> asail ©   (26.02.11 00:32) [21]
>
>
> > _Юрий   (25.02.11 19:13) [15]
> > Где-нибудь на OnShow формы-предка пробежаться по компонентам
> > и их событиям, и переприсвоить на свои
>
> Тута, имхо, загвоздка есть... У разных событий обработчики
> разного типа. У кого просто TNotifyEvent, а у кого TMouseEvent
> например... Как их всех учесть? Все с разным набором параметров.
>  Имхо, не взлетит...


Абсолютно все события не интересуют, интересуют только некоторые, несколько штук (от мыши, от клавиатуры), чьи сигнатуры заранее известны.

Можно просто их перебрать.


 
>|<   (2011-03-15 19:28) [24]

Вот решил в коде реализовать свою идею, но не до конца понимаю, как ее закончить из-за пробелов в языке программирования

TMethodArray = class
 private
   procedure SetValue(const Name : string; Value : TMethod);
   function GetValue(const Name: string): TMethod;
 public
   property Items[const Name : string] : TMethod read GetValue write SetValue; default;
 end;

 TModuleForm = class(TForm)
   procedure LoggedClick(Sender:TObject);
 protected
   procedure Loaded; override;
   procedure DoClose(var Action: TCloseAction); override;
 private
   FModuleName: string;
   FMethods:TMethodArray;
 public
   property ModuleName :string read FModuleName write FModuleName;
 end;

implementation

procedure TModuleForm.Loaded;
var i:integer;
begin
 inherited;
 
 for I := 0 to ComponentCount - 1 do
   if GetPropInfo(Components[i],"OnClick")<>nil then
   begin
     FMethods[Components[i].Name] := GetMethodProp(Components[i],"OnClick");
     SetMethodProp(Components[i],"OnClick", Self.LoggedClick);здесь ошибка! как правильно присвоить ссылку на новый метод
   end;
 {$IFDEF LOG}
 DMMain.LogEvent(self, "Форма ""+self.Caption+"" загружена.");
 {$ENDIF}
end;

procedure TModuleForm.LoggedClick(Sender: TObject);
begin
 {$IFDEF LOG}
 DMMain.LogEvent(Sender, "Метод "+MethodName(FMethods[GetNameOrClassName(Sender)].Code)+" объекта "+GetNameOrClassName(Sender)+" вызван.");
 {$ENDIF}
//TODO: Как вызвать родной метод?
end;

{ TMethodArray }

function TMethodArray.GetValue(const Name: string): TMethod;
begin
Result := Items[Name];
end;

procedure TMethodArray.SetValue(const Name: string; Value: TMethod);
begin
 if Items[Name]<>Value then
   Items[Name]:=Value;
end;



Кто в курсе, подскажите ответы на вопросы, выделенные жирным шрифтом в коде.
Заранее благодарен.


 
>|<   (2011-03-15 19:39) [25]

после тестирования этой версии вылезли ошибки в классе TMethodArray
в методе procedure SetValue(const Name : string; Value : TMethod);

в цикле
на этой строке
FMethods[Components[i].Name] := GetMethodProp(Components[i],"OnClick");
вылетает Stack Overflow


 
>|<   (2011-03-16 15:43) [26]

Докладываю:
универсальный логгер реализован.
Спасибо всем, кто помогал в этих ветках
http://delphimaster.net/view/2-1300265235/
http://delphimaster.net/view/2-1300265235/



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

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

Наверх





Память: 0.56 MB
Время: 0.004 c
15-1300321466
Дмитрий Тимохов
2011-03-17 03:24
2011.07.03
Нашел по рекламе на delphimaster.ru


15-1300200658
OW
2011-03-15 17:50
2011.07.03
А помните тут кто-то скрины раб столов собирал?


15-1300391272
vajo
2011-03-17 22:47
2011.07.03
Проблема со звуком на компе.


15-1300743002
Юрий
2011-03-22 00:30
2011.07.03
С днем рождения ! 22 марта 2011 вторник


2-1301297993
aka
2011-03-28 11:39
2011.07.03
Пазлы





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский