eManual - электронная документация
Создание проекта
Visual FoxPro CLUB
Проект
Я знаю людей,
которые в FoxPro для DOS использовали
проект только для генерации исполняемого файла. В Visual FoxPro проект - основа
всего.
Нажимайте: File
- New, по умолчанию вам сразу будет предложено
сделать проект - в появившемся меню уже выбран пункт Project.
Если вы выбираете кнопку New File придется
задать имя проекта, под которым он будет сохранен и вы получите окно проекта.
Есть еще кнопка
предполагающая использование Wizard.
Честно скажу
- после написания этих строк впервые решил её попробовать. Оказалось, что
с помощью Волшебника проект можно сделать со структурой директорий, в которые
потом Visual FoxPro будет разносить программы, базы, отчеты, но это же можно
сделать и без волшебника. Wizard-ы
вообще отдельный разговор - вероятно, это хорошая вещь, но пока с их помощью
мне не удалось сделать что-нибудь сложнее справочника.
Наполнение
проекта
Поговорим о проекте, придерживаясь
его страниц...
Базы данных
(Data)
Я полагаю, вы уже
представили какие таблицы базы данных вам будут нужны, набросали их структуры.
Теперь выберите в окне проекта вкладыш Data,
потом New и ... Вот тут нелишним будет напомнить, что Visual FoxPro имеет
базу данных (database) и таблицы (table),
которые в прошлом нестрого также называли базами данных. База данных Visual
FoxPro содержит данные о таблицах входящих в неё и структуру которых мы, собственно,
и создаём. Впрочем, таблицы могут быть и свободными, т.е. не входящие, не
включенные и не учтенные в файле базы данных (database).
При этом они утрачивают так много полезных свойств, что я стараюсь их не отпускать
на свободу без крайней необходимости.
Коды
(Подробнее см. описание переменной
_screen
|
*_screen.Width=200
|
|
*_screen.Height=50
|
|
_screen.caption=[Просмотр]
|
|
_screen.BorderStyle=1
|
|
_screen.Closable=.F.
|
|
_screen.ControlBox=.T.
|
|
_screen.MaxButton=.T.
|
|
_screen.MinButton=.T.
|
|
|
|
**-- Releases all Visual FoxPro toolbars
|
Этот фрагмент кода скрывает инструментальные
линейки.
|
DIMENSION ToolBars[11,2]
|
Формируется массив зарезервированных
имен...
|
ToolBars[1,1] = "FORM DESIGNER"
|
|
ToolBars[2,1] = "STANDARD"
|
|
ToolBars[3,1] = "LAYOUT"
|
|
ToolBars[4,1] = "QUERY"
|
|
ToolBars[5,1] = "VIEWD ESIGNER"
|
|
ToolBars[6,1] = "COLOR PALETTE"
|
|
ToolBars[7,1] = "FORM CONTROLS"
|
|
ToolBars[8,1] = "DATABASE DESIGNER"
|
|
ToolBars[9,1] = "REPORT DESIGNER"
|
|
ToolBars[10,1] = "REPORT CONTROLS"
|
|
ToolBars[11,1] = "PRINT PREVIEW"
|
|
|
|
FOR i = 1 TO ALEN(ToolBars, 1)
|
... и организуется цикл для сокрытия
инструментов.
|
ToolBars[i,2] = WVISIBLE(ToolBars[i,1])
|
|
IF ToolBars[i,2]
|
|
HIDE WINDOW (ToolBars[i,1])
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
*~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
set date british
|
Набор некоторых начальных установок.
Можно его и не
|
set escape off
|
делать, но стоит ли для каждого
экрана упоминать,
|
set delete on
|
что safety должно быть off, а
delete on ?
|
set notify on
|
|
set brstatus off
|
|
set status off
|
|
set talk off
|
|
set echo off
|
|
set step off
|
|
set safety off
|
|
|
|
*~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
SET SYSMENU OFF
|
Отключаем системное меню. Что
вместо него? Об этом ниже.
|
on key label F2 do form calk
|
Здесь же можно определить нужные
функциональные клавиши.
|
|
|
do form mainscr
|
Вызов Главной формы (по секрету
- она и есть главное меню).
|
read event
|
Оператор, без которого формы
не задерживаются на экране.
|
|
|
Clear events e=1>&&
это включено в форму mainscr
|
Можно это поставить здесь, а
можно и в форме. Наличие обязательно, иначе приложение не выгружается
из памяти. Наблюдался случай, когда расположение здесь оказалось неэффективным
и работало только в кнопке выхода их формы.
В Visual FoxPro команда Quit
понижена в должности и далеко
не все закрывает и заканчивает.
|
close databases
|
Закрываем базу данных
|
close all
|
Закрываем всё.
|
clear all
|
Очищаем всё. В общем изо всех
сил готовимся к выходу.
|
quit
|
Вот теперь и сам выход.
|
Другие коды
Это старые добрые
PRG-файлы. Без них не обойтись
даже в Visual FoxPro. По большей части это пользовательские процедуры и особо
сложные модули расчетов. Процедуры - понятно почему: к ним обращаются из разных
методов разных объектов и, естественно, их многократные копии ни к чему. Что
касается модулей расчетов, то, во-первых, их легче искать, во-вторых, отлаживать
не обращаясь к формам и объектам, в-третьих, больше шансов не удалить случайно
вместе с объектом. Врочем, я не настаиваю на самостоятельном существовании
расчетов.
Возможен и другой
подход, основанный на способности Visual FoxPro из метода одного объекта вызывать
метод другого. Например, у вас есть несколько полей ввода при выходе из которых
введённая информация обрабатывается по одной формуле. Поместить её в LostFocus
каждого объекта, естественно, малограмотно. Можно
оформить в виде PRG-файла и в нужных местах
ссылаться на него, но не много ли чести для одной формулки? А можно её поместить
в практически неиспользуемый метод какого-нибудь объекта. Если итог ввода
всей информации- ту же сумму - вы показываете в виде изменяемого заголовка
метки (пример
для начинающих: thisform.label1.caption=str(summa)
), то расчет можно поместить в метод Click
для метки (вызов: thisform.label1.click).
Вряд ли кто будет “кликать” по числу суммы, но даже если это и случиться,
то просто снова всё что надо сложится. Здесь главное для себя логически обосновать
выбор объекта и метода, где будет находиться формула, чтобы при необходимости
её можно было бы без труда найти.
Документы
Формы
Главный экран
Вот так выглядит
главный экран (он же - главное меню) в моем исполнении. Простая многостраничная
форма, в которой заголовки страниц выполняют роль линейки меню, опции расположены
на страницах и представляют собой метки (Label),
для которых выполняется метод Click. Внешняя
привлекательность достигается созданием BMP-картинок
и размещением их на страницах.
Рабочий экран
Если
структура баз определена и сами они созданы - можете воспользоваться Wizard-ом.
Он, задав ряд вопросов, создаст сносную экранную форму и расставит куда надо
какие надо кнопки. И всё будет работать. Только весь текст, какой там окажется
придется перевести на русский.
Я формы всегда
создаю вручную. За то они и получаются такие, как мне надо, а не как прописано
в базовом визардовском классе от Microsoft.
Формы располагаются
в соответствующем разделе на странице проекта Documents.
Нажмите кнопку New и
получите заготовку для экрана. Начните
с создания окружения Data Environment. Все
таблицы, которые вы в него поместите будут открываться при вызове формы соблюдая
установленные связи и закрываться при её отмене. Вам лишь останется при написании
необходимого кода указать select <нужная
область по имени таблицы>.
Создав окружение,
возвращайтесь в окно построителя экранной формы и наполняйте её нужными вам
объектами.
Что такое объект
в Visual FoxPro? Отступая от официального трактования скажу, что это - любая
закорючка на поле формы, т.е. даже линия, рамка, текст, не говоря уж о полях
ввода, кнопках, сетках (grid).
Да и сама форма - тоже объект, если исходить из того, что объект имеет свойства
и методы. Разница заключается в том, что одни объекты сложные - они в себе
содержат другие объекты и в этом случае называются контейнерами, а другие
простые - существуют сами по себе.
Свойства. Это некие
качества присущие объекту (чайник горячий, шрифт красный, кнопка скрытая).
Свойства объектов в процессе работы могут меняться, например, на время заполнения
поля какие-то кнопки могут стать недоступными.
Методы. Это то,
что можно делать с объектом. По кирпичу можно стукнуть, по кнопке -“кликнуть”
- указать мышью и нажать её клавишу. Программно на объект можно указать переведя
на него “фокус” - метод SetFocus.
Объектом является
и сама экранная форма, причем, объектом-контейнером и имеет собственные свойства
и методы. Как изменить цвет фона, размеры окна и прочее легко разобраться
самостоятельно. Я же остановлюсь на взаимодействии форм и борьбе с главным
окном Visual FoxPro.
Вы наверняка захотите,
чтобы ваше приложение в виде исполняемого файла производило впечатление самостоятельной
величины, а не некоего хвоста при Visual FoxPro. Для этого (а кроме того и
по эстетическим соображениям) надо избавиться от главного окна. Достаточно
в файле config.fpw поместить
строку SCREEN=OFF и при загрузке приложения
от окна FoxPro не останется и следа, но! - очень может быть, что при этом
вы не увидите и своего стартового экрана. Почему? Потому, что по умолчанию
все создаваемые экраны ориентированы на появление именно в основном окне Visual
FoxPro. Нет окна - нет и приложений? Тогда поступайте не по умолчанию. Обратите
внимание на следующие свойства формы и задайте им показанные здесь значения:
AlwaysOnTop
|
.T.
|
AutoCenter
|
.T.
|
ShowTips
|
.T. (если хотите,
чтобы возле элементов управления появлялись флажки с подсказками)
|
ShowWindow
|
2 - As Top-Level Form
|
WindowType
|
0 - Modeless (немодальное)
|
Это
я делаю практически для всех форм, и они послушно появляются друг над другом
на фоне рабочего стола Windows. Все формы
управляются одним READ EVENT, упомянутым
в стартовом файле.
Уже после написания
этих строк случилась заморочка, которая отняла два рабочих дня на свою ликвидацию.
Случай, казалось бы, простейший - просмотровый экран с Grid
(сеткой)и кнопками управления.
При нажатии кнопки “Поиск” вызывается экран поиска по условию поверх просмотрового.
Установки окон - описанные выше. Естественно, после нажатия любой кнопки я
заставил фокус возвращаться на Grid
- это комфортно, т. к. в сетке данные не только просматривались но и должны
были редактироваться, в общем, чтобы лишний раз не щелкать мышью, сетка становилась
активной после отработки любой кнопки. Программно в метод Click кнопки
я записал следующее:
do form searchform
|
вызов экрана поиска
|
thisform.refresh
|
“освежение” родительской
формы
|
thisform.grid1.setfocus
|
установка фокуса на
сетку
|
Вероятно, человек более
искушенный сразу сообразил бы что к чему, когда дочерняя форма вдруг заупрямилась
и категорически отказалась появляться поверх родительской невзирая на какие-то
ни было установки. Я же понял в чем дело, только включив Отладчик и проследив
построчно выполнение кода. Строка thisform.grid1.setfocus не только переводит
фокус, но и активизирует форму, в результате чего ранее вызванная searchform
пропадает под родительским окном просмотрового экрана. Более общий вывод -
программа не задерживается на строке do form searchform, а выполняет весь
набор строк кода принадлежащий данному методу. Я объясняю это тем, что всё
приложение управляется единственным READ EVENTS,
упомянутым в стартовом файле. Стоило поменять последовательность строк на
thisform.grid1.setfocus
|
установка фокуса на сетку
|
do form searchform
|
вызов экрана поиска
|
thisform.refresh
|
“освежение” родительской
формы
|
и все стало как надо.
И на какую ерунду порой уходит время!
Есть особые случаи,
когда главное окно Visual FoxPro необходимо, например, предварительный просмотр
отчета (PREVIEW) возможен
только в нём. Тогда применяем такой маневр:
_Screen.Show
|
report form ... preview
|
_Screen.Hide
|
т.е.
показываем окно Visual FoxPro, выводим на просмотр отчет, скрываем окно.
При этом
я не могу отделаться от мысли, что преодолеваю трудности порожденные головокружением
от собственного величия разработчиков Visual FoxPro (Microsoft).
Ну действительно, когда мыслями весь в сетях, серверах, ODBC-ях,
до отчетов ли тут, которые практически не изменялись с версии 2.6 для DOS.
Хорошо хоть к пятой версии с главным окном научились
бороться...
Отчеты
Разбираясь
со всевозможными казусами и заставляя приложение работать как того хочется
мне, а не ему, я пришёл к мысли, что не могу с уверенностью сказать кому принадлежит
очередной программный “глюк” - моему непрофессионализму или ошибке разработчиков.
Пример - печать отчетов.
Документация и пособия
скрупулёзно описывают такие команды как SET DEVICE TO,
SET PRINT TO, SET CONSOLE OFF, и прочее, чем
я пользовался в версиях DOS. В Visual
FoxPro (по крайней мере в моём от 21 августа 1996 г. Официальном.) достаточно
иметь строку REPORT FORM <Имя отчета>
NOCONSOLE TO PRINT - и всё! Когда я её обрамил (как, я думал, принято) командами
SET PRINT ON и SET PRINT OFF приложение
по завершении просто не выгружалось из памяти. А использование команды
SET PRINT TO приводило к неустранимой протяжке
пустой страницы после печати. Это что - ошибка Visual FoxPro? Во всяком случае,
нигде в документации не предупреждают, что некоторыми командами пользоваться
просто нельзя.
Классы
Одним из достоинств
объектно-ориентированного программирования и Visual FoxPro, в частности, объявляется
возможность использовать готовые классы и создавать собственные.
Отступая от канонов
я бы назвал класс набором объектов и их взаимодействий, т. е. некоторый шаблон,
который можно использовать в своем приложении. В сущности, все объекты, которые
мы вставляем в приложения есть порождение неких классов присущих Visual FoxPro.
И практически понимание класса и его роли в программировании отдельно взятого
приложения этим можно ограничить. Почему? Позволю себе некоторые рассуждения
на эту тему.
Наиболее отчетливо
программирование с использованием классов можно прочувствовать на примере
Wizard-ов экранных форм.
Существует определенный шаблон (класс), который “Волшебник” использует при
построении экрана. Строго говоря, там целая куча всяких мелких классиков состоящих
в сложных родственных отношениях, но мы на выходе, в виде готовой формы, получаем
конструкцию, которая при попытке что-либо изменить в своем внешнем облике
невозмутимо заявляет, что породивший ее класс категорически против какого
бы то ни было вмешательства в ее личную жизнь. Кроме того, интерфейс вообще
получается англоязычным. Насколько это удобно? Удобно (только не английский
для престарелой бухгалтерши!), если вы делаете пару десятков экранов без требований
к их разнообразию. Классы - враги разнообразия. Они его органически не переваривают.
Как достоинство классов разработчиками превозносится Наследование (“...
Обеспечивает автоматическое изменение свойств подклассов при изменении свойств
базового класса”. Документация.). Но, во-первых, если подклассы используются
в разных приложениях, то изменения вступят в силу очевидно только после перекомпиляции
приложений, во-вторых, изменения коснуться всех дочерних форм, а если
мне этого не надо?
Мнение программистов
с которыми я общался таково, что классы, в том числе и созданные пользователями
(а может и только они), хороши для разработки крупных проектов в больших программистских
коллективах, а одинокий возделыватель нивы программного обеспечения вполне,
и с комфортом!, может использовать нечто в роде простых шаблонов. Ну уж если
очень хочется можно и собственный класс сделать, только не забудьте очень
тщательно продумать то, что он передаст по наследству - его отпрыскам придется
самим приспосабливаться к тем местам, где будут работать. Поясню. Если вы
оформите как класс набор кнопок - перемещение по записям, печать, поиск, выход
- то для формы, в которой печать не нужна, соответствующая кнопка должна отсутствовать.
Поэтому, либо родительский класс кнопок должен быть так устроен, чтобы отпрыск
позволял скрыть ненужное без обращения к “папе”, либо не оформляйте набор
как класс - просто копируйте его откуда-то где он у вас храниться и дальше
делайте с ним, что хотите.
Классы в проекте
помещаются на одноименную вкладку. Если вы воспользовались Wizard-ом,
он сам накидает в проект всё, что нужно.
Прочие
(Other)
Меню - без комментариев.
Поскольку существующий Wizard
и его продукцию не люблю, то и не делаю.
Категорию
текстовых файлов попадает файл конфигурации. Если вы его поместите в проект,
пользователю в наборе файлов приложения он уже не будет нужен.
Прочие в прочих.
Сюда удобно поместить BMP-картинки,
которые вы использовали для фона экранных форм. Они после компиляции также
окажутся в исполняемом модуле (отчего он изрядно “пополнеет”). А вот звуковые
файлы *.WAV в проект включать нет смысла
- они в ЕХЕ-шник не включаются и пользователю передаются в явном виде.
|