Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Сокровищница
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  16:17[Войти] | [Зарегистрироваться]

Обмен текстовой информацией между модулями проекта

Сергей Перовский
дата публикации 20-02-2003 11:47

Обмен текстовой информацией между модулями проекта

При написании программ я всегда старался четко отделять пользовательский интерфейс от алгоритма задачи.
С появленинием в Delphi ActionList'а стало гораздо проще писать алгоритмическую часть без оглядки на структуру пользовательского интерфейса.

Но осталась проблема отображения информации: в некоторой точке программы требуется вывести сообщение, а куда выводить неизвестно.
Разработчик интерфейса еще не решил, что выводить в StatusBar, что в MessageBox. Какую отладочную информацию поместить в логфайл. Я решаю эту проблему следующим образом — во всех существенных точках алгоритма вызывается процедура ToLog.
Два ее параметра определяют текст сообщения и ее предназначение. 256 "каналов" должны быть поделены между сообщениями об ошибках, отладочной информацией, информационными сообщениями и результатами.

Это единственное соглашение, которое должны соблюдать все участники проекта. Разработчик интерфейса решает для компонента - сообщения из каких каналов он должен отображать и регистрирует соответствующий объект (Log). "Расчетные" модули могут не ссылаться на модули с описанием форм и диалогов. Единственный модуль, через который они общаются - и на который обязаны ссылаться (причем в implementation разделе) это uLogs.

Модуль uLogs предназначен для передачи текстовых сообщений между различными модулями, визуальными компонентами и файлами. Для разделения сообщений различных типов введено 256 "каналов". Каждому сообщению должен быть сопоставлен номер канала, определяющий цель сообщения и технологию его обработки. Для протоколирования и/или визуализации сообщений предназначены специальные объекты "Логи" - наследники базового объекта TLog. Каждый "лог" может обрабатывать все сообщения из заданного множества каналов. Логи разных типов различаются способом фиксации или отображения информации.
В модуле описано 5 различных наследников абстрактного класса TLog. По их образцу легко создать классы для других способов обработки сообщений.

uLogs.pas

Скачать uLogs.zip (2.3 K)
							  
unit uLogs; 
 
interface 
uses Classes,Controls,StdCtrls,ComCtrls,Forms; 
{-------раздел для генерации сообщений----------} 
   {всего одна процедура} 
procedure ToLog(Channel:byte;Mes:String); 
               {номер канала (0 - 255) и текст сообщения} 
 
 
{----------раздел для обработки сообщений----------} 
Type 
   TChannels = set of byte; 
   TLog = class          {абстрактный базовый класс} 
   protected 
   FChannels:TChannels;  {множество обрабатываемых каналов} 
   procedure InternalToLog(Channel:byte;Mes:String);virtual;abstract; 
   {InternalToLog - для каждого наследника определяет способ обработки.} 
   {Номер канала передается, чтобы его можно было учесть при обработке,} 
   {например, при выводе диагностических сообщений менять цвет текста} 
   {в зависимости от номера канала} 
   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) {добавление строки к содержимому 
    любого наследника абстрактного базового класса TStrings} 
   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) {вывод текста сообщения в Caption любого 
                               компонента - наследника TControl} 
   FControl:TControl; {компонент для отображения} 
   procedure InternalToLog(Channel:byte;Mes:String);override; 
   constructor Create(AChannels:TChannels;AControl:TControl); 
   end; 
 
   TStatusBarLog  = class(TLog){вывод текста сообщения в StatusPanel} 
   FStatusPanel:TStatusPanel; 
   procedure InternalToLog(Channel:byte;Mes:String);override; 
   constructor Create(AChannels:TChannels;AStatusPanel:TStatusPanel); 
   end; 
 
   TMessageBoxLog  = class(TLog) {вывод текста сообщения в MessageBox} 
   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);  { -1 если лога под таким именем нет} 
  if result<>-1 then LogList.Delete(result); 
End; 
 
{ TLog } 
 
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; 
 
{ TStringsLog } 
 
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; 
 
{ TFileLog } 
 
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; 
 
{ TCaptionLog } 
 
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; 
//  FControl.Caption:=Mes; 
 
end; 
 
{ TStatusBarLog } 
 
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; 
 
{ TMassageBoxLog } 
 
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); 
  // Каналы с 0 по 5 зарезервированы для ошибок инициализации модулей 
  SetLog(lLog); 
finalization 
  LogList.free; 
end. 





Смотрите также материалы по темам:
[Обмен данными между компонентами] [Взаимодействие расчетных модулей c User Interface]

 Обсуждение материала [ 01-07-2004 13:52 ] 6 сообщений
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования