Урок 4          Frank Fortino (ffortino@svn.net)  Copyright 1999  

Перевод на русский язык : 2001 год   Руденко Е.В. janerev@hotmale.ru
Стиль и оформление автора практически не изменены.



Привет,

Замечания:

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

Некоторые читатели присылают  мне email - письма , где :
 - указывают на некоторые ошибки
 - объясняют вещи , которые я не знаю
 - показывают мне другие стили и технику программирования.

Таким образом я постоянно вношу незначительные изменения . Но существенных изменений в Уроках 1,2 3 нет.


Темы дискуссии:
  - Теория группировки
  - Техника обучения 
  - Just old Bitching and Moaning
  - Дерево Меню и  Help файлы
  - Вверх / Вниз программирование
  - Формы, Диалоги, Сообщения ...
  - Динамическое создание Форм
  - Согласование типов
  - Компонент MaskEdit
  - Группировка компонентов Delphi


Я обнаружил, что  создавать данные Уроки тяжелее, если вдаваться в детали.  Я не хочу изобретать колесо.

Какая помощь доступна для программистов на  Delphi сейчас:
1) Другие WWW  сайты с  Компонентами, Типами и Советами, отдельные куски кода и т.д.  Огромный ресурс , который каждый должен использовать.
2) Группы новостей Borland .  Ответы на специфичные вопросы,  которые вы нигде не можете найти.  Именно здесь эксперты Delphi свободно дают советы.
     Не очень хорошее место для новичка , начинающего изучать Delphi, поскольку большинство ответов очень кратки.
     Каждый хороший программист на  Delphi должен знакомиться с сообщениями данных групп новостей.  Это хороший способ изучить некоторые специальные решения от экспертов Delphi.  Я использую их все время.
3) Книги.   Есть ряд превосходных книг по всем разделам Delphi.  Покупайте столько книг, сколько можете себе позволить.
4) Web уроки.   Хороших до сих пор я не видел.

Какой помощи не хватает:
1) Множества простых, полностью документированных примеров программ.

2) Хороших руководств пользователя, которые кратко , на 1 или 2 печатных страницах, раскрывают суть

3) Хорошо спроектированных наборов компонентов, приятных для глаз и легких в использовании.

4) Хорошо продуманных и структурированных Библиотек кодов , решающих много задач и доступных для быстрого использования

5) Примеры хорошего СТИЛЯ программирования, искусства программирования

6) Хороших библиотек макросов -  шаблонов кодов, шаблонов компонентов и т.д.

Итак, каким образом я надеюсь сделать мои Уроки полезными для начинающих программистов на  Delphi ?
Я решил посвятить часть моих Уроков обратной стороне вещей.  Попытаемся посмотреть на  Delphi нестандартно и ответить скорее на вопросы Почему и Где , чем на вопрос Как сделать что-то.

Я исследую маленькую пользовательскую сторону  Delphi; а не  Enterprise, MIDAS, CORBA или что-либо подобное.
Программистов на  Delphi, работающих в маленьких компаниях существенно больше, чем работающих в больших компаниях.  Кстати сказать , большие компании предпочитают продукты Microsoft (VB или VC++) более чем продукты Borland .  

Delphi - язык программирования для всех, а не только для искушенных программистов.  У меня есть множество примеров программирования на Delphi , которые я даю людям.

На каждый 1 час , затраченный на написание кода программы, вы потратите  10 часов на отладку и установку.  Поэтому делайте ваш код легким для чтения и понимания, Во-первых, и компактным и эффективным, во-вторых.  Ушли дни , когда вас волновало , сколько оперативной памяти (RAM) занимает ваша программа.  Практически везде теперь это неважно.  Иногда я вижу, что программисты "глубоко зарываются" в  тонкости программирования, в ущерб тому, чтобы сделать программу работоспособной и легкой для модификации и установки.  В школе вы учитесь написанию рекурсивных программ, способам сортировки и работе со списками.  Это , конечно, хорошо, но, Я думаю , что более важно знать , как использовать служебные программы, чем , как их написать.  Один человек написал одну служебную программу (утилиту), затем тысячи программистов используют ее тысячу раз.  Так, что же более важно?  Да , научиться, как правильно пользоваться инструментами программирования.  

