Apie PROGRESS  
  PROGRESS Lietuvoje  
  Projektai, įrankiai:  
    XML-RPC  
     TAB control  
    32bit checksum  


  in English in English


MS Windows TAB-control emuliacija PROGRESS 4GL kalba

Paskirtis

  Tai alternatyvi MS Windows Tab-control realizacija, parašyta gryna 4GL kalba, nenaudojant Active-X ar COM objektų.

Aprašymas

  Šis alternatyvus sprendimas panaudoja persidengiančius iš anksto apibrežtus statinius freimus ir statinius vidžetus jų viduje, t.y. preišingai negu gerai žinomas sprendimas, kuris naudoja standartinį MS Windows Tab-control objektą. MS Tab control varianto pagrindinis trūkumas yra tas, kad reikia realizuoti specialų įvykių apdorojimą (message handling) pagrindiniame PROGRESS pranešimų apdorojimo cikle (WAIT-FOR), kuris numato kreipimąsi į eilę papildomų Windows API funkcijų. Kartu tai sudaro problemų, kūriant didesnes aplikacijas, nes reikia pastoviai turėti omeny šį nestandartinį įvykių apdorojimą, kas įneša tam tikrą nelankstumo elementą į programavimą (prisimenate, - one world - one WAIT-FOR?).

Mūsų alternatyvus sprendimas yra tiesiog pilna loginė tab-control elgesio imitacija, kuri panaudoja tik standartinius PROGRESS vidžetus (mygtukus, stačiakampius ir freimus). Be to ji ir atrodo labai panašiai į tikrą MS Windows Tab control'ą. Žemiau pateikiamas programos skeletas, kuriame galima pamatyti visą tab-control sudarymo ir valdymo techniką, o jo implementacija galite pamatyti create_tab.i faile.

Iš pradžių Jūs sukūriate statinius freimus ir vidžetus juose. Aišku galima kurti ir dinaminius vidžetus, bet jie turi būti aktyvuojami prieš iškviečiant "tab"ų sudarymo (gf_create_tab) funkciją (žr. žemiau). Visas visų vidžetų tūrinys yra prieinamas tiesiogiai ir jį galimą valdyti iš bet kurio programos taško bet kuriuo momentu. Jūs taip pat galite valdyti visus vidžetus (pvz. enable ir disable) bet kuriuo metu, dar daugiau - Jūs galite netgi tiesiogiai valdyti pačius "tab"us.

Žemiau patekiamas statinių vidžetų ir freimų, kurie sudaro "tab"ų tūrinį, kodo pavyzdys (po vieną freimą kiekvienam "tab"ui):

/*  asmfr.i 
*/

/* Frame 1 */

DEFINE VARIABLE t-adrreg AS CHARACTER FORMAT "X(256)":U 
     LABEL "Region" 
     VIEW-AS COMBO-BOX INNER-LINES 5
     LIST-ITEM-PAIRS ""
     SORT
     DROP-DOWN-LIST
     SIZE-PIXELS 126 BY 24 NO-UNDO.

DEFINE VARIABLE t-ctr AS CHARACTER FORMAT "X(256)":U 
     LABEL "Country" 
     VIEW-AS COMBO-BOX INNER-LINES 10
     LIST-ITEM-PAIRS ""
     SORT
     DROP-DOWN-LIST
     SIZE-PIXELS 133 BY 26 NO-UNDO.

DEFINE VARIABLE t-doctip AS CHARACTER FORMAT "X(256)":U
     LABEL "Document" 
     VIEW-AS COMBO-BOX INNER-LINES 5
     LIST-ITEM-PAIRS ""
     SORT
     DROP-DOWN-LIST
     SIZE-PIXELS 154 BY 24 NO-UNDO.

DEFINE VARIABLE t-sex AS CHARACTER FORMAT "X(256)":U 
     LABEL "Sex" 
     VIEW-AS COMBO-BOX INNER-LINES 5
     LIST-ITEM-PAIRS ""
     SORT
     DROP-DOWN-LIST
     SIZE-PIXELS 133 BY 26 NO-UNDO.

