Як виділити (помітити, позначити) головний файл, FoxPro, Бази даних, статті

На етапі створення готового EXE-файлу всі наші файли включаються в загальний файл
проекту (файли з розширенням PJX і PJT). Файл проекту – це засіб якось
порядок ту купу файлів, з якої згодом буде зібрано готовий
EXE-файл, а, крім того, це інструмент власне складання EXE-файла.


Так от, в FoxPro головний (стартовий) файл може бути позначений тільки й
виключно всередині файлу-проекту
. Не існує ніяких особливих ключових
слів або синтаксичних конструкцій для його виділення в програмному коді.


За замовчуванням, перший доданий до проекту файл автоматично ставати
головним (якщо це можливо). Такий файл виділяється в проекті жирним шрифтом.


Якщо Вас не влаштовує такий автоматичний вибір, то Ви можете в будь-
момент вказати як головного (стартового) файлу потрібний Вам файл. Для цього
клацніть всередині проекту правою кнопкою миші по потрібному файлу і в який з'явився
меню виберіть пункт "Set Main". Обраний файл буде виділено жирним шрифтом, а
файл, раніше позначений як головний (стартовий) файл, скине своє виділення і
стане звичайним (не головним) файлом.


У межах одного файлу – проекту може бути тільки один головний (стартовий)
файл


В принципі, допустимо взагалі не вказувати головний (стартовий) файл. Однак з
такого проекту неможливо буде створити готового EXE-файлу. На етапі компіляції
виникне помилка з повідомленням про те, що Ви не вказали головний (стартовий) файл
проекту.


Який тип файлу зробити головним


Головним (стартовим) файлом може бути



Ну, по суті, файл меню – це і є програмний файл. Так історично
склалося. Точніше, розробники FoxPro поки "не доросли" до корінної переробки
ідеології побудови меню, як вони це зробили з формами, а в 9 версії і з
звітами.


Справа в тому, що хоча на етапі проектування меню – це файли з розширенням
MNT, MNX, але після створення макета меню необхідно запустити його генерацію.
Результатом генерації меню стають файли MPR, MPX. Ось ці-то файли і є
звичайні файли PRG і FXP, тільки зі зміненим розширенням.


Отже, по суті, вибір стоїть між програмним файлом і файлом
форми.


Так от, завжди вказуйте в якості головного (стартового) файлу
програмний файл
. Більш того, це повинен бути саме файл PRG і ніщо
інше.


Причин цьому безліч. У міру подальшого обговорення Ви побачите, що дуже
багато чого з того, що треба зробити в головному (стартовому) файлі дуже важко, а
іноді й просто неможливо реалізувати у формі.


В принципі, в залежності від конкретного завдання, частина операцій в головному
(Стартовому) файлі, які будуть описані далі, можна і не виконувати. А
залишилися операції можна "втиснути" в форму. Але я не радив би цього робити.
Програми мають "звичку" розростатися. А використання в якості головного
(Стартового) файлу форми сильно звужує можливість модифікації.


Ідеологія побудови програми


Вміст головного (стартового) файлу проекту залежить в першу чергу від
конкретного завдання. Наприклад, якщо метою Вашого проекту є створення
COM-сервера, то в головному (стартовому) файлі взагалі нічого не буде.


У FoxPro існують такі ідеології побудови програм:



Побудова програми на базі основного вікна FoxPro (SCREEN) припускає,
що в кінцевому додатку користувач буде бачити це основне вікно
(Зрозуміло, зі своїм меню і ToolBar) і всі форми будуть відкриватися всередині цього
основного вікна.


Побудова програми на базі "As Top-Level" форм припускає, що основна
вікно FoxPro (SCREEN) взагалі не буде відображатися в кінцевому додатку. А в
Як основний вікна буде виступати створене програмістом вікно зі
властивістю ShowWindow = 2 – "As Top-Level form"


Чесно кажучи, я не бачу особливого сенсу в побудові програм на базі "As
Top-Level "форм. Адже навіть у такому додатку, так чи інакше, необхідно буде
створити головну форму. А навіщо, коли ця форма і так вже є (основне вікно
FoxPro)?


Як елемент інтерфейсу (наприклад, для введення пароля при вході в програму) "As
Top-Level "форми цілком на своєму місці. Але будувати весь додаток цілком на їх
основі мені представляється нерозумною. Та й програмно це трохи складніше.
Втім, це тема для окремого обговорення.


Подальший опис вмісту головного (стартового) файлу буде стротіться
виходячи з припущення, що створюється додаток на базі основного вікна FoxPro
(SCREEN). Втім, навіть якщо Ви будуєте додаток на базі "As Top-Level" форм
вміст головного (стартового) файлу залишиться практично таким же. Відмінності
будуть в деяких деталях. У міру опису я буду вказувати на ці деталі.


Точка зупину. Read Events


При створенні програми основним керуючим елементом всього програми
є головне меню. Це означає, що в головній (стартової) програмі
необхідно зробити виклик цього меню


DO MainMenu.mpr


Синтаксично все абсолютно правильно. Більше того, коли Ви будете запускати
головний (стартовий) файл на етапі розробки програми все буде працювати
нормально. Але ось після того, як Ви створите готовий EXE-файл і запустіть його,
то замість очікуваного програми Ви побачите "дивний" ефект.


Вікно FoxPro промайне на екрані і тут же закриється.


Причиною такого "дивного" поведінки є те, що Ви "забули" вказати
FoxPro, в якому місці йому треба зупинитися і почекати реакції користувача. На
етапі налагодження такої "точкою зупинки" є раніше відкрите середовище FoxPro. Але в
готовому файлі EXE до нього ніякої середовища FoxPro відкрито не було! Щоб створити
"Точку зупину" треба дати спеціальну команду


READ EVENTS


Тобто вміст головного (стартового) файлу буде виглядати так:


DO MainMenu.mpr READ EVENTS


Ось тепер, в готовому файлі EXE, коли програма дійде до команди READ
EVENTS, то відбудеться зупинка в очікуванні реакції користувача.


Майте на увазі, що одночасно, в усьому додатку може бути активна тільки
одна команда READ EVENTS. Виклик іншої команди READ EVENTS не призведе до помилки,
але ця команда буде просто проігнорована. Щоб скасувати дію команди
READ EVENTS треба дати спеціальну команду


CLEAR EVENTS


За цією командою буде скасовано дію команди READ EVENTS і виконання
перейде на команду, наступну за командою READ EVENTS. Тобто, якщо Ви дали
команду CLEAR EVENTS у будь-якій процедурі, то все те, що варто слідом за цією
командою взагалі ніколи не буде виконано.


Так, де ж давати команду CLEAR EVENTS? Зрозуміло, у спеціальному пункті
меню "Вихід".


Якщо Ви створюєте додаток на базі "As Top-Level" форм, то команду CLEAR
EVENTS треба давати в події UNLOAD Вашої головної форми.


Разом, виходить приблизно така логіка:



Аварійне припинення програми. Налаштування ON
ShutDown


До цих пір, мова йшла про "штатному" завершення. Тобто коли користувач
дисципліновано використовує всі належні пункти меню для виходу з
програми. Але ж користувач може закрити програму, натиснувши на хрестик у
правому верхньому куті основного вікна FoxPro або, наприклад, через вікно "Диспетчер
завдань Windows "(Ctrl + Shift + Esc).


Якщо все залишити так, як було описано до сих пір, то після такої спроби
користувача вискочить повідомлення про помилку


Cann”t quit Visual FoxPro


Причина такого повідомлення в тому, що залишилася активної команда READ EVENTS.
Саме вона і викликає таке повідомлення про помилку в описаній ситуації. Щоб
перехопити описані події закриття програми використовується спеціальна
настройка


