Сергей Перовский дата публикации 20-02-2003 11:47 Обмен текстовой информацией между модулями проекта
При написании программ я всегда старался четко отделять
пользовательский интерфейс от алгоритма задачи.
С появленинием в Delphi ActionList'а стало гораздо проще писать
алгоритмическую часть без оглядки на структуру пользовательского
интерфейса.
Но осталась проблема отображения информации: в некоторой точке
программы
требуется вывести сообщение, а куда выводить неизвестно.
Разработчик интерфейса еще не решил, что выводить в StatusBar, что в
MessageBox. Какую отладочную информацию поместить в логфайл.
Я решаю эту проблему следующим образом — во всех существенных точках
алгоритма вызывается процедура ToLog.
Два ее параметра определяют текст сообщения и ее предназначение. 256
"каналов" должны быть поделены между сообщениями об ошибках,
отладочной информацией, информационными сообщениями и результатами.
Это
единственное соглашение,
которое должны соблюдать все участники проекта. Разработчик интерфейса
решает для компонента - сообщения из каких каналов он должен
отображать и регистрирует соответствующий объект (Log). "Расчетные"
модули
могут не ссылаться на модули с описанием форм и диалогов.
Единственный модуль, через который они общаются - и на который обязаны
ссылаться (причем в implementation разделе) это uLogs.
Модуль uLogs предназначен для передачи текстовых сообщений между
различными модулями, визуальными компонентами и файлами.
Для разделения сообщений различных типов введено 256 "каналов".
Каждому сообщению должен быть сопоставлен номер канала,
определяющий цель сообщения и технологию его обработки.
Для протоколирования и/или визуализации сообщений предназначены
специальные объекты "Логи" - наследники базового объекта TLog.
Каждый "лог" может обрабатывать все сообщения из заданного множества
каналов. Логи разных типов различаются способом фиксации или
отображения информации.
В модуле описано 5 различных наследников абстрактного класса TLog.
По их образцу легко создать классы для других способов обработки
сообщений.
Скачать uLogs.zip (2.3 K)
unit uLogs;
interface
uses Classes,Controls,StdCtrls,ComCtrls,Forms;
procedure ToLog(Channel:byte;Mes:String);
Type
TChannels = set of byte;
TLog = class
protected
FChannels:TChannels;
procedure InternalToLog(Channel:byte;Mes:String);virtual;abstract;
public
procedure SetChannel(Channel:byte;Status:boolean);
procedure toLog(Channel:byte;Mes:String);
constructor Create(AChannels:TChannels);
property Channels:TChannels read FChannels write FChannels;
end;
TStringsLog = class(TLog)
FStrings:TStrings;
procedure InternalToLog(Channel:byte;Mes:String);override;
constructor Create(AChannels:TChannels;AStrings:TStrings);
end;
TFileLog = class(TLog)
FFile:Text;
procedure InternalToLog(Channel:byte;Mes:String);override;
constructor Create(AChannels:TChannels;FileName:String);
end;
TCaptionLog = class(TLog)
FControl:TControl;
procedure InternalToLog(Channel:byte;Mes:String);override;
constructor Create(AChannels:TChannels;AControl:TControl);
end;
TStatusBarLog = class(TLog)
FStatusPanel:TStatusPanel;
procedure InternalToLog(Channel:byte;Mes:String);override;
constructor Create(AChannels:TChannels;AStatusPanel:TStatusPanel);
end;
TMessageBoxLog = class(TLog)
fCaption:String;
fFlags: Longint;
procedure InternalToLog(Channel:byte;Mes:String);override;
constructor Create(AChannels:TChannels;Caption:String;Flags: Longint);
end;
function SetLog(ALog:TLog):word;
function SetNamedLog(ALog:TLog;Name:string):integer;
function ReSetNamedLog(Name:string):integer;
implementation
uses Windows;
var LogList:TStrings;
lLog:TLog;
procedure ToLog(Channel:byte;Mes:String);
var i:integer;
Begin
if LogList.Count<1 then exit;
for i:=0 to LogList.Count-1 do
TLog(LogList.Objects[i]).toLog(Channel,Mes);
End;
function SetLog(ALog:TLog):word;
Begin
result:=LogList.AddObject('',ALog);
End;
function SetNamedLog(ALog:TLog;Name:string):integer;
var i:integer;
Begin
result:=-1;
i:=LogList.IndexOf(Name);
if i=-1 then result:=LogList.AddObject(Name,ALog);
End;
function ReSetNamedLog(Name:string):integer;
var i:integer;
Begin
result:=LogList.IndexOf(Name);
if result<>-1 then LogList.Delete(result);
End;
constructor TLog.Create(AChannels: TChannels);
begin
FChannels:=AChannels;
end;
procedure TLog.SetChannel(Channel: byte; Status: boolean);
begin
if status
then FChannels:=FChannels+[channel]
else FChannels:=FChannels-[channel];
end;
procedure TLog.toLog(Channel: byte; Mes: String);
begin
if (Channel in FChannels) then InternalToLog(Channel,Mes);
end;
constructor TStringsLog.Create(AChannels: TChannels; AStrings: TStrings);
begin
inherited Create(AChannels);
FStrings:=AStrings;
end;
procedure TStringsLog.InternalToLog(Channel: byte; Mes: String);
begin
FStrings.Add(Mes);
end;
constructor TFileLog.Create(AChannels: TChannels; FileName: String);
begin
inherited Create(AChannels);
AssignFile(FFile,FileName);
Rewrite(FFile);
Writeln(FFile, 'Log file start');
CloseFile(FFile);
end;
procedure TFileLog.InternalToLog(Channel: byte; Mes: String);
begin
Append(fFile);
Writeln(fFile, mes);
Flush(fFile);
CloseFile(fFile);
end;
constructor TCaptionLog.Create(AChannels: TChannels; AControl: TControl);
begin
inherited Create(AChannels);
FControl:=AControl;
end;
procedure TCaptionLog.InternalToLog(Channel: byte; Mes: String);
begin
TLabel(FControl).Caption:=Mes;
end;
constructor TStatusBarLog.Create(AChannels: TChannels;
AStatusPanel: TStatusPanel);
begin
inherited Create(AChannels);
FStatusPanel:=AStatusPanel;
end;
procedure TStatusBarLog.InternalToLog(Channel: byte; Mes: String);
begin
FStatusPanel.text:=Mes;
end;
constructor TMessageBoxLog.Create(AChannels: TChannels; Caption: String;
Flags: Integer);
begin
inherited create(AChannels);
fCaption:=Caption;
fFlags:=Flags;
end;
procedure TMessageBoxLog.InternalToLog(Channel: byte; Mes: String);
begin
Application.MessageBox(PChar(Mes), PChar(fCaption), fFlags);
end;
initialization
LogList:=TStringList.create;
lLog:=TMessageBoxLog.Create([0..5],'Ошибка инициализации', MB_OK);
SetLog(lLog);
finalization
LogList.free;
end.
[Обмен данными между компонентами] [Взаимодействие расчетных модулей c User Interface]
Обсуждение материала [ 01-07-2004 13:52 ] 6 сообщений |