Показаны сообщения с ярлыком Статьи. Показать все сообщения
Показаны сообщения с ярлыком Статьи. Показать все сообщения

воскресенье, 3 марта 2013 г.

Проверка почты средствами Delphi Часть 2

    В предыдущей части мы создали программу, которая проверяет почту напрямую без поддержки шифрования. В данной части мы рассмотрим возможности проверки почты с использованием SSL.
   Поскольку много времени прошло с момента написания предыдущей статьи и в связи с этим я начал использовать немного новый инструментарий, а именно: при написании кода я уже использую Delphi XE, компоненты все те же - INDY (Версия 10).
   Задание для дальнейшей работы будет следующим:
  • Добавить поддержку SSL для безопасного соединения.
  • Проверить работоспособность программы на gmail.com (там используется SSL) и ukr.net (Без шифрования)
Дальнейшее описание на сайте mirsovetov.net

Автор:

пятница, 29 апреля 2011 г.

Delphi: Секретная комбинация клавиш или "Пасхальное яйцо" - Часть 2

  В предыдущей статье секретная комбинация клавиш или "Пасхольное яйцо"  я описывал как можно управлять компонентами с помощью секретной комбинации клавиш, и для примера использовал запуск отладочного режима при котором отображается дополнительный функционал. Продолжая цикл заметок в этом направлении я попытаюсь описать как можно задать некие отладочные (настроечные) параметры при старте программы. Параметры будут задаваться следующего вида Project.exe -deb.  Для запуска программы отдельно можно создать ярлык с уже заданными параметрами запуска. И так, приступим.
Откроем к примеру предыдущий проект, или создадим новый. В разделе var добавим переменную DEBUGON, которой по умолчанию присвоем значение false
var
  Form1: TForm1;
  DEBUGON:Boolean = false;

   Следующим шагом будет написание процедуры, которая делает перебор всех входных параметров и устанавливает соответствующие значения (процедуру пишем у разделе implementation):

procedure StartInit; // добавляем для глобальной видимости
var
  Form1: TForm1;
  DEBUGON:Boolean = false;

implementation
{$R *.dfm}

procedure StartInit;
  const
    SDebugOn = '-deb';
  var
    I: Integer;
begin
  for I := 0 to ParamCount do
    if ParamStr(I) = SDebugOn  then
      DEBUGON:=true;
end;
  Проверяем в цыклом от 0 до количества параметров все входные параметры.  Кстати первый параметр с индексом 0 будет путь к программе, и ее названием. Если у нас параметр совпадает с константой SDebugOn, то есть имеет значение -deb - тогда переменная DEBUGON = true.
  Дальше нам нужно вызвать данную процедуру при запуске проекта и перед созданием форм. Для этого нужно в главном меню выбрать Project - View Source. В результате откроется исходный код проекта. Вставим вызов нашей процедуры после инициализации и перед созданием форм. У меня код выглядит следующим образом:
program Project1;
uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  StartInit;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
   Двигаемся дальше. Переходим на форму и создаем обработчик события на onCreate (два раза кликаем на пустое поле напротив названия onCreate в Object Inspector - Events) и пишем следующий код:
    Panel1.Visible:= DEBUGON;

  Если у нас переменная установлена, тогда задействуем некие параметры, в данном случае делаем видимой или нет Panel1 в зависимости от параметра DEBUGON.
  Практически все, теперь можно протестировать наше приложение на работоспособность запустив его с параметром -deb и без него. Для запуска программы с параметром можно воспользоваться средствами Delphi, для этого нужно зайти в Run-Parameters и написать в поле Parameters наше отладочное -deb. Пожалуй все, теперь можно опять протестировать и увидеть результат.

Delphi: Секретная комбинация клавиш или "Пасхольное яйцо" - Часть 1

   Бывают ситуации что нужно сделать в программе некий скрытый режим, при котором были доступны какие либо действия. Либо это так называемые "пасхальный яйца" либо какой то специальный режим, к примеру режим отладки, при котором будет доступна какая то панель, в которую мы можем выводить статус работы программы с внутренними параметрами.
   Приведу один из способов. Пример буду приводить на неком новом проекте, чтобы не было ничего лишнего. И так приступим.
   Создадим новый проект в Delphi (При написании статьи я использовал Delphi 2010). File - New - VCL Forms Application . (Рис.1)

 Рис.1.
  Создастся новый проект. Кликаем левой кнопкой мыши на форму и переходим в Object Inspector на закладку Properies, для того чтобы изменить свойство KeyPreview на True. Это свойство определяет будет ли форма обрабатывать события клавиатуры, прежде чем эти события обработаются элементом управления на котором был установлен фокус. В итоге нам нужно будет описать обработчик нажатия клавиш только для формы. Что мы собственно сейчас и сделаем. В переходим в Object Inspector на закладку Events, и в создадим обработчик события на onKeyDown для этого нужно два раза кликнуть левой кнопкой мыши напротив надписи onKeyDown. После создания события - мы переходи в Code Editor  для написания кода. Я заранее определился какая комбинация клавиш будет служить для запуска режима отладки - это Ctrl+Shift+D.Пишем следующий код:
  if (ssCtrl in Shift) AND (ssShift in Shift) AND (Key = Ord('D')) then
      begin
        // код обработки
      end
  Код думаю понятен, если у нас нажата кнопка Ctrl и Shift и D - тогда выполняется какой то заранее подготовленный код. К примеру разместим на форме панель (Panel1 и установим параметр Visible=false в Object Inspector - Properties), а на панели еще какие то компоненты. и к секции begin ... end вышеописанного кода напишем код для скрытия/отображения панели. Весь код представлен ниже:
  if (ssCtrl in Shift) AND (ssShift in Shift) AND (Key = Ord('D')) then
      begin
        Panel1.Visible:= not Panel1.Visible;
      end;
  Все готово.Запись Panel1.Visible:= not Panel1.Visible; означает что при выполнении кода параметр Visible будет принимать противоположное значение. Теперь можно запускать проект для тестирования. После запуска у нас не будет видна панель, поскольку мы установили свойство Visible = false (Рис.2), но при нажатии комбинаций клавиш Ctrl+Shift+D - панель отобразится (Рис.3)


Рис.2

Рис.3
   Вот собственно и все. В следующем описании рассмотрим как можно задать некие отладочные (настроечные) параметры при старте программы. Вида Project.exe -deb

воскресенье, 7 ноября 2010 г.

Подключение к MySQL с помощью Delphi

    На форумах часто задают вопрос - как подключиться к базе данных MySQL с Delphi. Все намного проще чем многие думают.
   Для подключения к  базе данных (БД) MySQL я буду использовать компоненты ZEOS. Недавно я описывал как установить компоненты ZEOS в Delphi 2010.....

 Прошу извинения за неудобства, но сайт переехал.
Для дальнейшего чтения данной статьи перейдите пожалуйста по данной ссылке.

понедельник, 12 апреля 2010 г.

Проверка почты средствами Delphi Часть 1

   Доброе время суток. Я начинаю цикл статей которые направлены на работу по созданию почтового клиента с помощью компонент Indy.
   Для начала определимся с инструментарием: при написании программы я использовал Delphi 2010 (Delphi 2009) компоненты Indy v10 
   В этой части мы выполним следующие задания:
  1. Проверка почты на наличие сообщений;
  2. Возможность задания периода проверки почты;
  3. Вывод уведомлений при наличии каких либо сообщений;

   Раз определились с планом действий - приступим к следующему этапу - созданию. Создаем новый проект, и размещаем на форме компонент idPOP3, который находиться на закладке IndyClients.
   Для того чтобы проверить почту нам необходимо передать компоненту idPOP3 некоторые параметры для подключения, а именно:

UserName – адрес электронной почты в формате (xxx@xxx.xx)
Password – пароль к данному почтовому ящику
Host – POP3 сервер (pop.mail.ru; pop3.ukr.net)
Port – порт (по умолчанию 110)
   Размещаем на форме компонент GroupBox из вкладки Standard – для группирования полей. Для того чтобы программа была более "гибкой" - поместим 4 компонента Edit и Label, они находятся на закладке Standard. Установим свойства компонентов, как показано в Табл.1.
Табл.1.
Компонент Свойство Значение Описание
Form1 Name MainForm
GroupBox1 Caption Настройки ящика

Name SettingsGroupBox
Label1 Caption Адрес

Name AdressLabel
Label2 Caption Пароль

Name PassLabel
Label3 Caption POP3 сервер

Name Pop3Label
Label4 Caption Порт

Name PortLabel
Edit1 Text
Адрес

Name AdressEdit
Edit2 Text
Пароль

Name PassEdit

PasswordChar *
Edit3 Text
POP3 сервер

Name Pop3Edit
Edit4 Text
Порт

Name PortEdit

NumbersOnly true Можно вводить только числа
idPop31 Name idPop31

Результат можно просмотреть на  Рис.1.

Рис. 1. 
   Что касается 2-го задания. Нам необходимо еще разместить на форме компонент Timer, который находиться на закладке System. Для задания интервала проверки, нам необходимо добавить на форму поле ввода Edit (панель Standard), компонент Memo для вывода системных сообщений и кнопку (Button на панели Standard) для подтверждения введеной информации. Установим для них следующие свойства (Табл. 2):
Табл. 2
Компонент
Свойство
Значение
Button1 Caption Установить
Name OkBtn
Memo1 Lines
Name ResultMemo
Edit5 Text
Name IntervalEdit
NumbersOnly true
Timer1 Enabled false
Name CheckTimer

   В результате мы получим следующий вид окна (Рис.2.):

Рис. 2.
   Напишем функцию присвоения значений таймера, его активацию и вывод соответствующих сообщений в ResultMemo.
function TMainForm.StartTimer(T:TTimer;int:Integer):string;
var
  sec:Integer; // объявляем переменную для записи в неё количество мсек.
begin
  T.Enabled:=false; //остановка таймера
  sec:=int*60000; // определяем интервал проверки
  T.Interval:=sec; // задаём интервал проверки
  T.Enabled:=true; //запускаем таймера
  Result:='Почта будет проверена через '+IntToStr(int)+' мин.'; // передача обратно оповещения
end;
Обьявим данную функцию в приватной секции главной формы:
private
  { Private declarations }
  function StartTimer(T:TTimer;int:Integer):string;
   Данная функция задает настройки таймера и возвращает строку с сообщением, через какой период будет проверена почта.

   Дальше создадим код для события onClick кнопки OkButton (для того чтобы создать данное событие необходимо два раза кликнуть на кнопку, или перейти в Object Inspector, открыть закладку Events, и два раза кликнуть по пустому полю возле названия onClick): После создания события автоматически сгенерируется следующий код:
procedure TMainForm.OkBtnClick(Sender: TObject);
begin
end;
Используем ранее написанную функцию, для этого передадим необходимые параметры:
procedure TMainForm.OkBtnClick(Sender: TObject);
begin
  ResultMemo.Lines.Add(StartTimer(CheckTimer,StrToInt(IntervalEdit.Text)));
end;
   Рассмотрим более детально: ResultMemo.Lines.Add(); - добавляем запись в ResultMemo которую возвращает написанная нами процедура StartTimer(CheckTimer,StrToInt(IntervalEdit.Text)).
   Всё очень просто мы останавливаем таймер, в том случае если он запущен, определяем время его срабатывания, записываем данное время в интервал и запускаем таймер.
Теперь перейдём непосредственно к таймеру. Два раза кликаем левой кнопкой мыши на компонент Timer, после чего вы перейдёте в редактор кода, при этом автоматически генерируется обработчик события OnTimer:
procedure TMainForm.CheckTimerTimer(Sender: TObject);
begin
end;
   Дальше реализуем процедуру для получения писем:
function TMainForm.CheckMail(IP:TIdPOP3;User,Pass,Host:string;Port:Integer):String;
var
  NumOfMsgs:Integer; // Количество писем
begin
try
  IP.Username:=User; // адрес электронной почты в формате (xxx@xxx.xx)
  IP.Password:=Pass; // пароль к данному почтовому ящику
  IP.Host:=Host; // POP3 сервер (pop.mail.ru; pop3.ukr.net)
  IP.Port:=Port; // порт
  IP.Connect; // подключаемся
  if IP.Connected then // если подключение прошло успешно
  begin
    // записываем в NumOfMsgs количество писем
    NumOfMsgs := IP.CheckMessages;
    // Возвращаем результат
    Result:='Подключение прошло успешно!'+#13#10;
    Result:=Result+'У вас '+IntToStr(NumOfMsgs)+' сообщений';
  end
  except // Если произошла ошибка- возвращаем текст ошибки
    on E:Exception do Result:='Ошибка подключения! '+E.Message;
  end;
  IP.Disconnect; // Отключаемся
end;
   И обявим ее в приватной секции главной формы:
private
  ...
  function CheckMail(IP:TIdPOP3;User,Pass,Host:string;Port:Integer):String;
   Переходим в обработчик события OnTimer и компонента CheckTimer и пишем следующий код для того чтобы почта проверялась при активации таймера:
procedure TMainForm.CheckTimerTimer(Sender: TObject);
begin
  ResultMemo.Lines.add(CheckMail(IdPOP31,AdressEdit.Text,PassEdit.Text,Pop3Edit.Text,StrToInt(PortEdit.Text)));
end;
   Теперь посмотрим что же получилось, заполняем все поля (настройки для получения почты можно взять на почтовых серверах, где у вас зарегистрирован почтовый ящик) (Рис.3):
Рис.3.
   Тестирование прошло успешно. Сегодня попробую протестировать на других почтовых серверах.
   PS: Если есть пожелания - пишите, с удовольствием выслушаю и по возможности реализую.
Продолжение во 2-й части: Проверка почты средствами Delphi - часть 2

вторник, 23 марта 2010 г.

Стилевое оформление исходного кода в Delphi


Вступление
   Я думал первую статью начать с описания проекта, но решил описать сначала стилевое оформление исходного кода в Delphi. Думаю причина ясна - сначала учимся грамотно писать =). Статья должна быть полезна как для начинающих, так и для опытных программистов. При написании статьи старался приводить примеры, поскольку написанное это хорошо, а увиденное лучше =).
  Object Pascal - замечательно спроектирован язык. Одним из его многочисленных достоинств является легкая читабельность. Описанный ниже стандарт позволит еще больше повысить легкость чтения кода Object Pascal. Унифицированный стиль написания исходного кода повышает читабельность и понятность. Да можно проигнорировать статью и писать как попало, но это лишь действует до некоторого времени, когда проект разрастается и строк кода все больше и больше – приходит момент когда все в куче, и разобраться в этом невозможно. Или представьте ситуацию - вы пришли на новую работу и вам дали недоделанный проект, при написании которого человек понятия не имел что такое форматирование текста вообще, тогда придется худо и вы его будете вспоминать не раз =).

   Естественно переход с собственного стиля оформления на предлагаемый может оказаться непростым, но рано или поздно это надо делать. Есть утилита которая может посодействовать более комфортабельно перейти на этот стандарт. Называется она "delforexp" (Доступна для Delphi 2/3/4/5/6/7/9/2007). В среде Delphi 2010 есть уже встроенный свой инструмент форматирования исходного кода.

   Кстати в компании Borland, на Web-сайте компании Borland, на CD, DVD купленных у компании Borland, везде где есть исходный код, стандарт форматирования является законом.

   Данный документ не является попыткой определить грамматику языка Object Pascal. В нем приводятся базовые примеры как можно поступить при оформлении исходного кода.

Файлы исходного кода (Наверх)   Исходный код Object Pascal подразделяется на модули и файлы проекта, которые подчиняются одинаковым соглашениям. Файл проекта Delphi имеет расширение dpr. Этот файл является главным исходным файлом для всего проекта. Любые модули, используемые в проекте, всегда будут иметь расширение pas. Дополнительные файлы, используемые в проекте могут играть важную роль, но эта глава описывает форматирование только pas и dpr файлов. Более подробно о расширениях файлов можно прочитать в статье: Описание типов файлов в среде Delphi.

Именование файлов (Наверх)
   Язык Object Pascal поддерживает длинные имена файлов. Если при создании имени файла Вы используете несколько слов, то необходимо использовать заглавную букву для каждого слова в имени, например: MyFirstProjectName.pas. Такой стиль оформления известен как InfixCaps или CamelCaps. Расширения файлов должны быть в нижнем регистре.

   Все файлы модулей которые созданы в какой либо организации, например: ХХХ должны иметь префикс ХХХ

Организация исходных файлов (Наверх)
   Все модули Object Pascal могут содержать следующие элементы в определенном порядке:

  • Информация о правах (Copyright/ID);
  • Имя модуля (Unit Name);
  • Секцию интерфейса (Interface section);
    • Подключаемые модули
  • Объявление классов и интерфейсов
    • Дополнительные определения (Additional defines);
  • Реализаця (Implementation)
    • Объявление используемых модулей и директив (Uses clause);
    • Исходный код;
  • Закрывающий оператор и точку (end.) (A closing end and a period).
   Для визуального разделения элементов между ними должна быть хотя бы одна пустая строка.

   При создании нового проекта – среда разработки генерирует исходный код, пример которго приведен ниже:
unit Unit1;

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
private
{ Private declarations }
public
  procedure TForm1.Inp(a:integer);
end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
procedure TForm1.Inp(a:integer);
begin
...
end;

end.
Нужно заметить что ключевые слова пушиться в нижнем регистре.
Рассмотрим каждые элемент в отдельности:

Информация о правах (копирайт) (Наверх)
 Должен содержать следующие пункты:

  • Назначение модуля;
  • Копирайт;
  • Разработчик;
  • Дата последней модификации для исполняемой версии
Он должен выглядеть примерно следующим образом:
{*******************************}
{                                                              }
{                   Модуль ХХХUnit               }
{             Copyright (c) 2010 ХХХ           }
{                     отдел/сектор                   }
{                                                              }
{     Разработчик: x.xxxxxxxx               }
{     Редактирован: дата                        }
{                                                              }
{*******************************}
Имя модуля (Наверх)
   Оно начинается с ключевого слова unit. Имя модуля может содержать символы как в верхнем, так и в нижнем регистре. Например: unit XXXModule1; В результате этот модуль будет назван XXXModule1.pas при сохранении.

Секция интерфейса (Наверх)
   Она состоит из определения подключаемых модулей, описания типов, констант, массивов, переменных:

Подключаемые модули(Наверх)
   Внутри модуля объявление используемых модулей должно начинаться со слова uses (в нижнем регистре). Затем следуют наименования модулей с сохранением регистра символов.
Каждый используемый модуль должен отделяться от следующего с помощью запятой. Объявление используемых модулей должно заканчиваться точкой с запятой. Список используемых модулей необходимо располагать на следующей строке после слова uses. Если используются модули из разных проектов или производителей, то необходимо сгруппировать модули по проектам или производителям и каждую новую группу начинать с новой строки и прокомментировать каждую группу:
uses
  Windows, SysUtils, Classes, Graphics, Controls, Forms, TypInfo, // модули Delphi
  XХХMyUnit1, ХХXMyUnit2; // модули ХХХ
   Если список используемых модулей не умещается по ширине в 80 символов (в редакторе кода есть вертикальная полоса, которая показівает границу в 80 символов), то его необходимо перенести на следующую строку.

Объявление классов, типов и интерфейсов (Наверх)
   Для разделения слов нельзя использовать символ подчеркивания. Имя класса должно быть именем существительным или фразой с именем существительным. Имена интерфейсов или классов должны отражать главную цель их создания:

Правильно:
AddressForm
ArrayIndexOutOfBoundsException
Неправильно:

ManageLayout             //глагол
delphi_is_new_to_me   //подчерк
   Объявление класса и типов начинается с двух пробелов, затем идет идентификатор класса(его имя) с префиксом Т.

   Следом за идентификатором класса идет пробел, знак равенства, пробел и слово class в нижнем регистре:

  TMyClass = class
   Если необходимо определить родителя класса, то следует добавить открывающую скобку, имя класса - родителя и закрывающую скобку:
TMyClass = class(TObject)
   Объявления областей видимости начинаются с двух пробелов и, следовательно, области видимости распологаются на одном уровне с идентификатором класса:
  TMyClass = class(TObject)
  private
  protected
  public
  published
  end;
   Данные всегда должны располагаться только в приватной секции и названия переменных должны всегда начинаться с префикса F. Все объявления внутри класса должны начинаться с четырех пробелов:
  TMyClass = class(TObject)
  private
    FMyData: Integer;
    function GetData: Integer;
    procedure SetData(Value: Integer);
  public
  published
    property MyData: Integer read GetData write SetData;
  end;
   Оформление объявлений интерфейсов подчиняется тем же правилам, что и оформление классов. Отличие будет в использовании ключевых слов специфичных для интерфейсов

   Ключевое слово type размещается без отступов, перечисление типов начинается с новой строки:
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
  private
  { Private declarations }
  public
    procedure TForm1.Inp(a:integer);
  end;
var
  Form1: TForm1;