ON SHUTDOWN


В принципі, можна просто написати


ON SHUTDOWN CLEAR EVENTS


Але, зазвичай перед закриттям програми треба виконати ряд попередніх
операцій. Яких? Це вже залежить від Вашого застосування. Ну, наприклад, можна
запитати користувача про те, чи дійсно він хоче вийти з програми або
це в нього "рука здригнулася". У загальному випадку однієї команди недостатньо. Потрібен
виклик процедури. Наприклад:


ON SHUTDOWN DO MyExitProcedure


І ось вже в цій процедурі MyExitProcedure і треба дати команду CLEAR EVENTS.
Причому ця команда повинна бути самою останньою, оскільки в момент її виконання
управління буде передано на команду, наступну за командою READ EVENTS і все
те, що написано після CLEAR EVENTS просто не буде виконано.


Для універсальності, бажано в пункті меню "Вихід", замість простої команди
CLEAR EVENTS також зробити виклик цієї процедури. Тоді у Вас буде один спільний
код, що обробляє вихід з Вашого застосування при будь-яких ситуаціях.


В принципі, власне процедуру MyExitProcedure можна розташувати в головному
(Стартовому) файлі. Оскільки головний (стартовий) файл – це "кореневої" файл, з
якого здійснюється виклик будь-яких інших файлів, то розташована таким
чином процедура буде "видно" і доступна з будь-якого місця Вашого
програми.


Проте я все-таки радив би винести цю процедуру в окремий однойменний
файл PRG або в метод якогось глобального об'єкта. Причина цієї рекомендації в
те, що окремий файл або метод класу простіше модифікувати.


Якщо Ви робите додаток на базі "As Top-Level" форм, то виклик цієї
процедури треба організувати ще й у події QueryUnload головної форми. Точніше
так, у події QueryUnload головної форми треба перенаправити виклик на власне
метод, що організує закриття всього програми.


В результаті, вміст головного (стартового) файлу набуває наступний
вид


ON SHUTDOWN DO MyExitProcedure DO MainMenu.mpr READ EVENTS


Чи треба давати команду QUIT для закриття програми


У FoxPro існує команда QUIT, яка призводить до негайного закриття
програми FoxPro. Правда ця команда також перехоплюється налаштуванням ON
SHUTDOWN і також по ній неможливо вийти з програми, якщо активна команда
READ EVENTS.


Виникає резонне питання, а чи потрібна ця команда, якщо додаток FoxPro і
так само закриється, коли завершиться виконання головного (стартового) файлу?


Ну, особисто я вважаю, що це команда для лінивих програмістів. Тобто для тих,
кому лінь відстежувати всі відкриті в додатку об'єкти. Як я вже згадував
раніше, закриття програми в загальному випадку – це дуже не тривіальна задача.


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


По "правильному" логічно запитати користувача чи бажає він зберегти
внесені зміни. Тобто організувати "штатний" закриття всіх відкритих
об'єктів. А команда QUIT просто "розчавить" всі відкриті об'єкти без будь-яких
додаткових питань і все!


Є і більш тонкі моменти. Тобто по хорошому, у процедурі MyExitProcedure
треба організувати "штатний" закриття всіх відкритих об'єктів і після команди READ
EVENTS (де власне і передбачається давати команду QUIT) взагалі не повинно
залишитися нічого такого, що варто було б закривати саме командою QUIT. Якщо
все-таки щось залишилося, то це явна недоробка розробника. І ця
недоробка може дуже сильно "гукнутися" в готовому додатку. Без команди
QUIT Ви відловити цю проблему ще на стадії налагодження програми.


Крім того, використання команди QUIT може ускладнити налагодження. Що, кожен
разу після запуску головного (стартового) файлу заново відкривати середу FoxPro?
Втім, як це обійти, трохи нижче.


Разом, я не рекомендував би використовувати команду QUIT.


Як приховати головне вікно FoxPro (SCREEN)


