Страница 1 из 1

Встраивание стандартных интерфейсов Галактики

Добавлено: 11 сен 2010, 17:57
galover
Встала задача встроить стандартный интерфейс Галактики в свой интерфейс (в embedded область). Накатал велосипед, может кому пригодится. Стандартные интерфейсы удобно использовать при просмотре детальной информации по какой-либо сущности в своем интерфейсе. Да и просто, чтобы не реализовывать то, что уже реализовано. Принцип простой - наследуемся от желаемого интерфейса, создаем конструктор или метод инициализации, в который передаем параметры родительского интерфейса (параметры, передаваемые в функцию RunInterface) и перенаправляем события инициализации/уничтожения в родительский интерфейс.
Пример 1: встраивание интерфейса каталога ЦО в свой интерфейс

Код: Выделить всё

#include FpCo.vih

#component "Utils_Test"

vipinterface GetCoEx(F_FpCatalog::GetCO);
   public:
      procedure Initialize(wIntModeA : word; cTopRecA : comp; cNodeTopA : comp; cGetRecA : comp);
end ;
   
interface GetCoEx;
   public procedure Initialize(wIntModeA : word; cTopRecA : comp; cNodeTopA : comp; cGetRecA : comp);
   {
      wIntMode := wIntModeA;
      cTopRec  := cTopRecA;
      cNodeTop := cNodeTopA;
      cGetRec  := cGetRecA;
   }
   handleEvent
      cmOnVipLoad: inherited::handleEvent(cmInit);
      cmOnVipUnLoad: inherited::handleEvent(cmDone);
   end;
end.

interface TestStdInterface 'Встраивание стандартного интерфейса';
   var _getCoEx : Utils_Test::GetCoEx new;

   screen scrEmpty;
      show at(,,, 10);
<<
  Данные моего интерфейса
>>
   end;
   
   embedded embFpCo interface _getCoEx;
      show at(, 11,,);
   end;
   
   handleEvent
      cmInit:
      {
         _getCoEx.Initialize(word(cgiPickMult), 0h, 0h, 0h);
      }
   end;
end.
Результат:
Изображение

Пример 2: встраивание списка договоров и окна детальной информации по договорам

Код: Выделить всё

#include Dogovor.vih

#component "Utils_Test"

vipinterface DogovorEx(L_Dogovor::Dogovor);
   public:
      constructor Initialize(pVidDogA : word; pTiDkA : word; pDirectA : word; pStatusA : word; pDogovorA : comp; pRecA : comp);
      function GetCurrentDogovorNRec : comp;
      event procedure DogovorChanged(dogNRec : comp);
end ;
   
interface DogovorEx;
   constructor Initialize(pVidDogA : word; pTiDkA : word; pDirectA : word; pStatusA : word; pDogovorA : comp; pRecA : comp);
   {
      pVidDog  := pVidDogA; 
      pTiDk    := pTiDkA;  
      pDirect  := pDirectA; 
      pStatus  := pStatusA;
      pDogovor := pDogovorA;
      pRec     := pRecA;   
      
      result := true;      
   }  
  
   public function GetCurrentDogovorNRec : comp;
   {
      result := Dogovor1.nRec;
   }
   
   tableEvent table Dogovor1
      cmPositionChanged:
      {
         inherited::handleEvent(cmPositionChanged);
         DogovorChanged(Dogovor1.nRec);
      }
   end;

   handleEvent
      cmOnVipLoad: inherited::handleEvent(cmInit);
      cmOnVipUnLoad: inherited::handleEvent(cmDone);
      cmDefault: Abort(); // Через default идет открытие окна - блокируем событие
   end;
end.

interface TestStdInterface 'Встраивание стандартного интерфейса';
   var _dogovorEx : Utils_Test::DogovorEx noauto;
   var _dogInfo : Utils_Test::DogovorEx noauto;
   
   ////////////////////////////////////////////////////////////////////////
   create view
   var _dogNRec : comp;
   as select
      Dogovor.nRec
   from
      Dogovor
   where
   ((
      _dogNRec == Dogovor.nRec
   ));
   
   ////////////////////////////////////////////////////////////////////////
   embedded embDogovors interface _dogovorEx;
      show at(,,, 10);
   end;
   
   embedded embDogovorInfo interface ;
      show at(, 11,,);
   end;
   
   ////////////////////////////////////////////////////////////////////////
   private procedure DogovorChanged(dogNRec : comp);
   {
      UnBindEmbeddedInterface(embDogovorInfo);
      
      if (not NullVipRef(_dogInfo))
         FreeVipInterface(_dogInfo);
      
      _dogNRec := dogNRec;

      if (getfirst fastfirstrow Dogovor = tsOk)
      {
         _dogInfo := new(Utils_Test::DogovorEx, Initialize(Dogovor.VidDog, Dogovor.TiDk, Dogovor.Direct, Dogovor.Status, Dogovor.cDogovor, Dogovor.nRec));
         BindEmbeddedInterface(embDogovorInfo, _dogInfo, 'wiDogovorEditMain');
      }
   }

   ////////////////////////////////////////////////////////////////////////
   handleEvent
      cmInit:
      {
         _dogovorEx := new(Utils_Test::DogovorEx, Initialize(0, 0, 0, 0, 0h, 0h));
         BindEvent(DogovorChanged, _dogovorEx.DogovorChanged);         
         DogovorChanged(_dogovorEx.GetCurrentDogovorNRec());
      }
   end;
end.
Результат:
Изображение
В верхней части общий список договоров, внизу окно с детальной информацией по выбранному договору из верхней панели. Здесь как видно есть косяк с отображением скроллбара в embedded области.
Недостатки метода:
1) необходимость перекомпиляции после наката патчей (ну это понятно);
2) обязательное наличие vih файла при компиляции с описанием родительского интерфейса. Это немного странно ведь данная символьная информация есть в ресурсе, и при докомпиляции, например, она берется от туда, при том что докомпиляция - суть то же наследование. Но компилятор ругается без vih файла, как обойти это не нашел;
3) не со всеми интерфейсами прокатит такой метод, наверняка найдется какой-то интерфейс с хитрой логикой инициализации;
4) желательно (хоть и не обязательно) все же иметь исходники родительского интерфейса, для изучения процесса инициализации и других особенностей поведения.
Достоинства: сокращение времени разработки за счет повторного использования существующего функционала. Если нужно что-то быстро слепить, то сойдет. Потом можно будет переписать для надежности на свою реализацию.
Файлы с исходниками примеров: http://ifolder.ru/19257569