Посмотрите внимательно на  Visual Basic или Visual C++ и вы сразу увидите отличия Delphi . You don't have to have an MS in Computer Science to be an excellent programmer.  Хорошее Программирование - это Искусство , а не просто написание кода.  Некоторые из так называемых лучших программистов могут писать тяжелейшие для понимания и установки программы.  I call that poor programming.  Don't always try to use the trickiest and most complicated features. Try and use the best technique to make things easy to understand.  The idea is to make a program that anyone can read and understand and improve. Put your ego in your pocket.  The idea is not to impress others.  You really don't need the appraisal of others, to know that you have done a good job. With Delphi, programming style is ultra important; since there are so many different ways to do the same thing.  It is easy to clutter a screen up with too much color, or fail to organize elements is a simple and easy to understand way.  That's where the Art comes in.  Всем необходимы примеры хорошего стиля и функций.  Но где научиться таким вещам?

И последнее.  Важнейшая часть любого проекта - фаза первоначального проектирования и спецификации.  You should spend 40% of your time (not 10%), seeing what all your options are and deciding on a path to take.  Once you start on a path, it is very difficult to turn back.  So, be sure where you are going, before you start.

Also, you learn along the way; seeing better techniques as you build and try what you've done.  Сделайте СНАЧАЛА программу работоспособной , а потом "отполируйте" ее.  Program Top Down, and Bottom Up. i.e. Do the overall design and program flow, and also start writing the primitive functions.  Then they meet somewhere in the middle.  И всегда будьте готовы внести изменения.  What sounds like a good idea, sometimes isn't.

Можно использовать другой способ обучения (который помогал мне в колледже).  When you want to learn something new, load data into all of you senses.  Look at it, say it out loud (hear it), write it down (or type it in).  Then it will stick better.  Your memory has a easy time storing data; the hard part, is to find the link to access the memory.

That's why you learn so much by physically doing something, rather then just silently reading about it.  It impacts your senses a lot more when you see, say, hear and feel it.  Несомненно верно выражение: "Каждый учится на своих ошибках".  That is because making a mistake impacts you more.  You are frustrated, humbled and kicked all at the same time.  Как вы могли это забыть.
The worst thing to do is stand still, then you are sure to go nowhere. So keep on Trucking!  And that means, driving the Delphi truck.


Интересная точка зрения:

Franky любит использовать во множестве Глобальные переменные.
 
Новый взгляд:
  Ваши Глобальные Переменные - Гигантский лист глобальных параметров с фиксированной структурой
        (нет необходимости помнить порядок данных).

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

Теперь вы понимаете, почему мне не нравиться так много параметров.
It's like using Reverse Polish Notation, or MODULO 2 (whatever that awful language was called)
It used the Stack to hold data, so the order of the data on the Stack had to be known.

What a total pain in the ass that was.  It's hard enough remembering the variables that you use,
    now you also have to know the order to pass them, and you have to pass them all, all the time.
With Global Vars you only have to change the vars that have changed, all the other vars that haven't
changed, are available, everywhere in the program.
Отладка происходит намного легче, когда вы можете видеть ВСЕ переменные , когда они вам необходимы.

Запомните, что хороший программист затрачивает  8 часов на отладку и проверку программы, на каждый 1 час написания кода .
Итак, Отладка, Проверка и Упорядочение кода программы должны быть первыми в вашем списке .

Компактный код  с минимальными комментариями -  это теперь  ПЛОХАЯ ПРИВЫЧКА.
Пишите ваш код так, чтобы он был легким для понимания.

Например:
var Prn, Int, Res: currency
begin
  Prn:=Q1.FieldByName('PrinAmt').AsCurrency;
  Int:=Q1.FieldByName('IntAmt').AsCurrency;
  Res:=Prin+Int;
  Q1.FieldByName('ResultAmt').AsCurrency:=Res;
end;

Я думаю, вышеприведенный код легче понять, чем следующий:

begin
  Q1.FieldByName('ResultAmt').AsCurrency:=Q1.FieldByName('PrinAmt').AsCurrency
     -Q1.FieldByName('IntAmt').AsCurrency;
end;

Итак, я люблю использовать локальные переменные , чтобы сделать мой код легким для чтения.


Franky's стиль:

Другая вещь, которую я делаю нестандартно.

Вопрос: Frank, почему вы не используете  Модули данных (Data Modules)?
Ответ: Я думаю, что они имеют некоторые ограничения, так что я использую обычную форму и модуль (Form и Unit) вместо Data Module.

Повторю еще раз, я не использую Data Modules.
Я всегда использую Форму (и Модуль) для размещения моей базы данных (Tables, Querys)
Обычно я называю такой модуль (DB1.pas) и Форму (DB1F)

Затем я размещаю компонент  DBGrids на Форме для каждой моей Таблицы (Tables) или Запроса (Querys) (с компонентом DBNav для редактирования каждой БД)
  (заметьте: Если у меня много таблиц, я использую компонент Tabbed PageControl, размещая на каждой странице компонент DBGrids.)

Когда программа запускается:
    Я могу разместить кнопку  Button для вызова процедуры  DB1F.Show,  для показа моей БД.

Во время разработки программы:
   Я могу перейти на  DB1F Form и сделать любую Таблицу активной,
   и таким образом увидеть содержимое БД, имена полей и т.д.,
   и я могу также добавлять новые записи и редактировать существующие в БД.

Another great Debugging Aid.
  Being able to see and manipulate all of your DB's, in the IDE environment, and when the program is running.


Позвольте мне ответить кратко:

  Вопрос: Frank, what is your view of  the Window's Help *.hlp format and Menus?
  Ответ:   It Sucks!

  Вопрос: Что вы думаете об  *.hlp файлах?
   Ответ:   Not very much, they Suck

  Вопрос: Ну и что вы думаете о Меню  (Древовидных структурах)?
  Ответ:    They usually Suck?

  Вопрос: Are we a little testy today?
  Ответ:     No.  Just a lot of stuff Sucks.

Please God, stop me before I hurt myself.

There is one thing that I do like about *.hlp files
  The INDEX mode (search mode)
  Not the CONTENTS view    It S---s     Frank,  Stop that!


Что такое хороший стиль программирования?

Что вы думаете о стандартной структуре меню фирмы Microsoft?
 ...........  Будь добр, Frank, воздержись от неприличных слов!

Я сильно не люблю подменю.  Если у вас есть  компонент Menu bar, используйте его более эффективно.  размещайте максимально возможное число элементов на каждом уровне меню.
Структура Дерева Меню может иметь некоторые ограничения:
  - Только 1 путь на каждый объект
  - Слишком много точек выбора
  - Недостаточно легкий доступ к объектам вторичного выбора
  - Недостаточно легкий способ выгрузить все оъекты в файл  (т.е. распечатать Дерево Меню)
     Попытайтесь напечатать  *.hlp файл и вы получите около 60 страниц с 4 строками на каждой.
     Согласитесь, что это огромная структура.

Если Субменю имеет от  2 до  4 позиций, то попытайтесь сделать его частью Основного Меню.
Вы можете делать основное Меню до 20 пунктов.

Знаете ли вы , сколько раз в день я создаю новую Директорию (Folders) или использую пункт меню "Найти".
Эти действия я выполняю неоднократно и они требуют выбора из ПодМеню.
Спасибо фирме  Microsoft!

Техника группировки:
  - Один длинный список, который можно отсортировать различными способами
  - Дерево Меню только с одним указателем на каждый объект
  - Гиперссылки, jump point to point, have multiple groupings

Вот почему Гиперссылки так прекрасны.  You can jump from anywhere to anywhere, and you can easily create multiple grouping of Links.