Реализаця (Implementation) (Наверх)
   Может содержать объявление подключенных модулей, дополнительные наборы директив компилятора, исходный код в виде процедур и функция. Например:

implementation


uses MyUnit.pas


{$R *.dfm}


procedure Inp(a:integer);
begin
...
end;
Закрывающий оператор и точку (end.) (A closing end and a period) (Наверх)
   И конечно же в конце всего этого долен стоять оператор end. – что сведетельствует о окончании модуля.

Соглашение об именовании (Наверх)
   Исключая зарезервированные слова и директивы, которые всегда пишутся в нижнем регистре, все идентификаторы Object Pascal должны использовать InfixCaps (Каждое слово начинается с большой буквы):

MyIdentif, MyFTPClass, NewModuleName;
   Самое главное исключение для всех правил состоит в использовании оттранслированных заголовочных файлов С/С++. В этом случае всегда используются соглашения, принятые в файле источнике. Например будет использоваться WM_LBUTTONDOWN, а не wm_LButtonDown.

Именование (Наверх)
   При именовании полей всегда необходимо использовать InfixCaps. Объявлять переменные только в приватных частях и использовать свойства для доступа к переменным. Для переменных использовать префикс F.

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

   В имени метода всегда должна содержаться команда к действию или глагольная фраза:

Правильно:

ShowStatus
DrawCircle
AddLayoutComponent
Неправильно:

MouseButton;  //Существительное, не описывает функцию
drawCircle;  //Начинается с маленькой буквы
add_layout_component; //Используются символы подчерка
ServerRunning;  //Глагольная фраза, но без команды
   Обратите внимание на последний пример (ServerRunning) - непонятно, что делает этот метод, он может быть использован как для запуска сервера (лучше использовать StartServer) так и для проверки работы сервера (лучше использовать IsServerRunning).

   Имена процедур или методов для установки/получения значений свойств должны составляться по правилу: для получения - Get+имя свойства; для установки - Set+имя свойства.

Например:

GetHeight, SetHeigh;
   Методы для теста/проверки булевских свойств класса должны именоваться с префиксом Is+имя свойства.

Например:

IsResizable, IsVisible, IsServerRunning;
Примечание:

  • Не используйте все заглавные буквы для констант, за исключением оттранслированных заголовочных файлов.
  • Не используйте Венгерскую нотацию, за исключением оттранслированных заголовочных файлов.
Правильно

FMyString: string;
Неправильно

lpstrMyString: string;
   Исключение для Венгерской нотации делается в случае объявления перечислимого типа:

TBtnKind = (bkCustom, bkOK, bkCancel, bkHelp,bkYes, bkNo, bkClose, bkAbort, bkRetry,bkIgnore, bkAll);
bk обозначает ButtonKind;

   Когда Вы подбираете имя переменной, то имейте в виду, что нужно избегать однобуквенных имен, кроме как для временных переменных и переменных цикла.

   Переменные цикла именуются I и J. Другие случаи использования однобуквенных переменных это S (строка) и R (результат). Однобуквенные имена должны всегда использовать символ в верхнем регистре, но лучше использовать боле значимые имена. Также не рекомендуется использовать переменную l (эль), потому что она похожа на 1 (единица).

Зарезервированные слова (Наверх)
   Зарезервированные слова и директивы должны быть все в нижнем регистре. Производные типы должны начинаться с большой буквы (Integer), однако string - это зарезервированное слово и оно должно быть в нижнем регистре.

Использование пустых строк (Наверх)
   Пустые строки могут повысить читабельность путем группирования секций кода, которые логически связаны между собой. Пустые строки должны использоваться в следующих местах:

  • После блока копирайта;
  • После декларации пакета;
  • После секции импорта;
  • Между объявлениями классов;
  • Между реализациями методов;
Использование пробелов (Наверх)
   Язык Object Pascal является очень легким для понимания языком, поэтому нет особой необходимости в использовании большого количества пробелов. Следующие пункты дадут Вам понимание  -  в каком случае необходимо использовать пробелы.

Пробелы, запрещенные к использованию в следующих случаях:

  • До или после оператора .(точка);
  • Между именем метода и открывающей скобкой;
  • Между унарным оператором и его операндом;
  • Между выражением приведения (cast) и приводимым выражением;
  • После открывающей скобки или перед закрывающей;
  • После открывающей квадратной скобки [ или перед закрывающей ];
  • Перед точкой с запятой;
Примеры правильного использования:

function TMyClass.MyFunc(var Value: Integer);
MyPointer := @MyRecord;
MyClass := TMyClass(MyPointer);
MyInteger := MyIntegerArray[5];
Примеры неправильного использования:

function TMyClass.MyFunc( var Value: Integer ) ;
MyPointer := @ MyRecord;
MyClass := TMyClass ( MyPointer ) ;
MyInteger := MyIntegerArray [ 5 ] ;
Использование отступов (Наверх)
   Всегда необходимо использовать два пробела для всех уровней отступа. Другими словами, первый уровень отступает на два пробела, второй на четыре и так далее. Можно настроить табуляцию на ширину в 2 пробела и пользоваться табуляцией.

   Существует несколько исключений из этого правила. Зарезервированные слова unit, uses, type, interface, implementation, initialization и finalization, они всегда должны примыкать к левой границе.

   Также должны быть отформатированы финальные end-ы , завершающий исходный модуль и отдельные блоки. В файле проекта выравнивание по левой границе применяется к также к словам program, главным begin и end. Код внутри блока begin-end должен иметь отступ два символа.