DEFINE VARIABLE t-abbr AS CHARACTER FORMAT "X(256)":U 
     LABEL "ShortName" 
     VIEW-AS FILL-IN NATIVE 
     SIZE-PIXELS 336 BY 26 NO-UNDO.

DEFINE VARIABLE t-birthday AS DATE FORMAT "9999/99/99":U 
     LABEL "Birth date" 
     VIEW-AS FILL-IN NATIVE 
     SIZE-PIXELS 98 BY 26 NO-UNDO.

DEFINE VARIABLE t-cod AS CHARACTER FORMAT "X(256)":U 
     LABEL "Personal ID" 
     VIEW-AS FILL-IN NATIVE
     SIZE-PIXELS 154 BY 26 NO-UNDO.

DEFINE VARIABLE t-doccod AS CHARACTER FORMAT "X(256)":U 
     LABEL "Nr" 
     VIEW-AS FILL-IN NATIVE
     SIZE-PIXELS 154 BY 26 NO-UNDO.

DEFINE VARIABLE t-fname AS CHARACTER FORMAT "X(256)":U 
     LABEL "First Name" 
     VIEW-AS FILL-IN NATIVE
     SIZE-PIXELS 231 BY 26 NO-UNDO.

DEFINE VARIABLE t-sname AS CHARACTER FORMAT "X(256)":U 
     LABEL "Last Name" 
     VIEW-AS FILL-IN NATIVE
     SIZE-PIXELS 231 BY 26 NO-UNDO.


/* ************************  Frame Definitions  *********************** */

DEFINE FRAME FR_1
     t-sname AT Y 63 X 112 COLON-ALIGNED
     t-fname AT Y 98 X 112 COLON-ALIGNED
     t-abbr AT Y 133 X 112 COLON-ALIGNED
     t-ctr AT Y 168 X 112 COLON-ALIGNED
     t-adrreg AT Y 168 X 322 COLON-ALIGNED
     t-cod AT Y 203 X 112 COLON-ALIGNED
     t-birthday AT Y 238 X 112 COLON-ALIGNED
     t-sex AT Y 238 X 315 COLON-ALIGNED
     t-doctip AT Y 275 X 112 COLON-ALIGNED
     t-doccod AT Y 275 X 294 COLON-ALIGNED
    WITH 1 DOWN NO-BOX KEEP-TAB-ORDER OVERLAY 
         SIDE-LABELS THREE-D 
         AT X 5 Y 5
         .


FRAME FR_1:FRAME = FRAME tabframe:handle.
FRAME FR_1:VISIBLE = false.


/* Frame 2 */

/* ..... widget definitions */


DEFINE FRAME FR_2
    .... widgets
    ....
    WITH 1 DOWN NO-BOX KEEP-TAB-ORDER OVERLAY 
         SIDE-LABELS NO-UNDERLINE THREE-D 
         AT X 5 Y 5
         .

FRAME FR_2:FRAME = FRAME tabframe:handle.
FRAME FR_2:VISIBLE = false.

/* Frame 3 */

.....


/* Frame 4 */

DEFINE BUTTON bt-ca-del 
     LABEL "Delete" 
     SIZE-PIXELS 105 BY 26.

DEFINE BUTTON bt-ca-edit 
     LABEL "Edit" 
     SIZE-PIXELS 105 BY 26.

DEFINE BUTTON bt-ca-new 
     LABEL "New" 
     SIZE-PIXELS 105 BY 26.

DEFINE BUTTON bt-ca-view 
     LABEL "Go to companies registry ..." 
     SIZE-PIXELS 183 BY 26.

DEFINE BUTTON bt-ca-cmp 
     IMAGE-UP FILE "icons/cbbtn.bmp":U
     LABEL "Button 1" 
     SIZE-PIXELS 21 BY 26.

DEFINE VARIABLE ca-tip AS CHARACTER FORMAT "X(256)":U 
     VIEW-AS COMBO-BOX INNER-LINES 5
     LIST-ITEM-PAIRS "Item 1","Item 1"
     DROP-DOWN-LIST
     SIZE-PIXELS 144 BY 24 NO-UNDO.

DEFINE VARIABLE ca-cmp AS CHARACTER FORMAT "X(256)":U 
     VIEW-AS FILL-IN NATIVE 
     SIZE-PIXELS 98 BY 24 NO-UNDO.

DEFINE VARIABLE ca-ikits AS DATE FORMAT "9999.99.99":U 
     VIEW-AS FILL-IN NATIVE 
     SIZE-PIXELS 98 BY 24 NO-UNDO.

DEFINE VARIABLE ca-nuots AS DATE FORMAT "9999.99.99":U INITIAL ? 
     VIEW-AS FILL-IN NATIVE 
     SIZE-PIXELS 98 BY 24 NO-UNDO.

DEFINE RECTANGLE fr-4-rc-1
     EDGE-PIXELS 2 GRAPHIC-EDGE  NO-FILL 
     SIZE 70.43 BY 1.58.

/* Query definitions                                                    */
DEFINE QUERY cmpasm-br FOR 
      tt-cmpasmb SCROLLING.

/* Browse definitions                                                   */
DEFINE BROWSE cmpasm-br
  QUERY cmpasm-br DISPLAY
       tt-cmpasmb.del COLUMN-LABEL "" FORMAT "x/ "
       tt-cmpasmb.cmpname COLUMN-LABEL "Company" FORMAT "x(15)"
       tt-cmpasmb.tipname COLUMN-LABEL "Role  " FORMAT "x(20)"
       tt-cmpasmb.nuots COLUMN-LABEL "Worked from  " FORMAT "xxxx.xx.xx    "
       tt-cmpasmb.ikits COLUMN-LABEL "to   " FORMAT "xxxx.xx.xx"
    ENABLE tt-cmpasmb.del
    WITH NO-ROW-MARKERS SEPARATORS
         SIZE-PIXELS 487 BY 161
         TITLE "Person's occupations" 
         EXPANDABLE.


/* ************************  Frame Definitions  *********************** */


DEFINE FRAME fr_4
     cmpasm-br AT Y 23 X 18
     bt-ca-cmp AT Y 205 X 119
     ca-cmp AT Y 206 X 7 COLON-ALIGNED NO-LABEL
     ca-tip AT Y 206 X 129 COLON-ALIGNED NO-LABEL
     ca-nuots AT Y 206 X 274 COLON-ALIGNED NO-LABEL
     ca-ikits AT Y 206 X 375 COLON-ALIGNED NO-LABEL
     bt-ca-new AT Y 264 X 21
     bt-ca-edit AT Y 264 X 139
     bt-ca-del AT Y 264 X 381
     bt-ca-view AT Y 318 X 303
     fr-4-rc-1 AT ROW 8.65 COL 2.86
    WITH 1 DOWN NO-BOX KEEP-TAB-ORDER OVERLAY 
         SIDE-LABELS NO-UNDERLINE THREE-D 
         AT X 5 Y 5
         .

FRAME FR_4:FRAME = FRAME tabframe:handle.

FRAME FR_4:VISIBLE = false.

/* Frame 5 */

/* .... */

/* Frame 6 */

/* .... */

/* end of frames source */

Jūs galite kurti kiekvieno freimo turinį, naudodami UIB (User Interface Builder), sukurdami netikrą atitinkamo dydžio dialogą (freimą), ir po to visus vidinius vidžetus jame. Sukurus tokį freimą, sugeneruotą kodą galimą pernešti į galutinį failą, turintį visų reikalingų freimų vidžetus.