У більшості випадків, незалежно від того в якій ідеології Ви
розробляєте свій додаток при завантаженні середовища FoxPro бажано приховати
головне вікно FoxPro (SCREEN). Якщо Ви розробляєте додаток в основному вікні
FoxPro, то потім його можна буде переглянути. Ну, а якщо додаток на базі "As
Top-Level "форм, то відображення його і не потрібно.


Можна першої ж командою в головному (стартовому) файлі дати команду

_SCREEN.Visible = .F.

Вікно FoxPro дійсно сховається. Однак перед цим встигне все-таки
"Майнути". Не добре.


Щоб придушити відкриття головного вікна слід використовувати файл конфігурації
Config.fpw. Це звичайний текстовий файл. У ньому повинна бути рядок:

SCREEN=OFF

Більш докладно про фото конфігурації розказано в інших розділах. Дана
стаття присвячена тільки головному (стартовому) файлу.


Щоб знову відобразити головне вікно FoxPro (SCREEN) слід дати команду

_SCREEN.Visible = .T.

Якщо головне вікно FoxPro (SCREEN) і до цієї команди було відображено, то від
цієї команди гірше не буде.


В результаті, вміст головного (стартового) файлу набуває наступний
вид

ON SHUTDOWN DO MyExitProcedure
DO MainMenu.mpr
_SCREEN.Visible = .T.
READ EVENTS

Як приховати системні ToolBar


Коли Ви запускаєте свій додаток в режимі налагодження, то системне меню
замінюється Вашим меню. Але ось системний ToolBar залишається "висіти", як ні в чому
не бувало.


Строго кажучи, на системний ToolBar можна взагалі не звертати уваги. Річ у
те, що інформація про те, які саме системні ToolBar відкриті і де саме
вони розташовані, зберігається в так званому "ресурсному файлі". За умовчанням, це
файл FoxUser.dbf і пов'язаний з ним файл FoxUser.fpt.


Зрозуміло, Ви не потягнете користувачеві цей ресурсний файл. Як наслідок,
на машині клієнта системні ToolBar взагалі не з'являться. Просто тому, що там
не буде ресурсного файлу з машини розробника.


Однак якщо на етапі налагодження Вам все-таки необхідно приховати системні
ToolBar, то це можна зробити набором команд


HIDE WINDOW


Ім'я того чи іншого ToolBar можна подивитися в заголовку самого ToolBar (якщо
він не "приклеєний" до меню) або через пункт меню View, підпункт ToolBars


Наприклад, приховати стандартну панель можна командою


HIDE WINDOW “Standard”


Знову активізувати стандартну панель можна командою


SHOW WINDOW “Standard”


Перевірити той факт, що та чи інша панель зараз активна можна
використовуючи команду WEXIST ()


IF WEXIST(“Standard”) = .T.       HIDE WINDOW “Standard” ENDIF


Таким чином, якщо Вам дуже хочеться приховати системні ToolBar в режимі
налагодження, то нескладно написати прості процедури їх закриття на початку головного
(Стартового) файлу і відновлення після команди CLEAR EVENTS.


Але, повторюся, особливого сенсу в готовому додатку це не має. Оскільки
там їх і так не буде.


Налаштування середовища FoxPro


Раніше я побіжно вже згадав той факт, що просто запустити середу FoxPro
недостатньо. Треба зробити деякі попередні налаштування. Хоча б
настройку ON SHUTDOWN.


Справа в тому, що середовище FoxPro за замовчуванням налаштована таким чином, щоб
полегшити створення нових і модифікацію старих додатків. Тобто вона налаштована для
зручності розробника. Але в готовому додатку така настройка середовища
FoxPro не просто некоректне. Вона може виявитися неприпустимою!


Взагалі-то, налаштувань середовища FoxPro багато. Навіть дуже багато. Однак на практиці,
для коректної роботи готового програми слід уточнити тільки кілька
налаштувань. Найбільше – два … три десятки.