Grouping 101
  1) Не следуйте заголовкам от  Microsoft
  2) Ищите другие пути группировки элементов.  Действуйте творчески.
        Выбирайте лучшее решение.
  3) Когда вы просматриваете программы, обращайте внимание на группировку элементов.
        Учитесь у экспертов.  Although some excellent programmers are extremely weak in this area.
        I'm not even close to being an expert programmer;   я тоже нуждаюсь в помощи (In more ways than one).
                 (Frank, ты можешь сказать это снова - Тебе действительно необходима Помощь)
        As Buzz Light-year said in the movie Toy Story.   "You're a very strange, sad, little person".

Еще один комментарий по поводу Меню.  Только несколько типов данных хорошо работают с Меню.  Во многих случаях в меню вы не увидите достаточно пунктов одновременно.  Everything is tucked in tiny cubby holes, and the limbs of the menu tree are not mutually exclusive.

For example, look at all the places that you find Options, Preferences, Configuration, Properties and Setup information.
They can keep the structure that they have now; but, please add an OPTIONS menu, that lists everything in one place.
Even Delphi 3      Project/Options       Tools/Env.Options       Tools/ConfigureTools
                           RightClickTools/Properties                          RightClickPalette/Properties


Когда я начал изучать  Delphi, я хотел видеть примеры стилей отображения Форм.  Я хотел видеть реальные программы и обучаться на примерах других людей.  До сих пор я ищу некоторые хорошие примеры программ.
Книги дают немного в показе и объяснении различных стилей и техники группирования.

Тяжело изучать некоторые примеры программ, потому что программисты использовали Инспектор Объектов  (ObjI).
Так что , программа имеет очень мало программного кода или его нет вообще.
Если вы недостаточно хорошо  знаете Компоненты, то не знакомы с их Свойствами  (или как их использовать).
И что плохо, вы не знаете значения величин, которые устанавливаются по умолчанию; так что если программист изменил Свойство, вы об этом не узнаете.

Hey, that would be a nice feature (Pay attention Borland)  Note: They did  Delphi 5 has ObjI grouping
  - Mark the Properties (in the ObjI) that have been changed.  Это сильно поможет начинающим.
       or put the changed properties, at the top of the list
  - It could even help the seasoned programmer, get some visual feedback
  - Even having markers on items in the ObjI, depending on their Category and Status

Взглянув назад , вспомним ошибки, которые я совершал при написании программ Delphi :
  1) НЕ именовал Компоненты при старте, писал код и только потом переименовывал Компонент!!
       OOP's, delphi didn't change the names inside my procedures.
 2) Забывал конвертировать переменные в правильный тип   IntToStr(  );  ...AsString;
 3) На форме.  Не использовал в достаточном количестве  Panels и GroupBoxes.
       Теперь я почти всегда размещаю первой панель Panel , учитывая , что позже она мне понадобится для группировки компонентов.
 4) Не знал , ГДЕ и КАК использовать различные компоненты.

Один момент.  Не забывайте карандаш и бумагу при написании программ.
   1) Keep a folder of 1 or 2 sheet References on (Dates, SQL, Formats, ...)
         a great concise look at all your choices
  2) Выключите компьютер, сядьте в удобное кресло и начните структурировать вашу программу с карандашом и бумагой.
        Один момент.  Не стирайте много.  If you change a lot of stuff, redo it on another sheet.  Не стирайте.
             If you find yourself erasing a lot, then get on the computer, and do your designs there.
        Создайте подробную карту задачи (на 1 листе).  Да, разместите все на 1 листе.

С помощью моих Уроков я хочу улучшить ваш и мой СТИЛЬ программирования.
I also want to Group things together for you in different ways.   That's why the best Instructors at school, were the ones that explained things from a different perspective.

Как можно изучать предмет быстрее?
  - Load data into all of your senses See it, Feel it, Say it, Hear it , Touch it
      - have a pencil and paper on your desk.  Make short notes to yourself, write things down.
  - Reinforce good behavior; do the correct thing over and over, get good habits
  - Have quick access to lots of data (this is were seasoned programmers can help newcomers)
  - When you learn it, keep it, and have quick access to it.
       - It is difficult enough to learn Delphi without re-learning things. Learn it once.
  - You learn by doing, creating RR Tracks of strong multi-sensual channels. (sounds pornographic)
  - Ваша память очень визуальна.  Картинки легче запомнить.

 


