Межоконное взаимодействие.

  1. Независимое окно
  2. Зависимое окно
  3. Подчиненное окно
  4. Справочное окно
  5. Определение порождающей зоны
  6. Перепривязка окна
  7. Связь зависимых окон с процессами порождающих зон
  8. Автоматическое закрывание зависимых окон
  9. Определение транзакции, для выполнения процессов в зависимых окнах
  10. Запрет перехода в окно с процессом, работающим не на последнем уровне транзакции
  11. Зависимые окна, в которых не смог выполниться видеоконформ

Окна по своей структуре делятся на независимые по определению (например окно RWayS (мастер окна и 1-й зоны - файл RWayS), окно Staff_A (мастер окна и 1-й зоны - файл Staff)) и зависимые по определению, например, окно Money (мастер окна и 0-й зоны - файл Staff, 1-й зоны - файл Money, 2-й зоны - файл PCalc).

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

  1. Независимое. Может быть открыто в любой момент, независимо от наличия других открытых окон. Особенности обработки независимого окна:
    1. Межоконный конформ всегда идет из активной зоны верхнего окна в мастер независимого окна.
    2. Неявным образом не закрываются
    3. Не наследуют транзакцию из чужих окон
    4. После закрытия текущим становится предыдущее по порядку окно, т.е. то, в которое попали бы при выполнении опции PrvWin (обычно на кнопке Gray*)

    Открыть независимое окно можно так:

    1. в качестве имени окна указать имя независимого по определению окна. Например, View(RWayS 1)
    2. в качестве имени окна указать имя зависимого или независимого по определению окна, указав в 3-м параметре опции символ @. Такое окно называется принудительно независимым. Например, View(Money 1 @). При прохождении конформа в мастер принудительно независимого окна вызывается программное событие OnConformToWindow.
  2. Зависимое. Может быть открыто на экране только в привязке к некому главному окну, а точнее к одной из его зон, которую будем называть порождающей зоной для данного зависимого окна. Логически зависимые окна дополняют главное окно.  Межоконная связь между порождающей зоной и мастером зависимого окна аналогична внутриоконной связи между зонами одного окна (см. принципы построения видео-окон). Можно считать, что при открытии зависимого окна образуется связь, аналогичная межзонной, в которой в качестве главенствующей зоны выступает порождающая зона, а в качестве подчиненной - мастер зависимого окна.

    Зоны зависимых окон в свою очередь тоже могут иметь зависимые окна. Таким образом образуется целое дерево зависимых окон, корнем которого является независимое окно. Такую совокупность окон будем называть кланом окон. Если представлять себе зависимые окна, как дополнительные зоны порождающего окна, то клан окон может рассматриваться, как одно виртуальное окно, в котором зоны связаны в единое дерево, корнем которого является мастер независимого окна. Это именно дерево, а не граф, а следовательно существует только один путь из любой зоны Z этого виртуального окна до корня дерева - мастера независимого окна. Промежуточные зоны этого пути будем называть транзитивно порождающими или транзитивно главенствующими зонами для зоны Z.

     Особенности обработки зависимого окна:

    1. Видеоконформ всегда идет из мастера порождающей зоны в мастер зависимого окна. Именно этим обеспечивается отображение в зависимом окне тех записей, которые относятся к текущей записи порождающей зоны.
    2. Автоматически закрывается (если это возможно) при завершении последнего процесса в порождающей зоне.
    3. Работает на транзакции того процесса порождающей зоны, из которого оно было открыто
    4. Панельная зона, непосредственно подчиненная зависимому окну, мастер которой совпадает с мастером собственного окна и мастером порождающей зоны, наследует некоторые свойства порождающей зоны:
      1. Если порождающая зона иерархическая, то при вставке новой записи поля связи с вышестоящим контейнером заполняются значениями так, что вставляемая запись становится подчиненной к исходной, а в режиме FORM_ZONE.ShowLeavesInHierarchicView поле "Leaf" вставляемой записи заполняется значением 0, и объявляется запрещенным к редактированию.
      2. Если при вставке/редактировании записи обнаруживается, что запись не удовлетворяет условиям фильтра и/или ручного селекта, то выдается сообщение с предложением снять фильтр именно в главном окне, а в зависимом уж как следствие. Аналогично в тексте исключения 234.
    5. После закрытия текущим становится главное окно.

    Открыть зависимое окно можно так:

    1. в качестве имени окна указать имя зависимого по определению окна. Например, View(Money 1). Окно откроется как зависимое к зоне окна, на контексте которого выполнена данная опция.
    2. в качестве имени окна указать имя зависимого или независимого по определению окна, указав в 3-м и 4-м параметрах опции соответственно окно и зону, к которым открываемое окно должно стать зависимым. Такое окно называется принудительно зависимым. Например, View(Money 1 RWayS 1) открывает окно Money, как принудительно зависимое от зоны 1 окна RWayS. При прохождении конформа в мастер принудительно зависимого окна вызывается программное событие OnConformToWindow.
  3. Подчиненное окно - частный случай зависимого окна. Это окно, имя которого указано в качестве Subwindow к некоторой зоне (свойство Subwindow в описателе зоны в WED; в объектной модели это FORM_ZONE.SubwindowOriginalName + FORM_ZONE.SubwindowAssignedName) , и открыто это окно было именно как подчиненное, т.е. с указанием "@" в качестве имени окна. Если мастер подчиненного окна совпадает с мастером порождающей зоны, такое окно называется натурально подчиненным. В противном случае окно становится принудительно подчиненным, и если с помощью системных связей не строится путь из мастера порождающей зоны в мастер принудительно подчиненного окна, то при прохождении конформа вызывается программное событие OnConformToWindow. Подчиненное окно обладает всеми свойствами зависимых окон, но имеет дополнительные особенности:
    1. Перемещение по записям в панели подчиненного окна (в процессах Edit, ShowWin) реализовано перемещением по записям порождающей зоны.
    2. Панель натурально подчиненного окна наследует из порождающей зоны текущий индекс сортировки, селект, представление, перманентный и пользовательский фильтры вместе с флагом FORM_ZONE.UserFilterIsActive, а также признак иерархии, FORM_ZONE.HierarchicLink, флаг FORM_ZONE.ShowLeavesInHierarchicView и т.п. Как следствие, перечисленные свойства в панели натурально подчиненного окна не доступны по записи (исключение 947)
    3. Подчиненные окна могут быть автоподменяемыми.
  4. Справочное окно - открывается при старте процесса Ask. Об этом здесь.