Перенос строк (Наверх)
   Все строки должны быть ограничены 80 столбцами. Строки, длиннее чем 80 столбцов должны быть разделены и перенесены. Все перенесенные строки должны быть выровнены по первой строке и иметь отступ в два символа. Выражение begin всегда должно находиться на своей отдельной строке.
   Никогда не разрывайте строку между параметром и его типом, кроме параметров, перечисляемых через запятую. Двоеточие для всех объявлений переменных не должно содержать перед собой пробелов и иметь один пробел после перед именем типа.

Правильно

procedure Foo(Param1: Integer; Param2: Integer);
Неправильно

procedure Foo( Param :Integer; Param2:Integer );
   Нельзя переносить строки в тех местах, где не допускаются пробелы, например между именем метода и открывающей скобкой или между именем массива и открывающей квадратной скобкой. Никогда нельзя помещать выражение begin на строку, содержащую другой код.

Правильно

while (LongExpression1 or LongExpression2) do
begin
  // DoSomething
  // DoSomethingElse;
end;
if (LongExpression1)  
or (LongExpression2)
or (LongExpression3) then
 Неправильно

while (LongExpression1 or LongExpression2) do begin
  // DoSomething
  // DoSomethingElse;
end;
В случае с логическими операторами предпочтительнее будет следующий вариант:

if (LongExpression1)
or (LongExpression2)
or (LongExpression3) then
Комментарии (Наверх)
   Язык Object Pascal поддерживает два типа комментариев: блочные и однострочные. Общие правила по использованию комментариев могут быть следующими:

  • Помещайте комментарий недалеко от начала модуля для пояснения его назначения;
  • Помещайте комментарий перед объявлением класса;
  • Помещайте комментарий перед объявлением метода;
  • Избегайте очевидных комментариев: (i := i + 1 // добавить к i единицу);
  • Помните, что вводящий в заблуждение комментарий хуже чем его отсутствие;
  • Избегайте помещать в комментарий информацию, которая со временем может быть не верна;
  • Избегайте разукрашивать комментарии звездочками или другими символами;
  • Для временных (отсутствующие в релизе) комментариев используйте "TODO".
Блочные комментарии (Наверх)
   Object Pascal поддерживает два типа блочных комментариев. Наиболее часто используемый блочный комментарий - это пара фигурных скобок: { }. Команда разработчиков Delphi предпочитает использовать этот комментарий как можно проще и как запасной. Используйте в таких комментариях пробелы для форматирования текста и не используйте символы зведочка "*". При переносе строк необходимо сохранять отступы и выравнивание

Пример из DsgnIntf.pas:

{ TPropertyEditor

Edits a property of a component, or list of components,
selected into the Object Inspector. The property
editor is created based on the type of the
property being edited as determined by the types
registered by...

etc...

GetXxxValue
Gets the value of the first property in the
Properties property. Calls the appropriate
TProperty GetXxxValue method to retrieve the
value.

SetXxxValue Sets the value of all the properties
in the Properties property. Calls the appropriate
TProperty SetXxxxValue methods to set the value. }
   В блочный комментарий в большинстве случаев заключается информация о модуле: копирайт, дата модификации и так далее. Блочный комментарий, описывающий метод должен идти перед объявлением метода.

Правильно

{ TMyObject.MyMethod
This routine allows you to execute code. }


procedure TMyObject.MyMethod;
begin
end;
Неправильно
procedure TMyObject.MyMethod;
{******************************************************
TMyObject.MyMethod
This routine allows you to execute code.
*******************************************************}
begin
end;
   Второй тип блочного комментария содержит два символа: скобку и звездочку: (* *). Этот тип комментария используется при разработке исходного кода. Его преимуществом является то, что он поддерживает вложенные комментарии, правда комментарии должны быть разного типа. Вы можете использовать это свойство для комментирования больших кусков кода, в котором встречаются другие комментарии:

(* procedure TForm1.Button1Click(Sender: TObject);
begin
  DoThis; // Start the process
  DoThat; // Continue iteration
{ We need a way to report errors here, perhaps using
a try finally block ??? }
  CallMoreCode; // Finalize the process
end; *)
Однострочные комментарии (Наверх)
   Однострочный комментарий состоит из символов // после которого идет пробел и текст комментария. Однострочные комментарии должны иметь отступы такие же, как и код, в котором они встречаются. Однострочные комментарии можно сгруппировать, чтобы сформировать большой комментарий.

  Однострочный комментарий может начинаться с новой строки и может продолжать код, который он комментирует. В этом случае между кодом и комментарием должен быть хотя бы один пробел. Если больше одного комментария следует за кодом, то они должны быть выровнены по одному столбцу.

Пример однострочного строкового комментария:

// Open the table
Table1.Open;
Пример комментария в коде:

if (not IsVisible) then
  Exit; // nothing to do
Inc(StrLength); // reserve space for null terminator
Необходимо избегать использовать комментарии в коде для каждой строки модуля.
 
Классы
Структура тела класса  (Наверх)

   Тело класса при его декларации подчинено следующей структуре:

  • Объявление полей;
  • Объявление методов;
  • Объявление свойств.
   Поля, свойства и методы в вашем классе должны быть упорядочены в алфавитном порядке.

Уровни доступа (директивы видимости)  (Наверх)
   В Object Pascal существует четыре уровня доступа (директивы видимости) для членов класса: published, public, protected и private - в порядке уменьшения видимости. По умолчанию, уровень доступа - published. В общем, члены класса должны давать наименьший уровень доступа, который подходит для этого члена.
   Например, член, к которому имеют доступ классы из одного модуля должен иметь уровень доступа private. Кроме того, объявляя члены класса с наименьшим уровнем доступа, Вы позволяете компилятору воспользоваться дополнительными возможностями для оптимизации. С другой стороны, если Вы планируете в дальнейшем порождать дочерние классы от Вашего класса, то нужно использовать уровень доступа protected.

   Никогда не указывайте уровень доступа public для данных. Данные всегда должны быть объявлены в приватной секции и доступ к ним должен осуществляться с помощью методов или свойств.
  
   Исключая код, вставленный IDE, директивы видимости должны быть объявлены в следующем порядке:

  • Приватные (скрытые) члены класса (private);
  • Защищенные члены класса (protected);
  • Общедоступные члены класса (public);
  • Публикуемые члены класса (published)
Объявление конструктора  (Наверх)
   Все методы класса должны быть упорядочены по алфавиту. Однако Вы можете поместить объявления конструктора и деструктора перед всеми остальными методами. Если у класса существует более чем один конструктор и если они имеют одинаковые имена, то они должны располагаться в порядке увеличения числа параметров

Объявление методов  (Наверх)
   По возможности, объявление метода должно располагаться на одной строке:
Например:

procedure ImageLoad(ImageCount: Integer, y: Integer, w: Integer, h: Integer);
Интерфейсы (Наверх)
   Все основные правила форматирования для классов применяются и для форматирования интерфейсов. Интерфейсы декларируются в той же манере, что и классы.

InterfaceName = interface([Inherited Interface])
  InterfaceBody
end;
   Отступ для интерфейса должен быть равен двум пробелам. Тело интерфейса имеет отступ четыре пробела. Закрывающий end должен иметь отступ в два пробела. Объявление класса заканчивается точкой с запятой. У интерфейса не существует полей, однако могут присутствовать свойства.

   Все методы интерфейса являются абстрактными и общедоступными, поэтому не требуется включать слова public и abstract в объявление метода.

Структура тела интерфейса (Наверх)
   Тело интерфейса при его декларации подчинено следующей структуре:

  • Объявление методов интерфейса;
  • Объявление свойств интерфейса.
   Стили для объявления свойств и методов интерфейса аналогичным стилям для класса.

Операторы (Наверх)
   Операторы - это одна или более строк кода, разделенных точкой с запятой. Простые операторы имеют одну точку с запятой, а составные (структурированные) состоят из множества простых операторов и могут иметь более чем одну точку с запятой.
Например, простой оператор:

A := B;
   Это составной или структурированный оператор:


begin
  B := C;
  A := B;
end;
Простые операторы(Наверх)
   Простые операторы содержат одну точку с запятой. Если Вам необходимо разделить операторы, то перенесите продолжение оператора на следующую строку с отступом в два пробела:

MyValue :=
  MyValue + (SomeStatement / OtherStatement);
Составные операторы(Наверх)
   Составные операторы всегда заканчиваются точкой с запятой и имеют несколько простых операторов.

begin
  MyStatement;
  MyNextStatement;
  MyLastStatement;
end;
Присвоения и выражения(Наверх)
   Каждое присвоение и каждое выражение должно располагаться на разных строках.
Правильно

a := b + c;
Inc(Count);
Неправильно

a := b + c; Inc(Count);
Объявление локальных переменных(Наверх)
   Как уже было описано выше - локальные переменные должны иметь стиль Camel Caps. Для локальных переменных префикс F не требуется.

var
  MyData: Integer;
  MyString: string;

   Все переменные с их типами, особенно поля класса, должны быть объявлены на различных строках.

Объявление массивов(Наверх)
   При объявлении массива перед и после квадратных скобок должны стоять пробелы.

type
  TMyArray = array [0..100] of Char;
Оператор if(Наверх)
   Оператор if всегда должен располагаться по крайней мере на двух строках, на первой - условие, на второй - оператор
Правильно

if A > B then
  DoSomething;
Неправильно

if A > B then DoSomething;
   В случае составного оператора необходимо поместить каждый оператор на новую строку.
Правильно

if A > B then
begin
  DoSomething;
  DoSomethingElse;

end
else
begin
  DoThis;
  DoThat;
end;
Неправильно

if A > B then begin
DoSomething; DoSomethingElse  ;
end else begin DoThis; DoThat; end;
   Все остальные варианты расположения операторов не рекомендуются и не одобряются, хотя и являются синтаксически правильными.
   Избегайте использования круглых скобок в простых проверках. Например:
Правильно

if I >= 0 then
  DoSomething;
Неправильно

if (I >= 0) then
  DoSomething;
Оператор for(Наверх)
   Оператор for всегда должен располагаться по крайней мере на двух строках, на первой - условие, на второй - оператор.
Правильно

for I := 0 to 10 do
begin
  DoSomething;
  DoSomethingElse;
end;


for I := 0 to 10 do
  DoSomething;
Неправильно

for I := 0 to 10 do begin
  DoSomething;
  DoSomethingElse;
end;
Оператор while(Наверх)
   Оператор while также как и предыдущие операторы должен располагаться на нескольких строках

Правильно

while X > J do 
begin 
  DoSomething;
  DoSomethingElse;
end;


while X < J do 
  Something; 
Неправильно


while X > J do begin DoSomething; DoSomethingElse; end;
Оператор repeat until (Наверх)
   Также как и все операторы - должен быть записан с новой строки каждый элемент.
Правильно

repeat
  X := J;
  J := UpdateValue;
until J >= 25;
Оператор case(Наверх)
   Несмотря на то, что существует множество синтаксически правильных конструкций, одобренной и рекомендованной считается следующая:
Правильно

case ScrollCode of
  SB_LINEUP, SB_LINEDOWN:
  begin
    Incr := FIncrement div FLineDiv;
    FinalIncr := FIncrement mod FLineDiv;
    Count := FLineDiv;
  end;
  SB_PAGEUP, SB_PAGEDOWN:
  begin
    Incr := FPageIncrement;
    FinalIncr := Incr mod FPageDiv;
    Incr := Incr div FPageDiv;
    Count := FPageDiv;
  end;
  else
    Count := 0;
    Incr := 0;
    FinalIncr := 0;
end;
Оператор try(Наверх)
   Несмотря на то, что существует множество синтаксически правильных конструкций, одобренной и рекомендованной считается следующая (древовидная структура):
Правильно

try
  try
    EnumThreadWindows(CurrentThreadID, @Disable, 0);
    Result := TaskWindowList;
  except
    EnableTaskWindows(TaskWindowList);
    raise;
  end;
finally
  TaskWindowList := SaveWindowList;
  TaskActiveWindow := SaveActiveWindow;
end;
PS: Теперь можно приступить к написанию статей.

среда, 17 марта 2010 г.

Описание типов файлов в среде Delphi

Рассмотрим типы файлов которые используются в среде программирования Delphi
  • .dpr - файл проекта Delphi. Это первичный файл, в котором содержаться ссилки на другие модули программы и связывает формы с соответствующими модулями. 
  • .pas - файл который содержит исходный код программы. 
  • .dfm - файл содержит свойства формы, описание и свойства объектов, которые расположены на форме. 
  • .dcu - скомпилированный вариант .pas файла.
  • .res - файл, который содержит ресурсы. Данные в нем хранятся в двоичном виде. Он включает также в себя информацию о приложении. По умолчанию, Delphi создает новый .res - файл с именем проекта при каждой компиляции. Так что, если нужно добавить какие то ресурсы в программу (звуки, графику и т.д.), то нужно загружать их в файл ресурса из названием которое отличается от названия проекта.
  • .dof - файл содержит настройки для текущего проекта (настройки компилятора, каталоги...)
  • .dem - в данном типе файлов сохраняются некоторые стандартные, привязанные к стране, форматы компонента TMaskEdit.
  • .bpg - Файл содержит описание групп проектов. (При открытие этого типа файл - могут подгружаться несколько проектов одновременно).
  • .dsk - файл содержит настройки относительно состояния проекта (координаты положение окон проекта, открытые окна ). Он подобен файлу с расширением .dof. Но содержит другие настройки.
  • .dpk - файл пакета (аналогично .dpr-файлу. В основном используется для установки новых компонент).
  • .dcp - файл содержит информацию о символах и дополнительных заголовках, требуемых IDE. Для сборки (build) проект, IDE должен иметь доступ к этому файлу.
  • .bpl - это выполняемый  runtime-пакет фактически является DLL файлом.
  • .dci - файл содержит как стандартные, так и определенные пользователем шаблоны кода, используемых в IDE.
  • .dct - файлы данного типа содержат информацию об определенных пользователями шаблонах компонентов.
  • .dro - файлы содержит информацию об объектном хранилище (Repository). Каждый пункт данного файла содержит специфическую информацию о каждом доступном элементе в хранилище объектов. Хранилище можно отредактировать только с помощью меню "Tools => Repository" в самом IDE.
  • .dmt - данные "частные" бинарные файлы содержат встроенные и определенные пользователем шаблоны меню. 
  • .tlb - двоичные файлы библиотеки типов. Данные типы файлов обеспечивают информацией для идентификации типов объектов и интерфейсов, доступных в ActiveX сервере. Подобно модулю или заголовочному файлу, .tlb служит в качестве хранилища для необходимой символьной информации приложения. 
  • .ocx - типы файлов с таким расширением является специализированными DLL, которые содержит все или несколько функций, связанных с элементом управления ActiveX. Файлы с расширением .ocx задумывался как "обертка", которая содержала бы сам объект, и средства для связи с другими объектами и серверами.
  • .gdb - стандартные Interbase-файлы.
  • .dbi - Файлі с таким расширением содержат информацию, необходимую для инициализации Database Explorer. 
  • .exe - Исполняемые файлы приложения. При компиляции (сборке) вашего проекта в результате получается приложение с именем данного проекта и с данным расширением.
  • .dll - файлы DLL (англ. Dynamic-link library — динамически подключаемая библиотека) динамическая библиотека, позволяющая многократное применение различными программными приложениями. K DLL относятся также элементы управления ActiveX и драйверы. Формат файлов DLL придерживается тех же соглашений, что и формат исполняемых файлов, сочетая код, таблицы и ресурсы.
  • .~dpr ; .~pas ; .~dfm - файлы резервных копий. Соответственно, резервные копии проектов, модулей, форм.