Данный вопрос я задаю каждому.

Начинающим программистам необходимо как можно больше изучать примеров программ.
.
Есть ли у вас  компоненты Form, Dialog или  Panel , которые вам нравятся и вы ими гордитесь?
Могли бы вы предоставить их новичкам?
Пришлите мне по  email .dfm файл и  .pas файл (с вашим именем),  чтобы я мог создать Библиотеку Форм.

Может быть у вас есть примеры программ, по которым вы учились?

Спасибо


Теперь о некоторых хитростях  Delphi :


Формы, Диалоги, Сообщения , ...

Давайте посмотрим , как Delphi может посылать сообщения пользователю.

Пути отображения данных для пользователя в формах,  Диалоговые Окна :

Form2.Show;
        Открывает(Показывает) форму Form2 (пользователь может щелкнуть на  Form1)

Form2.ShowModal;
        Открывает (Показывает) форму Form2 (пользователь  НЕ МОЖЕТ щелкнуть на  Form1)

ShowMessage('Это - сообщение !');
        Просто отображает строку текста; пользователь должен нажать кнопку  OK для закрытия окна сообщения.

    ShowMessage('Вот это и есть диалоговое окно , УРА !');

MessageDlg('Сообщение',mtConfirmation,[mbYes],0);
      То же самое , что и  ShowMessage, но с большим числом кнопок выбора для пользователя.

  if MessageDlg('Пожалуйста, нажмите  YES или NO',mtConfirmation,[mbYes,mbNo],0)=mrYES then
  begin
    EntryEB.Text:='Вы нажали кнопку YES ';
  end;


TMsgDlgType = mtWarning, mtError, mtInformation, mtConfirmation, mtCustom

TMsgDlgBtn =  mbYes,    mbNo,    mbOK,    mbCancel,    mbAbort,   mbRetry,   mbIgnore,   mbAll,  mbHelp

Return values =   mrNone,    mrYes,     mrNo,    mrOk,     mrCancel,     mrAbort,   mrRetry,   mrIgnore,   mrAll