Sekantis žingsnis - pagrindinio lango sudarymas, kuriame turi būti sukurtas "tab"us apimantis freimas. Toliau sukūriami patys "tab"ai nuosekliai iškviečiant gf_create_tab funkcijas. Šie funkcijos iškvietimai turi būti UIB standartinėje procedūroje Enable_UI, arba Jūsų sudarytoje ekvivalentiškoje procedūroje. Kiekvienas "tab" sudarymo funkcijos iškvietimas grąžina "tab"o kontroliuojančio vidžeto handlerį, kuris iš tikrųjų yra pusiau paslėptas mygtuko (button) vidžetas. Vėliau galima panaudoti šį handlerį įvykių apdorojimo trigeriuose ("ON" frazėje), arba tiesiogiai valdyti pačius "tab"us, keičiant jų savybes (properties).
Naudojant ketvirtą gf_create_tab funkcijos parametrą, galima nurodyti išorines arba vidines procedūras, kurios bus iškviestos paspaudus "tab"ą prieš jo pasirodymą ir po to. Pre- ir post- processingo procedūrų pavadinimai skiriami kableliu ir sudaro vieną eilutę. Penktas (paskutinis) parametras skirtas nurodyti procedūros handleriui, kurios kode randasi pre- ir post- procedūros.

Žemiau pateikiamas galimos programos skeletas:

/*------------------------------------------------------------------------

  File: _asm.p

  Description: Personnel registry

  Author: Vladas Saulis (PRODATA)

  Created: 2001.06.20
*/


{ create_tab.i }  /* This can also be put into global persistent section */

DEF VAR hTabFrame as handle.

DEF VAR hBut1 as widget-handle.
DEF VAR hBut2 as widget-handle.
DEF VAR hBut3 as widget-handle.
DEF VAR hBut4 as widget-handle.
DEF VAR hBut5 as widget-handle.
DEF VAR hBut6 as widget-handle.

/* ***********************  Control Definitions  ********************** */

/* Define the widget handle for the window                              */
DEFINE VAR C-Win AS WIDGET-HANDLE NO-UNDO.


/* Widget definitions goes here
   ....
*/

/* ************************  Frame Definitions  *********************** */



DEFINE FRAME asm-fr
    ..... widgets
    .....
    WITH 1 DOWN NO-BOX KEEP-TAB-ORDER
         SIDE-LABELS NO-UNDERLINE THREE-D 
         AT X 0 Y 0
         SIZE-PIXELS 760 BY 470.


/* Example of container frame - the parent of all "tab" frames */
DEFINE FRAME tabframe
    WITH THREE-D
    .


FRAME tabframe:frame = FRAME asm-fr:handle.

ASSIGN
    hTabFrame = FRAME tabframe:handle
    htabFrame:WIDTH-PIX = 545
    hTabFrame:HEIGHT-PIX = 425
    hTabFrame:X = 215
    hTabFrame:Y = 40
    hTabFrame:BOX = false
    .


{ asmfr.i }  /* All "tabs" content */


/* Main window */
  CREATE WINDOW C-Win 
      ASSIGN
         TITLE              = "Personnel registry"
	 ....
	 ....
         SENSITIVE          = yes
         .


/* Event processing */

{ events.i }
  /* The placeholder for event processing */



