![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Автоматический LOG программы [D7, Win2k, WinXP]
Shaman_ © (2006-08-08 11:20:00)Стоит задача разработать универсальный механизм ведения истории работы с программой. Необходимо на всех формах приложения отслеживать нажатия всех TButton и заносить в историю запись вида:
Открыта форма "TForm.Caption"
На форме "TForm.Caption" нажата клавиша "TButton.Caption"
и.т.д.
Думаю как это лучше организовать одним универсальным методом? Добавлять к кажому TObject событие не подойдет- форм 90 штук, элементов форм - не поддается подсчету. Наверняка уже многие сталкивались и есть свои наработки в этой области.
Гутан Орангович (2006-08-09 10:38:00) [1]Каждому овощу свое время. В том числе и OnMessage и TApplicationEvent.
Не имеет смысла говорить о том, что один метод лучше другого.
Это всего лишь дело вкусовых рецепторов каждого.
Loginov Dmitry_ (2006-08-09 10:32:00) [2]
> и в своем, после нужных действий вызывать стандартный
Что еще за "стандартный" обработчик? Таких здесь нету. Если имеется ввиду старый обработчик, тогда ладно. Но предпочтительнее все же не вешать собственный обработчик, а использовать механизм ApplicationEvents.
Гутан Орангович (2006-08-09 09:28:00) [3]
> Loginov Dmitry © (09.08.06 07:51) [15]
> > Гутан Орангович (09.08.06 02:01) [14]> Своя обработка
> OnMessage совершенно не мешает иметь > сколько угодно других
> обработчиков.А самому проверить не судьба?
И проверять нечего. Это тривиально.
StriderMan (2006-08-09 09:04:00) [4]
> Loginov Dmitry © (09.08.06 07:51) [15]
можно же сохранить указатель на стандартный обработчик перед переопределением OnMessage, и в своем, после нужных действий вызывать стандартный. Чем это плохо?
Loginov Dmitry (2006-08-09 07:51:00) [5]> Гутан Орангович (09.08.06 02:01) [14]
> Своя обработка OnMessage совершенно не мешает иметь
> сколько угодно других обработчиков.
А самому проверить не судьба?
Гутан Орангович (2006-08-09 02:01:00) [6]
> Loginov Dmitry © (08.08.06 17:46) [10]
> > Application.OnMessage := MsgHandler;Мой совет: никогда
> так не делай. Для этих целей в Дельфи есть компонент TApplicationEvents.
>
> Loginov Dmitry © (08.08.06 18:37) [12]
> Вот именно! Только 1. Это ни есть гуд, так как может понадобиться
> обработка OnMessage в совершенно разных местах программы.
> А если ты делашь такApplication.OnMessage := MsgHandler;
> то все компоненты TApplicationEvents перестают работать.
>
Своя обработка OnMessage совершенно не мешает иметь сколько угодно других обработчиков.
Shaman_ (2006-08-08 18:48:00) [7]Можно выстроить цепочку на передачу сообщения от одного обработчика к другому, но в целом согласен, лишняя, ненужная замороченность получается
Loginov Dmitry (2006-08-08 18:37:00) [8]Вот именно! Только 1. Это ни есть гуд, так как может понадобиться обработка OnMessage в совершенно разных местах программы. А если ты делашь так
Application.OnMessage := MsgHandler;
то все компоненты TApplicationEvents перестают работать.
Shaman_ (2006-08-08 18:02:00) [9]Loginov Dmitry © (08.08.06 17:46) [10]
Опасения основаны на том, что обработчик может быть только 1? Или может есть еще какие негативные стороны?
Loginov Dmitry (2006-08-08 17:46:00) [10]> Application.OnMessage := MsgHandler;
Мой совет: никогда так не делай. Для этих целей в Дельфи есть компонент TApplicationEvents.
Loginov Dmitry (2006-08-08 17:44:00) [11]А я вот решил сабж с помощью читерства :)
unit BntLoggerUnit;
{$define UserHook}
interface
uses
Windows, Messages, SysUtils, StdCtrls, Buttons, ComCtrls;
{$ifdef UserHook}
type
TMyButton = class(TButton)
public
procedure Click; override;
end;
TMySpeedButton = class(TSpeedButton)
public
procedure Click; override;
end;
TMyToolButton = class(TToolButton)
public
procedure Click; override;
end;
TButton = class(TMyButton);
TSpeedButton = class(TMySpeedButton);
TToolButton = class(TMyToolButton);
procedure WriteToLog(AText: string);
{$endif UserHook}
implementation
{$ifdef UserHook}
procedure WriteToLog(AText: string);
begin
// Здесь выполняй запись в лог-файл
end;
{ TMyButton }
procedure TMyButton.Click;
begin
inherited;
Beep;
WriteToLog(Caption);
end;
{ TMySpeedButton }
procedure TMySpeedButton.Click;
begin
inherited;
Beep;
WriteToLog(Caption);
end;
{ TMyToolButton }
procedure TMyToolButton.Click;
begin
inherited;
Beep;
WriteToLog(Caption);
end;
{$endif UserHook}
end.
Добавь имя данного модуля в список USES секции INTERFACE каждого модуля формы. Оно должно быть в конце списка.
P.S.: enjoy ;)
Shaman_ (2006-08-08 17:35:00) [12]DiamondShark [6]
Чем может быть полезен это уже вопрос творческий, а не программерский. В том числе- clickmaker © (08.08.06 16:56) [7] :)
В общем вот пример как реализовал. Все не буду расписывать, просто пишу пример перехвата Caption нажимаемых пользователем TButton
Все делаем через обработку сообщений:
...
private
procedure MsgHandler(var Msg:TMsg);
...
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := MsgHandler;
end;
procedure TForm1.MsgHandler(var Msg:TMsg);
var
CaprionBuffer: PChar;
begin
case Msg.message of
//Перехват нажатия на TButton
WM_LBUTTONDOWN:
begin
//Получаем Caption кнопки
GetMem(lpBuffer,255);
GetWindowText(msg.hwnd,CaprionBuffer,255);
//Вот собственно и все
ShowMessage('Перехвачено нажатие кнопки "'+CaprionBuffer+'"');
end;
//Если нужно перехватить другое действие пользователя
//то соответственно обрабатываем здесь нужное сообщение
...
end;
end;
Это естественно пример. В реале весь код получился на ~300 строк и еще не дописан :)
clickmaker (2006-08-08 16:56:00) [13]
> DiamondShark © (08.08.06 16:46) [6]
> Интересно, а чем такой лог может быть полезен?
никак не могут прищучить юзера, который лажает, а потом валит все на прграммеров, наверно )
DiamondShark (2006-08-08 16:46:00) [14]Интересно, а чем такой лог может быть полезен?
Loginov Dmitry (2006-08-08 15:38:00) [15]Еще вариант: использовать наследование форм. Обработку сообщений выполнять в процедуре WndProc(), которая объявляется так:
TParentForm = class(TForm)
.....
protected
procedure WndProc(var Message: TMessage); override;
end;
(Вообще, полезая вещь "наследование форм", сильно сокращает объем кода)
StriderMan (2006-08-08 12:40:00) [16]
> Shaman_ © (08.08.06 12:29) [2]
отпишитесь пожалуйста как сделаете. Интересный вопрос.
Ketmar (2006-08-08 12:37:00) [17]повесить хук и ловить всё, что надо.
Shaman_ (2006-08-08 12:29:00) [18]1. - Немного не то
2. - В этом направлении сейчас и копаю
StriderMan (2006-08-08 11:24:00) [19]способы:
1. сделать свой компонент от TButton, добавив запись в лог. Написать программулину, которая перелопатит в проекте все TButton в *.pas и *.dfm.
2. копать в сторону Application.OnMessage