Частина налаштувань середовища FoxPro можна побачити через пункт меню Tools, підпункт
Options. А щоб отримати ці настройки у вигляді кодів натисніть і потримайте
клавішу "Shift" і лівою кнопкою миші натисніть на кнопку "Ok". У командне вікно
буде виведено всі поточні налаштування форми Options. Ви можете їх просто
скопіювати і вставити в головний (стартовий) файл. Зрозуміло, заздалегідь
переглянувши, що саме з них дійсно потрібно для успішної роботи Вашого
програми.


Складність у тому, що на етапі налагодження програми все-таки потрібні декілька
інші настройки, ніж в готовому додатку.


Наприклад, на етапі налагодження добре б мати можливість перервати виконання
будь-якого процесу після натискання клавіші "Esc", але в готовому додатку цього
допускати в жодному разі не можна. Це регулює налаштування SET ESCAPE.


Тобто виходить, що необхідно якось відрізняти, в якому режимі було запущено
додаток. В режимі налагодження або як готовий файл EXE.


Є кілька варіантів визначення режимів роботи. Найпростіший – це
посмотреть значення властивості


_VFP.StartMode


Якщо ця властивість має значення 0, то ми знаходимося в режимі налагодження. Тобто
виходить щось на кшталт:

 * Загальні настройки незалежно від режиму роботи
IF _VFP.StartMode = 0
* Установки тільки для режиму налагодження
ELSE
* Установки тільки для готового програми
ENDIF

Є й ще одна проблема налаштувань. Справа в тому, що при відкритті Private
DataSession частина установок, пов'язаних з роботою з даними скидаються в
значення за замовчуванням. Повний список таких настройок Ви можете подивитися в
описі до команди "SET DataSession". Причому для деяких налаштувань ці самі
значення за замовчуванням відрізняються залежно від того, в якій DataSession ми
перебуваємо.


Тобто виходить, що недостатньо просто один раз зробити налаштування в головному
(Стартовому) файлі. Потрібно ще повторити частина настройок в кожній Private
DataSession.


Отже, виконання налаштувань середовища FoxPro треба винести або в окрему
процедуру, або оформити як метод класу. Якщо як метод класу, то або як
метод якоїсь базової форми, на основі якої будуть створені всі форми Вашого
проекту, або як метод класу Custom, примірник якого буде "кидатися" на
потрібні форми.


Нарешті, ще одна проблема налаштувань. По завершенні роботи програми треба
повернути налаштування в той стан, в якому вони були на момент запуску
програми.


На перший погляд, це здається абсолютно безглуздим вимогою. Але не треба
забувати, що ми налагоджує наш додаток. Це означає, що є частина
налаштувань, які просто зобов'язані відрізнятися в залежності від того, просто ми
налагоджує якусь форму (процедуру) або запустили програму в режимі налагодження,
починаючи з головного (стартового) файлу.


Наприклад, при налагодженні тригерів добре б бачити записи позначені як
видалені. Але в готовому додатку, навіть при запуску в режимі налагодження, нам
бачити ці записи не треба. Це регулює налаштування SET DELETED


Та й в будь-якому випадку бажано завжди дотримуватися принципу: насмітив, прибери за
собою. Для програмування це особливо важливо у всіх сенсах.


Таким чином, у загальному випадку, робота з налаштуваннями виглядає приблизно
так:



З цієї логіки випливає, що використовувати процедури в принципі можна, але дуже
вже незручно. Потрібні дві окремі процедури для установки і для відновлення
налаштувань. А, крім того, потрібно десь зберігати старі налаштування.


Більш зручним здається використання класів. Створюються два методи одного і
того ж класу (можливо більше, адже для Private DataSession треба встановити
тільки частина налаштувань). А для зберігання старих значень налаштувань можна
використовувати властивості (Properties) класу.


Тоді залишається уточнити, чи використовувати клас Custom або клас на базі
Form?