Некоторые особенности более подробно:

  1. Определение порождающей зоны. В момент открытия зависимого окна выполняется поиск его непосредственно порождающей зоны.

    Зона, которая была текущей при выполнении опции, открывающей зависимое окно, будем называть исходной зоной.

    Зону Z будем называть зоной-кандидатом на должность порождающей зоны для некоторого зависимого окна W, если мастер окна W совпадает с мастером зоны Z или является дальним справочником дальнего Lend-а мастера зоны Z.

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

    Более строго алгоритм поиска порождающей зоны для поднимаемого зависимого окна выглядит так:

    1. Начиная с исходной зоны просматриваются все ее транзитивно главенствующие зоны (т.е. вся цепочка главенствующих зон с учетом цепочки зависимых окон) и выбираются среди них зоны-кандидаты. Если ни одной зоны-кандидата не найдено, то зависимое окно поднять невозможно.
    2. Из всех зон-кандидатов, выбираются зоны, link-путь из мастера которых в мастер зависимого окна совпадает с конечным отрезком link-путей из мастеров других зон-кандидатов в мастер зависимого окна. Если ни одной такой зоны не найдено, это означает, что из разных зон-кандидатов мастер зависимого окна достигается разными путями.  Возникает ошибка неоднозначности определения порождающей зоны и зависимое окно не поднимается. Если найдено более одной такой зоны, то ясно, что все они имеют один и тот же мастер-файл.
    3. Из полученных зон в качестве порождающей выбирается зона, ближайшая к исходной в цепочке транзитивно главенствующих зон.

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

    Из этого алгоритма в частности следует, что опция View(Money 1) никогда не отработает из меню, поднимаемого по F9 в окне Car.

    Пример. Проект KL - Перевозки - "Путевые листы" - Enter входим в редактирование путевого, поднимается подчиненное окно RWaySE с мастером окна и 0-й зоны файлом RWayS и мастером 1-й зоны файлом RWayJ - F3 переходим в рулон с RWayJ, нужно было выбрать путевой, у которого есть рейсы - F9 - Показатели поднимается зависимое окно RWayJP с мастером окна RWayJ и мастером 1-й зоны RWayJP, причем поднимается как зависимое к зоне 1 окна RWaySE - Gray* возвращаемся в зону 1 окна RWaySE - F9 - "Дополнительный персонал" поднимается зависимое окно WayLMen с мастером окна RWayS и мастером 1-й зоны WayLMen, причем поднимается как зависимое к зоне 0 окна RWaySE несмотря на то, что исходной была зона 1 окна RWaySE

  2. Автоматическое разрывание связи между главными и зависимыми окнами (перепривязка окна). При разработке окно проектируется как зависимое или независимое по определению. Но при этом нигде не указывается к какой именно зоне данное окно является, например, зависимым. Это определяется в момент открытия окна. При этом, если окно уже открыто как зависимое к некой порождающей зоне, то любая опция, которая открывает это же окно как зависимое к другой зоне, аннулирует прежнюю зависимость окна и устанавливает новую. Это же правило действует, если зависимое окно становится принудительно независимым и наоборот. Такая перепривязка окна сопровождается завершением всех процессов в этом окне и в его зависимых окнах. Если это невозможно, т.е. имеется процесс редактирования, на экран выдается сообщение с предложением перейти в проблемное окно. Данное правило действует, начиная с V14.144.010, до этого зависимость окон автоматически не изменялась.

    Пример: проект KL - Ценности - Склад - Объекты материального учета (попадаем в зону 1 окна Math00) - F9 - Все свойства (поднимается окно MathPrA как зависимое окно к порождающей зоне 1 окна Math00) - F10 - Ценности - Основные средства - Список (попадаем в зону 1 окна Math01) - F9 - Все свойства - окно MathPrA молча становится зависимым к порождающей зоне 1 окна Math01 (до V14.144.010 в этом случае выдавалось сообщение "Для выполнения этой операции закройте окно "Свойства объекта материального учета"")

  3. Связь зависимых окон с процессами порождающих зон. До сих пор утверждалось, что зависимое окно связано с порождающей зоной. Это не совсем верно. Более точная формулировка звучит так: зависимое окно связано с видеопроцессом порождающей зоны, который был активным в этой зоне в момент открытия зависимого окна. Из этого следует
    1. Если зависимое окно поднято из одного процесса порождающей зоны, то опция "поднять это окно" из другого процесса той же зоны сопровождается перепривязкой окна.
    2. Зависимое окно получает транзакцию из порождающего процесса.
    3. Зависимое окно, поднятое из процесса редактирования (вставки), автоматически закрывается при завершении в порождающей зоне процесса редактирования (вставки).

    Пример: проект KL - Персонал - Справочники - Отделы (поднимается окно Depart "Отделы" с мастером окна и единственной рулонной зоны файлом Depart) - F9 - "Все свойства" (поднимается окно DprtPro "Свойства отдела" как зависимое к процессу View в рулоне окна Depart)  - Gray* (возвращаемся в окно "Отделы") - Enter (входим в редактирование отдела - записи файла Depart, редактирование в рулоне) - F9 - "Все свойства" - окно DprtPro становится зависимым к процессу Edit в рулоне окна Depart (до V14.144.010 в этом случае выдавалось сообщение "Для выполнения этой операции закройте окно "Свойства отдела""). Снова Gray* (возвращаемся в окно "Отделы") - Esc (выходим из редактирования) - окно DprtPro автоматически закрывается.

    Такое поведение связано прежде всего с тем, что считается, что открытие зависимого окна из разных процессов преследует разные цели, иначе говоря ведутся разные сюжетные линии, и работа в зависимом окне может сильно различаться в зависимости от того, из какого процесса это окно поднято, например, в нем могут быть назначены разные контексты. Но если использовать окна-клоны, то для процессов View и Edit одной и той же порождающей зоны можно поднять 2 экземпляра одного и того же зависимого окна.

  4. Автоматическое закрывание зависимых окон. При закрывании главного окна автоматически закрываются и все его (транзитивно) зависимые окна, т.е. все имеющиеся видео-процессы в этих окнах завершаются. Но процессы редактирования и вставки автоматически завершить нельзя. Поэтому если хотя бы в одном зависимом окне работает такой процесс, то закрыть главное окно нельзя. Система в этом случае выдает сообщение "Сначала следует завершить редактирование в окне "Заголовок окна с редактированием"".
  5. Определение транзакции, для выполнения процессов в зависимых окнах. Как уже упоминалось, весь клан окон можно представить как одно виртуальное окно, в котором зоны объединены в дерево. Если в одной из зон этого дерева начинается процесс редактирования или вставки, то порождается транзакция, на которой выполняется этот процесс. В транзитивно зависимых окнах, открытых из этого процесса, вся работа выполняются на его транзакции. Это отрисовка самой зоны, выполнение программных событий, работа интерактивных процессов модификации, выполнение программ и т.п.

    Как определяется транзакция для зоны Z? Просматривается цепочка транзитивно порождающих зон собственного окна, начиная от зоны Z в сторону корня. Если обнаружилась зона с процессам Ask, то транзакция определяется так. Если нашлась зона с редактированием, то транзакция берется из нее. Иначе берется транзакция видеопроцесса, из которого было открыто наше зависимое окно. Если этот процесс не порождал транзакцию, или наше окно независимое, то работа в зоне Z выполняется на параллельной транзакции.

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

  6. Запрет перехода в окно с процессом, работающим не на последнем уровне транзакции. Если несколько записей разных файлов редактируются соответственно в разных зависимых окнах, представляющих собой одну цепочку окон, и соответственно на разных уровнях одной транзакции, то система не позволяет переходить в зону окна, где редактирование ведется не на последнем уровне транзакции. Проблема в том, что уровни одной транзакции представляют собой стек, т.е. завершаться должны в порядке, обратном созданию. Клан окон, как уже упоминалось, можно представлять себе как дерево окон или, более детально, как дерево зон. В связи с этим имеется несоответствие: если редактирование ведется в окнах, представляющих собой параллельные ветви дерева, то эти ветви становятся как бы неравноценными. Поскольку редактирование в одной такой ветви идет на меньшем уровне транзакции, а в другой на большем, то в первую ветвь нельзя перейти до тех пор, пока не закончится редактирование во второй. Этот запрет перехода обеспечивает невозможность работать на промежуточном уровне транзакции.

    Пример (действующий на 10.12.2008). Проект KL - Главное меню-Ценности-скЛад-Документы о движении ОМУ (поднимается подчиненное окно MDoc_DO) - 05 накладные на приход - F3 - Ins (поднимается подчиненное окно "Накладная на приход материальных ценностей"(MD011E) для выполнения вставки в его панели) - F3 (переходим в его рулон, одновременно поднимается подчиненное окно "Строка накладной на приход материальных ценностей" (MD011EF) для выполнения вставки в его панели) - Gray* (возвращаемся в окно MD011E) - F9 - "Экземпляры" (поднимается окно "Перечень экземпляров"(MDocLCU), попадаем в его зону 1) - Ins (выполняется вставка в рулоне окна MDocLCU). Теперь в окно MD011EF невозможно попасть ни мышью, ни Gray+/Gray*

  7. Зависимые окна, в которых не смог выполниться видеоконформ. Внутри окна конформ идет в подчиненную зону из ее главенствующей, а в зависимое окно идет из непосредственно порождающей зоны его главного окна. Именно видеоконформ, и только он, определяет селекты и позиции в курсорах зон. Но если в одной из зон текущая позиция не определена, например, в селекте нет записей, то в ее подчиненной зоне конформ не может определить селект. Поля такой зоны заполнятся символом "сетка". Такое можно наблюдать, например, если в окне "Структура организации" текущая зона 1, а в подчиненной ей зоне 2 не определена позиция, то в зонах 3, 4 и 5, транзитивно подчиненных зоне 2, не определен селект, и они заполнены "сеткой". Но если конформ не может определить селект в мастере уже открытого зависимого окна, такое окно автоматически закрывается, все работающие в нем видеопроцессы завершаются.

Посмотреть как связаны между собой мастера окон, мастера зон в окне и файлы полей зоны можно с помощью диалога "Loaded Windows".