InputBox(...);
        Давайте попробуем ввести данные (в виде строки) (кнопка CANCEL очищает вводимую строку)

    var
  `   InputString: string;
    begin
      InputString:= InputBox('Ввод имени пользователя ', 'Пожалуйста, введите ваше имя ...', '');
    end;


InputQuery(...);(очень похоже на  InputBox)
        Давайте попробуем ввести данные и определить , какая кнопка нажата  (OK или CANCEL)

  var
    EntryStr: string;
    ClickedOK: Boolean;
  begin
    ClickedOK := InputQuery('Ввод имени пользователя', 'Пожалуйста введите ваше имя ...', EntryStr);
  end;

Я написал простую программу (Windows1P.dpr) в  L4Examples.zip , в которой продемонстрированы различные типы окон.

Также , просмотрите помощь  (по F1) на  компоненты ShowMessage, MessageDlg, InputBox, InputQuery


Формы:

    Я обычно делаю МАКСИМАЛЬНЫМ размер (WindowState:=msMaximized)
    При этом , мне не приходиться заботиться о  MODAL формах, поскольку вы не можете щелкнуть мышкой вне максимизированной формы.
    Форму с обычным размером (не максимальным) , я обычно делаю модальной ( MODAL).
        begin
          Form2.ShowModal;
        end;

 Различные пути создания Форм:
        1)  Delphi создает ваши формы при первом запуске программы
        2) Создавайте и разрушайте  (Destroy) ваши формы по мере необходимости (Динамически в коде программы)

 1) Delphi автоматически создает ваши Формы.
                Посмотрите на файл  .dpr для проекта с двумя формами.
    {$R *.RES}

    begin
      Application.Initialize;
      Application.CreateForm(TForm1, Form1); // создание Form1 
      Application.CreateForm(TForm2, Form2); // создание Form2 
      Application.Run;
    end.


Чтобы  Delphi не создавала формы , как показано выше, необходимо сделать следующее:
    -Зайти в  PROJECT MANAGER (Menu)
        -Выбрать пункт  OPTIONS
            -и переместить Form2 из левого бокса в правый

Файл  .dpr изменится следующим образом :
  begin
    Application.Initialize;
    Application.CreateForm(TForm1, Form1); // Только Form1 создается
    Application.Run;
  end.


2) Динамическое создание вашей Формы в коде

  procedure TForm1.ShowF2BtnClick(Sender: TObject);
  begin
    Form2:=TForm2.Create(self); // Создаем Form2
    Form2.ShowModal;
    Form2.Free;                // Освобождаем Form2
  end;


Преимущества и недостатки автоматического и динамического создания форм?

1) Автоматическое
    Преимущества:   -Все формы создаются для вас одновременно
                                -Ваша программа не ждет, пока  Delphi создаст формы

    Недостатки:        -В начале программы затрачивается больше времени на создание форм
                                -Используется больше памяти для хранения созданных форм

2) Динамическое
    Преимущества:   -Используется меньше памяти
                                - Программа стартует быстрее

   Недостатки:         -Задержка в программе на время создания форм
                                -Если в ваших формах  есть утечки памяти, то каждый раз при создании и освобождении формы памяти будет    теряться все больше и больше.
 

Примечание Франка:

Если у вас в программе больше чем  20 форм, пусть  Delphi создает их автоматически. В данном случае нет преимуществ в динамическом создании форм и даже могут возникнуть некоторые проблемы с памятью при создании и освобождении форм..


Согласование типов

var XInt  : integer;
    XByte : byte;
    XChar : char;
    XBoolean : boolean;

XInt:=Integer('A');   // XInt = 65    преобразование(char to int)
XByte:=Byte('A');     // XByte = 65   преобразование(char to byte)

XBoolean:=Boolean(0); // XBoolean = False

XChar:=char(65);      // XChar = 'A'  преобразование(byte to char)

XChar:=chr(65);       // XChar = 'A'  chr( ) - функция
XByte:=ord('A');      // XByte = 65   ord( ) - функция


Заметки:

Я собирался разобраться с использованием компонента MaskEdit (с которым я мало знаком).
Итак, я начал искать примеры компонентов MaskEdits среди более чем  3000 *.pas файлов на CD диске от книги.

Ну и как вы думаете, сколько файлов я нашел?  11
Боже мой, а я то думал что множество людей хотят фильтровать ввод пользователя.  Они это делают, но не с компонентом MaskEdit.

Не удивительно, почему я не использую много компонент  MaskEdit .  Никто этого не делает.
О чем это говорит?  С уверенностью можно сказать, что MaskEdit не очень универсальный компонент и ,вдобавок, трудный в использовании.
Справочно,  я поискал примеры использования компонента  TEdit  (в более чем  3000 *.pas файлах) и нашел 523


Один из своеобразных путей группировки стандартных компонентов  Delphi:
 
 
Контейнеры:
    Panel     GroupBox     PageControl
    DBRadioGroup
Навигация:
    ScrollBar        UpDown 
    DBNavigator  TabControl
Невизуальные:
  Timer    DataSource 
  Table    Query
Сетки:
    StringGrid 
    DBGrid
Графические:
    Shape 
    Image
Ввод данных:
    Edit           MaskEdit 
    RichEdit    DBEdit
Выбор:
    Button          SpeedBtn 
    BitBtn          RadioButton
    MainMenu   PopupMenu 
    DateTimePicker   TrackBar
    CheckBox
Отображение:
   Label        StaticText     StatusBar 
   ToolBar    CoolBar
   Splitter      Chart
   TreeView   ListView
   HeaderControl   ProgressBar
Списки:
   ListBox        Memo   ComboBox
   CheckListBox           DBListBox
   DBMemo         DBComboBox
   DBCheckBox   DBLookupComboBox
   DBLookupListBox

Пока это все.

Frank

Возврат в список переводов

 Lesson 1
 Lesson 2
 Lesson 3