За великим рахунком – це абсолютно однакові варіанти. Слід тільки
пам'ятати, що методи класу Custom можна запустити не раніше події Init цього
класу. Але в будь-якому випадку методи власне форми або будь-яких її об'єктів ще не
існують на момент виконання події BeforOpenTables в DataEnvironment форми.
Тобто автоматичне відкриття таблиць, включених до DataEnvironment форми,
станеться з використанням настройок за замовчуванням.


Але в більшості випадків, це не настільки вже й принципово. Справа в тому, що
критичними (принципово важливими) в момент відкриття таблиць є наступні
налаштування:

SET DELETED
SET EXCLUSIVE
SET MULTILOCKS

Всі інші налаштування цілком можна зробити вже після відкриття таблиць. Вони
впливають вже власне на роботу з відкритими таблицями, а не на їх відкриття.


Налаштування SET DELETED принципово важлива, якщо в DataEnvironment включено
Local View, оскільки просто немає іншого способу відсікти записи, позначені як
вилучені, щоб вони не потрапили в Local View. Але зазвичай Local View включають в
DataEnvironment з опцією NoDataOnLoad =. T. і наповнюють даними в Init-форми. Тобто
коли настройка SET DELETED вже зроблена в наших методах


Налаштування SET EXCLUSIVE має різне значення за замовчуванням для Default і
Private DataSession. У Private DataSession вона має значення OFF, що
власне і треба. А в Default DataSession використовується раніше зроблена у тій же
DataSession настройка. Якщо ж для окремих таблиць принципово важливо відкрити
їх у режимі Exclusive, то використовуйте однойменне властивість курсора в
DataEnvironment – форми.


Налаштування SET MULTILOCKS потрібна, якщо робиться настройка режиму буферизації
безпосередньо у властивостях курсору в DataEnvironment – форми. Але в цьому випадку
FoxPro сам робить потрібну настройку. Тобто знову ж таки немає необхідності в ручній
попередньої настройки.


Повертаючись до вмісту нашого головного (стартового) файлу отримуємо, що
його вміст вже виглядає приблизно так:

 * Підключаю бібліотеку класів, яка містить ряд корисних класів загального призначення
LOCAL loSetting, llIsClass
IF "MyClass.VCX" $ SET("ClassLib")
      llIsClass = .T.
ELSE
      llIsClass = .F.
SET CLASSLIB TO MyClass ADDITIVE
ENDIF

* Клас, що встановлює глобальні налаштування середовища (знаходиться в MyClass.VCX)
loSetting = CREATEOBJECT("Setting")

ON SHUTDOWN DO MyExitProcedure
PUSH MENU _MSYSMENU
DO MainMenu.mpr
_SCREEN.Visible = .T.
READ EVENTS

********* Відновлення початкових настройок
ON SHUTDOWN
POP MENU _MSYSMENU
IF m.llIsClass=.F.
      RELEASE CLASSLIB MyClass
ENDIF


Тут я припускаю, що в бібліотеці класів MyClass.VCX є клас
"Setting" у події Init, якого відбувається встановлення потрібних налаштувань, а в
подію Destroy відновлення вихідних налаштувань. Тобто видалення змінної
m.loSetting означає автоматичне відновлення вихідних налаштувань.


Ще використані додаткові команди PUSH MENU і POP MENU, які
зберігають і відновлюють системне меню FoxPro.


Зверніть увагу на те, що змінні оголошуються як LOCAL. Справа в тому,
що якщо не оголосити змінні, то за умовчанням вони отримають контекст
PRIVATE. А для змінних головного (стартового) файлу це рівнозначно оголошенню
їх як PUBLIC, оскільки вони будуть видні в усіх викликаних формах і
процедурах.


Як бачите, головний (стартовий) файл починає розростатися. З цим треба
щось робити. Чим більше лістинг програми (код одного методу або процедури),
тим складніше такий код налагоджувати і модифіковані.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*