PROCEDURE enable_UI : /* This is a part of UIB code */


  ENABLE ......
      WITH FRAME asm-fr IN WINDOW C-Win.


  VIEW C-Win.


  /* gf_create_tab parameters:
    
    1. The "tab" element screen label
    2. Container frame handle
    3. "tab's" frame handle 
    4. Optional: Pre- and post-processing
 procedures' names 
	(separated by comma)
    5. Optional: Procedure handle of pre-/post- procedures.
    
    Returns: Controlling "tab" button handle.
  */

  hBut1 = gf_create_tab("Main info", FRAME tabframe:HANDLE, 
			FRAME FR_1:HANDLE, ?, ?). 
  hBut2 = gf_create_tab("Extra info", FRAME tabframe:HANDLE, 
			FRAME FR_2:HANDLE, ?, ?). 
  hBut3 = gf_create_tab("Addresses", FRAME tabframe:HANDLE, 
			FRAME FR_3:HANDLE, "init_3_tab", THIS-PROCEDURE). 
  hBut4 = gf_create_tab("Occupation", FRAME tabframe:HANDLE, 
			FRAME FR_4:HANDLE, "init_4_tab", THIS-PROCEDURE). 
  hBut5 = gf_create_tab("Events", FRAME tabframe:HANDLE, 
			FRAME FR_5:HANDLE, "init_5_tab", THIS-PROCEDURE). 
  hBut6 = gf_create_tab("Other", FRAME tabframe:HANDLE, 
			FRAME FR_6:HANDLE, "init_6_tab", THIS-PROCEDURE). 

  ENABLE ALL WITH FRAME tabframe.
  /* enable widgets in some (or all) "tabs" */
  ENABLE ALL WITH FRAME FR_2.
  ENABLE ALL WITH FRAME FR_1.
  /* you can hide some frames */
  FRAME fr_4:VISIBLE = FALSE.
  FRAME fr_3:VISIBLE = FALSE.

  run dis_frames_content. /* optionally disable all frames content */


END PROCEDURE.
 /* Enable_UI */


Procedūros kodo atsisiuntimas

  Jūs galite parsisiųsti arba peržiūrėti šį create_tab.i išeities tekstą.

Ekrano vaizdų pavyzdžiai

  Čia Jūs galite pamatyti pavyzdynės personalo valdymo programos ekrano vaizdus


Čia pavaizduotas pradinis "tab"as, kuris atsiranda kada sukūriama arba koreguojama asmens informacija. Galima pastebėti, kad kai kurie "tab"ai gali būti neprieinami.


Sąrašas šiame "tab"e nereikalauja specialaus apdorojimo, todėl kad jis yra statinis, ir dirba kartu su visais kitais interfeiso elementais.


Papildomos pastabos apie 4GL "tab-control" užprogramuotas savybes

  Kaip visada būna, šis "tab_control" variantas turi ir savo apribojimų. Pagrindinis apribojimas yra glaudžiai susijęs su PROGRESS r-kodo dydžio apribojimu. Jis atsiranda dėl to, kad visų "tab"ų visų elementų įvykiai turi būti apdorojami vieno kodo segmeto ribose. Aišku galima šiek tiek sušvelninti situaciją, iškarto iškviečiant vidines procedūras iš įvykių apdorojimo trigerių, bet realiame gyvenime šis variantas taip pat gali nepadėti, jeigu programa yra pakankamai didelė.
Galimas ir kitas šios problemos sprendimas - kiekvieną "tab"ą apdoroti atskiroje "persistent" procedūroje. Bet šis sprendimas iškelia kitą gana sudėtingą problemą - taisyklingą šių procedūrų tarpusavio bendravimo užtikrinimą.

Kitas apribojimas yra ribotas horizontalus visų "tab"ų ilgis, ypač jeigu norima turėti daugiau "tab"ų arba turėti ilgas antraštes ant jų. Egzistuoja galimybė realizuoti "prasukamą tab"ą. Mes paliekam šios galimybės realizaciją Jums ir tikimės, kad Jūs pasidalinsite su mumis savo idėjomis.

Kai kuriais atvejais reikalinga kurti "tab"us dinamiškai, priklausomai nuo programos eigos. Šis variantas leidžia padaryti tai, bet pareikalaus iš Jūsų kiek įmantresnės programavimo technikos.

Autoriai

  Originali 4GL "tab-control" idėja ir realizacija priklauso Vladui Sauliui (PRODATA) ir Sauliui Sakarauskui (Baltic Amadeus). Jūs galite laisvai naudoti šį kodą Jūsų projektuose su sąlyga, kad bus nurodyta šio kodo autorystė. Klausimai ir komentarai priimami adresais, nurodytais kontaktų puslapyje.





Powered by PROGRESS

| ProData | PROGRESS | Linux | Programavimas | TROLIS.NET |

Last updated 2021-06-20