home *** CD-ROM | disk | FTP | other *** search
/ TopWare 18: Liquid / Image.iso / liquid / top1143 / gepackt.exe / WGVDOKU.EXE / WGDOKU.TXT
Encoding:
Text File  |  1993-07-12  |  491.7 KB  |  20,013 lines

  1.                                                 WGVISION 1.0
  2.  
  3.  
  4.  
  5.  
  6.  
  7. Klassenbibliothek zur Ausstattung von Turbo- und Borland-
  8. Pascal-Programmen mit einer Windows-ähnlichen grafischen
  9. Nutzeroberfläche
  10.  
  11. -----------------------------------------------------------
  12. Copyright (c) 1992/93  Dipl.Phys. Mathias Scholz
  13.  
  14.                        02763 Zittau/Sa.
  15.                        Bergstr. 7
  16. -----------------------------------------------------------
  17.  
  18.                WW      WW     GGGGGG
  19.                WW      WW    GG     GG
  20.                WW      WW   GG
  21.                WW      WW   GG              ========
  22.                WW  WW  WW   GG   GGGGG      ========
  23.                WW WWWW WW    GG     GG
  24.                 WW    WW     GG     GG
  25.                 WW    WW      GGGGGGGG
  26.  
  27.  
  28.    VV     VV   ii    SSSSSS    ii    OOOOOOO     NN     NN
  29.    VV     VV   ii   SS         ii   OO     OO    NNN    NN
  30.     VV   VV    ii   SS         ii   OO     OO    NNNN   NN
  31.     VV   VV    ii    SSSSSS    ii   OO     OO    NN NN  NN
  32.      VV VV     ii         SS   ii   OO     OO    NN  NN NN
  33.      VV VV     ii         SS   ii   OO     OO    NN   NNNN
  34.       VVV      ii         SS   ii   OO     OO    NN    NNN
  35.        V       ii    SSSSSS    ii    OOOOOOO     NN     NN
  36.  
  37.  
  38.                         Version 1.0
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46. WG-Vision ist eine Weiterentwicklung der Klassenbibliothek
  47.                        WGRAPH 1.0
  48.  
  49.  
  50.  
  51.                                                     WG-Vision  I
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59. Eingetragene Warenzeichen
  60.  
  61. Microsoft, MS-DOS und Windows sind eingetragene Warenzeichen
  62. der Microsoft Corp., USA
  63.  
  64. Turbo Pascal und Borland Pascal sind eingetragene Waren-
  65. zeichen von Borland International Inc., USA
  66.  
  67.  
  68.  
  69. WG-Vision verwendet einen VESA-BGI-Treiber der Firma W&B
  70. Software, Dresden
  71.  
  72. Aus Gründen des Copyrights liegen diesem Programmpaket nur
  73. die Shareware-Versionen der VESA-Treiber von W&B Software
  74. bei. Die Treiber, die sich im Verzeichnis PDVESA befinden,
  75. sind Public Domäin und können zusammen mit den mit WG-Vision
  76. entwickelten Anwendungen beliebig weitergegeben werden.
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.                                                     WG-Vision  II
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109. Inhaltsverzeichnis
  110.  
  111.  
  112. 1.       Programmieren mit WG-Vision ........................... 1
  113.  
  114. 2.       Aufbau von WG-Vision .................................. 2
  115.  
  116. 3.       Programmierung des Desktops ........................... 4
  117. 3.1.     Aufbau des Desktops ................................... 6
  118. 3.2.     Gestaltung des Rahmens ................................ 6
  119. 3.3.     Gestaltung des Arbeitsbereiches (Hintergrund) ........ 11
  120. 3.4.     Aufbau eines Menüs ................................... 16
  121. 3.4.1.   Farbeinstellungen .................................... 22
  122. 3.4.2.   Laden von Menüs aus Ressourcen ....................... 23
  123. 3.4.3.   Verarbeitung von Menü-Kommandos, der Event-Handler ... 26
  124. 3.4.4.   Verschieben des Menüs in der Menüzeile ............... 32
  125. 3.5.     Grafikmodus einstellen ............................... 33
  126. 3.6.     Wechseln der Desktop-Farben zur Laufzeit ............. 37
  127. 3.7.     Umschalten in den Alpha-Modus ........................ 40
  128.  
  129. 4.       Heap- und EMS-Überwachung ............................ 41
  130.  
  131. 5.       Schöne neue Fensterwelt .............................. 43
  132. 5.1.     Programmierung ....................................... 46
  133. 5.1.1.   Eigenschaften eines Fensters festlegen ............... 48
  134. 5.1.2.   Hintergrundinformationen zur Fenstertechnik .......... 63
  135. 5.1.3.   Fenster mit Rollbalken ............................... 69
  136. 5.1.3.1. Farbgestaltung der Rollbalken und des Scrollbereichs . 76
  137. 5.1.3.2. Programmierung des Scrollers ......................... 77
  138. 5.1.3.3. Bedienung des Rollbalkens mit der Tastatur ........... 80
  139. 5.1.3.4. Verwendung der Sonderzeichensätze .................... 80
  140. 5.1.3.4. Grafiken in einem Scrollfenster darstellen ........... 82
  141. 5.2.     Programmierung von Dialogen .......................... 85
  142. 5.2.1.   Pushbuttons (Drucktasten) ............................ 86
  143. 5.2.1.1. Farbgestaltung ....................................... 90
  144. 5.2.1.2. Verändern der Textposition ........................... 91
  145. 5.2.2.   Statische Texte ...................................... 96
  146. 5.2.3.   Rahmen, Gruppenrahmen ............................... 101
  147. 5.2.3.1. Farbgestaltung ...................................... 102
  148.  
  149.  
  150.  
  151.                                                     WG-Vision  III
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159. 5.2.4.   Icons ............................................... 103
  160. 5.2.5.   Aktive Dialogelemente in WG-Vision .................. 104
  161. 5.2.6.   Radio-Buttons (Optionsschaltflächen) ................ 106
  162. 5.2.7.   Checkbuttons (Kontrollfelder) ....................... 118
  163. 5.2.7.1. Farbgestaltung von Radio- und Checkbutton ........... 120
  164. 5.2.8.   Textfelder (Edit-Controls) .......................... 120
  165. 5.2.8.1. Datenübergabe von und in Eingabefelder .............. 122
  166. 5.2.8.2. Farbgestaltung von TInputLine-Objekten .............. 128
  167. 5.2.8.3. Aufbau von Eingabemasken ............................ 143
  168. 5.2.9.   Zählschalter ........................................ 144
  169. 5.2.10.  Listboxen ........................................... 148
  170. 5.2.10.1.Farbpalette ......................................... 152
  171. 5.2.11.  Zusammenfassung Dialogelemente ...................... 152
  172. 5.3.     Child-Fenster ....................................... 155
  173. 5.4.     Programmierung einer Iconleiste ..................... 163
  174. 5.5.     Mitteilungsboxen .................................... 185
  175. 5.6.     Anzeigen von Fehlermeldungen ........................ 186
  176. 5.7.     Kontextsensitive Hilfe .............................. 189
  177. 5.8.     Statuszeile ......................................... 193
  178. 5.9.     Zweisprachige Programmierung ........................ 194
  179.  
  180. 6.       Objekte im Detail ................................... 195
  181. 6.1.     Unit WDriver ........................................ 195
  182. 6.1.1.   Ansteuerung der Grafikkarte - TVideoDevice .......... 195
  183. 6.1.2.   Ansteuerung eines Spielhebels - TJoyStickDevice ..... 199
  184. 6.1.3.   Tastatur - TKeyboardDevice .......................... 202
  185. 6.1.4.   Maus - TMouseDevice ................................. 212
  186. 6.1.4.1. Erstellung von Mauszeiger-Ressourcen ................ 218
  187. 6.1.4.2. Einige Hinweise zur Benutzung des Mausobjektes ...... 224
  188. 6.1.5.   SummaSketch-Digitizer - TSSDigiDevice ............... 226
  189. 6.2.     Unit WText .......................................... 232
  190. 6.2.1.   Standard-VGA: Sonderzeichensätze .................... 232
  191. 6.3.     Unit WFont .......................................... 237
  192. 6.3.1.   ROM- und Userzeichensätze in WG-Vision - TPixelFont . 237
  193. 6.3.2.   Fontmania ........................................... 237
  194. 6.3.3.   Font-Ressourcen ..................................... 239
  195. 6.3.4.   Objekt TPixelFont ................................... 239
  196. 6.3.5.   Verwendung der Vektorzeichensätze - TVektorFont ..... 256
  197. 6.3.5.1. Skalierung der BGI-Zeichensätze ..................... 256
  198.  
  199.  
  200.  
  201.                                                     WG-Vision  IV
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209. 6.4.     Unit WEMS - Die Verwaltung des Expanded Memory ...... 259
  210. 6.4.1.   Ein paar Worte zur Funktionsweise ................... 260
  211. 6.5.     Schwelgen in Farben - Die Unit WPalette ............. 272
  212. 6.5.1.   Farbmodelle ......................................... 283
  213. 6.5.1.1. RGB-Modell .......................................... 283
  214. 6.5.1.2. HSV-Modell .......................................... 284
  215.  
  216. 7.       Die Kern-Units von WG-Vision ........................ 285
  217. 7.1.     Unit WAPP ........................................... 285
  218. 7.1.1.   Aufbau eines WG-Vision-Programms .................... 285
  219. 7.2.     Unit WViews ......................................... 291
  220. 7.2.1.   Objekt TView ........................................ 291
  221. 7.2.2.   Objekt TGroup ....................................... 293
  222. 7.2.2.1. Aufbau einer doppelt verketteten Liste .............. 295
  223. 7.2.3.   Speicherobjekte ..................................... 302
  224. 7.2.4.   Das Rahmenobjekt .................................... 303
  225. 7.3.     Unit WDlg ........................................... 305
  226. 7.3.1.   Das Standard-Fenster - TWindow ...................... 305
  227. 7.3.2.   Dialogfenster - TDlgWindow .......................... 308
  228. 7.3.2.1. Dialogelemente ...................................... 311
  229.  
  230. 8.       WG-Vision und der Coprozessor ....................... 313
  231. 8.1.     Erweiterte Funktionen des Coprozessors .............. 313
  232.  
  233. 9.       Verwendung von Overlays ............................. 315
  234.  
  235. 10.      Tips und Tricks ..................................... 318
  236.  
  237. 10.1.    Wir basteln uns einen Screensaver ................... 318
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.                                                     WG-Vision  V
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259. Anhang    Interfacedokumentation der Units
  260.  
  261. WDECL ........................................................ 325
  262. WAPP ......................................................... 334
  263. WVIEWS ....................................................... 337
  264. WDRIVER ...................................................... 344
  265. WDLG ......................................................... 349
  266. WEVENT ....................................................... 357
  267. WERROR ....................................................... 359
  268. WTEXT ........................................................ 360
  269. WEMS ......................................................... 362
  270. WUTILS ....................................................... 363
  271. WFONT ........................................................ 364
  272. WHELP ........................................................ 366
  273. WPCX ......................................................... 368
  274. W256PCX ...................................................... 369
  275. WCPROC ....................................................... 371
  276. WFILEDLG ..................................................... 372
  277. WPRINT ....................................................... 374
  278. WICNEDIT ..................................................... 377
  279. WCALC ........................................................ 379
  280. WUHR ......................................................... 381
  281. WPALETTE ..................................................... 383
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.                                                     WG-Vision  VI
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309. Objekt-Hierarchie WG-VISION           Unit
  310.  
  311.  
  312. Objekte
  313.  - TObject                            [WDECL]
  314.     - TView                           [WVIEWS]
  315.        - TGroup                       [WVIEWS]
  316.           - TBackground               [WVIEWS]
  317.              - TCalcBackground        [WCALC]
  318.              - TColorBar              [WPALETTE]
  319.              - TDruckBgrd             [WPRINT]
  320.              - TDsktpBgrd             [WAPP]
  321.              - TIconEditBgrd          [WICNEDIT]
  322.              - TIDlgBgrd              [WFILEDLG]
  323.              - TODlgBgrd              [WFILEDLG]
  324.              - TOptionBgrd            [WPRINT]
  325.              - TPWorkshopBgrd         [WPALETTE]
  326.              - TScaleBgrd             [WPALETTE]
  327.              - TUhrBgrd               [WUHR]
  328.           - TButton                   [WDLG]
  329.              - TGroupFrame            [WDLG]
  330.              - TIcon                  [WDLG]
  331.              - TInputLine             [WDLG]
  332.                 - TNumButton          [WDLG]
  333.              - TPushButton            [WDLG]
  334.              - TRadioButton           [WDLG]
  335.                 - TCheckButton        [WDLG]
  336.              - TScroller              [WDLG]
  337.                 - THelpScroller       [WHELP]
  338.                 - TListBox            [WDLG]
  339.                    - TDateiListBox    [WFILEDLG]
  340.           - TDesktop                  [WVIEWS]
  341.           - TFrame                    [WVIEWS]
  342.           - TLine                     [WVIEWS]
  343.           - TMemory                   [WVIEWS]
  344.              - TEMS                   [WVIEWS]
  345.              - THardDisk              [WVIEWS]
  346.              - THeap                  [WVIEWS]
  347.  
  348.  
  349.  
  350.  
  351.                                                     WG-Vision  VII
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.           - TProgram                  [WAPP]
  360.              - TApp                   [WAPP]
  361.           - TWindow                   [WDLG]
  362.              - TDlgWindow             [DLG]
  363.                 - TCalculator         [WCALC]
  364.                 - TDigitalUhr         [WUHR]
  365.                 - TDruckOptionen      [WPRINT]
  366.                 - TIconEdit           [WICNEDIT]
  367.                 - TInputDialog        [WFILEDLG]
  368.                 - TOutputDialog       [WFILEDLG]
  369.                 - TPalWorkShop        [WPALETTE]
  370.                 - TPrintOptionWindow  [WPRINT]
  371.                 - TScale              [WPALETTE]
  372.              - TGrayBar               [WPALETTE]
  373.              - THelpWindow            [WHELP]
  374.        - TMainMenu                    [WVIEWS]
  375.           - TSubMenu                  [WVIEWS]
  376.        - TScrollBar                   [WDLG]
  377.  - TObject                            [WDECL]
  378.     - TJoyStickDevice                 [WDRIVER]
  379.     - TKeyboardDevice                 [WDRIVER]
  380.     - TMouseDevice                    [WDRIVER]
  381.     - TPixelFont                      [WFONT]
  382.     - TSSDigiDevice                   [WDRIVER]
  383.     - TVektorFont                     [WFONT]
  384.     - TVideoDevice                    [WDRIVER]
  385.  - TLinePrint                         [WPRINT]
  386.  - TPalette                           [WPALETTE]
  387.  - TPCXImage                          [WPCX]
  388.  - TPoint                             [WDECL]
  389.  - TRect                              [WDECL]
  390.  - TText                              [WTEXT]
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.                                                     WG-Vision  VIII
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409. Leistungsmerkmale von WG-VISION
  410.  
  411. Allgemeine Angaben
  412.  
  413. - 65 Objekte in 21 Units
  414. - 12000 Zeilen Quelltext in der Profiversion
  415.  
  416. Hardware
  417.  
  418. WG-Vision unterstützt
  419.  
  420. - Maus
  421. - Tastatur
  422. - Joystick
  423. - Digitizer  (Summagraphic MM-Serie)
  424.  
  425. Grafik
  426.  
  427. - Standard-VGA und EGA  (VGA wird empfohlen)
  428. - Super-VGA's mit VESA-Unterstützung (VESA-Treiber für die
  429.   meisten Grafikcontroller verfügbar), 256 Farben in allen
  430.   unterstützten Auflösungen (nur Voll- und Profiversion)
  431.  
  432. Oberfläche
  433.  
  434. - WG-Vision erlaubt die Erstellung von Programmen mit einer
  435.   stark an Windows angelegten Nutzeroberfläche (GUI)
  436. - SAA-konformes Menüsystem. Unterstützung von Menü-
  437.   Ressourcendateien.
  438. - Programmierung von Statuszeile und Iconleisten problemlos
  439.   möglich.
  440. - Kontextsensitives Hilfesystem
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.                                                     WG-Vision  IX
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459. - voll fensterorientiert
  460.     * Verschiebbare und in ihrer Größe veränderbare Fenster
  461.     * Dialogboxen mit - Druckschalter (mit und ohne Icons)
  462.                       - Radio- und Checkbuttons
  463.                       - Eingabefelder mit Editierfunktionen
  464.                         und Rollen
  465.                       - Eingabemasken
  466.                       - Zählschalter
  467.                       - Listboxen mit horizontalen und
  468.                         vertikalen Rollbalken
  469.                       - Statische Texte, Unterstützung von
  470.                         9 Vektorzeichensätzen
  471.                       - Gruppenrahmen und Icons
  472.     * Mitteilungsfenster (Messageboxen)
  473.     * Fenster mit Rollbalken
  474.     * Childfenster
  475.  
  476. Die Bedienung eines WG-Vision-Programmes kann mit der Maus
  477. und mit der Tastatur erfolgen
  478.  
  479. Speicher
  480.  
  481. - Verwendung von EMS zur Auslagerung von Fenster-
  482.   Untergrundbereichen und Daten. Wenn kein EMS vorhanden
  483.   ist, werden Bildschirmbereiche in tempöräre Swapdateien
  484.   gerettet.
  485. - Speicherobjekte für Heap, Festplatte und EMS
  486.  
  487. Zusätzlich zu den Kernroutinen enthält WG-Vision Objekte für
  488.  
  489. - Datei Ein- und Ausgabedialoge
  490. - Paletteneditor für die 256-farbigen VESA-Modi
  491. - IconEditor
  492. - Digitaluhr
  493. - Erweiterte Funktionen des Coprozessors (ab INTEL 80387)
  494. - VGA-Fonts im Grafikmodus, 6 Sonderzeichensätze für
  495.   Standard-VGA
  496. - Laden und Speichern von PCX-Bildern mit 16 und 256 Farben
  497.  
  498.  
  499.  
  500.  
  501.                                                     WG-Vision  X
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509. Hinweise zur Arbeit mit der Klassenbibliothek
  510.  
  511. 1. Units
  512.  
  513. In den Programmbeispielen des Handbuchs werden die einzu-
  514. bindenden Units i.R. explizit nicht angegeben. Schauen Sie
  515. deshalb in der Tabelle der Objekte nach, in welcher Unit das
  516. betreffende Objekt implementiert ist.
  517.  
  518. 2. Verzeichnisse
  519.  
  520. Für ein Pascal-Projekt hat sich folgende Verzeichnisstruktur bewährt:
  521.  
  522. -  Projekt - EXE            {EXE und TPU's}
  523.            - UNITS          {Projekt- und WG-VISION-Units}
  524.            - INC            {COMPILER.INC, INC-Dateien}
  525.            - OBJ            {Objektdateien}
  526.  
  527. Wenn Sie mit Borland Pascal 7.0 und nur mit den TPU's
  528. von WG-VISION arbeiten, dann sollten Sie diese TPU's in
  529. das Verzeichnis BIN von BP7 kopieren. Andernfalls müssen Sie
  530. in einem separaten Verzeichnis oder im Verzeichnis EXE des
  531. Projekts zugänglich sein. Nicht vergessen, in der IDE
  532. Directories einstellen !
  533.  
  534. 3. IDE
  535.  
  536. - Linkpuffer auf "Disk" stellen
  537. - TP6/7: EMS verwenden
  538. - Directories einstellen
  539. - Kompilieren auf DISK
  540. - Einstellungen in <Projektname>.TP retten
  541.  
  542. 4. Compileroptionen
  543.  
  544. Die Compileroptionen befinden sich in der Include-Datei
  545. COMPILER.INC. Sie werden beim Compilieren der Bibliothek
  546. über den Include-Befehl in die Units mit eingebunden. Wenn
  547. Sie die Quellen von WG-Vision besitzen, dann sollten Sie in
  548.  
  549.  
  550.  
  551.                                                     WG-Vision  XI
  552.  
  553.  
  554.  
  555.  
  556.  
  557.  
  558.  
  559. der Testphase Ihres Programms die Präprozessorkonstante
  560. Debug einschalten, damit Sie mit dem Debugger auch innerhalb
  561. der Units von WG-Vision herumstöbern können. COMPILER.INC
  562. hat folgenden Aufbau:
  563.  
  564. (************************************************
  565. *                                               *
  566. * COMPILER-Optionen für WG-Vision 1.0           *
  567. *                                               *
  568. *---------------------------------------------- *
  569. * (c) 1992/93 Dipl.Phys. Mathias Scholz         *
  570. ************************************************)
  571.  
  572. { Die Optionen sind auf maximale Geschwindigkeit ausgelegt}
  573.  
  574. {$DEFINE Debug}   { Nur in der Testphase setzen! }
  575.  
  576. {$IFDEF Debug}    { Debugging eingeschaltet }
  577.  
  578. {$A+,B-,D+,F-,G+,I+,L+,O-,P-,Q+,R+,S+,T-,V+,X-,Y+}
  579.  
  580. {$ELSE}
  581.  
  582. {$A+,B-,D-,F-,G+,I-,L-,O-,P-,Q-,R-,S-,T-,V+,X-,Y+}
  583.  
  584. {$ENDIF}
  585.  
  586. { Checking, ob Coprozessor vorhanden ist }
  587.  
  588. {$IFDEF CPU87}
  589.  
  590. {$N+,E-}
  591.  
  592. {$ELSE}
  593.  
  594. {$N+,E+}
  595.  
  596. {$ENDIF}
  597.  
  598.  
  599.  
  600.  
  601.                                                     WG-Vision  XII
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609. Unterschiede zwischen Shareware- und Vollversion
  610.  
  611. WG-VISION wird in drei Varianten angeboten:
  612.  
  613. 1. Sharewareversion : Darf frei kopiert und vervielfältigt werden,
  614.                       wenn der Inhalt der Diskette dabei nicht
  615.                       verändert wird. Für den Kopierservice dürfen
  616.                       maximal 15.- DM verlangt werden.
  617.  
  618. 2. Vollversion      : Enthält das Programmpaket in Form von TPU's
  619.                       für die Borland-Compiler TP6 / TP7 und BP7.
  620.                       Der Preis beträgt 59.- DM + Porto und Verpackung.
  621.  
  622. 3. Profiversion     : Enthält alle Quellen von WG-VISION.
  623.                       Der Preis beträgt 149.- DM + Porto und Verpackung.
  624.  
  625. In der Shareware-Version werden nur die 16-farbigen EGA- und VGA-Modi
  626. unterstützt. Außerdem erscheint am Ende eines mit WG-VISION kompilierten
  627. Programms ein Registrierhinweis. Beim Anklicken des ENDE-Buttons vom
  628. Desktop wird ein Copyright-Fenster aufgeblendet. Weitere Einschränkungen
  629. sind nicht vorhanden.
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.                                                     WG-Vision  XIII
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659. Aus der Szene ...
  660.  
  661.  
  662. Fachhochschule für Technik und Wirtschaft Reutlingen
  663.  
  664. ... unsere Studenten sind von Ihrem Produkt beeindruckt.
  665.  
  666. JDS-Report 5/93 (Rainer Nausedat)
  667.  
  668. ... Mit WGRAPH 2.0 stellt der Autor Dipl.Phys. Mathias Scholz
  669. nun eine objektorientierte Klassenbibliothek für Turbo- und
  670. Borland-Pascal vor, die jedem fleißigen Turbo-Vision-Nutzer
  671. die Tränen der Freude in die Augen treiben dürfte.
  672.  
  673. ... Die mit WGRAPH erzeugten Fenster, Messageboxen, Menüs etc.
  674. sind optisch höchst ansprechend und zeugen von der Liebe des
  675. Programmierers zum Detail. Bei der Gestaltung der Fenster,
  676. Menüs etc. wurde auch auf absolute Kleinigkeiten geachtet.
  677. Das Outfit der mit WGRAPH erzeugten Programme ist professionell.
  678.  
  679. ... Ich empfehle bei Gefallen unbedingt den Kauf der Quelltext-
  680. version: Der Autor gestattet auch die lizenzfreie Nutzung von
  681. Programmteilen (z.B. PCX-Bilder lesen und schreiben) und weiterhin
  682. ist WGRAPH auch gut als Lehrstück geeignet. Anstatt sich bei einem
  683. Massenverlag ein Buch für rund 100.- DM über Turbo Pascal und die
  684. objektorientierte Programmierung zu kaufen, sollte man sich lieber
  685. seine Handbücher schnappen und den Quelltext von einem Produkt wie
  686. WGRAPH durchackern. Der Nutzen ist wesentlich größer und zudem hat
  687. man auch noch eine vollständige, ansprechende Bibliothek.
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701.                                                     WG-Vision  XIV
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709. Mit WG-Vision wurden vom Autor bis jetzt folgende größere Projekte
  710. erstellt:
  711.  
  712. SBG 1.0   Digitale Bildverarbeitung für ST4-CCD-Kameras (diese Kamera
  713.           wird von Amateurastronomen zur Fotografie von kosmischen
  714.           Objekten eingesetzt). Die Demo-Version liegt der Klassen-
  715.           bibliothek bei (SBGDEMO.EXE)
  716.  
  717. IMOD      Berechnung der Schadstoffausbreitung nach dem Gauß-Modell
  718.           unter Berücksichtigung komplizierter orographischer und
  719.           meteorologischer Verhältnisse
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734.  
  735.  
  736.  
  737.  
  738.  
  739.  
  740.  
  741.  
  742.  
  743.  
  744.  
  745. Programmierhandbuch                                 WG-Vision - 1 -
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752. 1. Programmieren mit WG-Vision
  753.  
  754. Der Aufbau einer grafischen Oberfläche für ein Programm ist
  755. eine zeitraubende und fehleranfällige Angelegenheit. Das
  756. gilt besonders dann, wenn man näherungsweise die Funktiona-
  757. lität und Flexibilität von Windows als Prototyp einer grafi-
  758. schen Betriebssystem-Erweiterung anstrebt. Eine ausgefeilte
  759. Fenstertechnik in Verbindung mit einer ereignisgesteuerten
  760. Programmarchitektur läßt sich am komfortabelsten mit Hilfe
  761. objektorientierter Programmiermethoden realisieren. Borlands
  762. Spitzenprodukte Turbo-Vision und Object Windows können dabei
  763. als Vorbild dienen.
  764. WG-Vision besteht aus einer Anzahl von Kernbibliotheken, die
  765. in ihrer Einheit und Komplexität den Aufbau von Tastatur-
  766. und Maus-gesteuerten Programmen ermöglichen, die sich im ge-
  767. wohnten Windows-Look dem Nutzer präsentieren. Ein "klassi-
  768. scher" Pascal-Programmierer muß bei der Arbeit mit WG-Vision
  769. in vielerlei Hinsicht umdenken. An erster Stelle ist die Be-
  770. herrschung objektorientierter Programmiertechniken zu nen-
  771. nen. Sie sind Voraussetzung, um mit WG-Vision ansprechende
  772. und fehlerfreie Programme zu erstellen. Da es bereits eine
  773. ganze Anzahl guter Bücher gibt, die sich mit objektorien-
  774. tierter Programmierung beschäftigen, soll hier nicht weiter
  775. auf dieses Thema eingegangen werden. Trotzdem möchte ich
  776. keinen Leser abschrecken, der noch nie etwas über diese neue
  777. Art von Programmieren gehört hat. WG-Vision ist durchaus ge-
  778. eignet, um OOP (object oriented programming) zu erlernen.
  779. Vor der Verwendung einzelner Units aus WG-Vision als her-
  780. kömmliche Bibliotheken möchte ich warnen (mit Ausnahme viel-
  781. leicht von WDRIVER, WFONT und WEMS), da sie nur als Einheit
  782. ihre Fähigkeiten entfalten können. Da die Objekte der
  783. Toolbox hierarchisch geordnet sind, macht es auch wenig
  784. Sinn, sie aus ihrem ganz spezifischen Zusammenhang zu
  785. reißen. Ein WG-Vision Programm wird entweder ganz aus WG-
  786. Vision heraus entwickelt oder man läßt es bleiben. Einen
  787. Mittelweg gibt es nicht. Das bedeutet keine Einschränkung in
  788. den Möglichkeiten von WG-Vision. So gesehen bildet diese
  789. Klassenbibliothek ein festes Fundament, auf das sich mehr
  790. oder weniger komplexe Programme aufbauen lassen.
  791.  
  792.  
  793.  
  794. Programmierhandbuch                                 WG-Vision - 2 -
  795.  
  796.  
  797.  
  798.  
  799.  
  800.  
  801.  
  802. 2. Aufbau von WG-Vision
  803.  
  804. Der Kern von WG-Vision besteht aus folgenden Units:
  805.  
  806. WDECL     : Enthält grundlegende Deklarationen und einige
  807.             Standardobjekte wie TRect und TObject
  808.  
  809. WAPP      : Applikationsobject
  810.  
  811. WVIEWS    : Objektverwaltung (TView, TGroup, Menü und
  812.             Desktop)
  813.  
  814. WDLG      : Fenster- und Dialogobjekte
  815.  
  816. WEVENT    : Event-Verwaltungsroutinen
  817.  
  818. WDRIVER   : Treiber für Bildschirm, Tastatur, Maus, Joystick
  819.             und Summagraphic-Digitizer
  820.  
  821. WEMS      : Verwaltungsroutinen für Expanded Memory
  822.  
  823. WERROR    : Fehlermitteilungen
  824.  
  825. Der Kern verwendet wiederum einige Objekte, die in folgenden
  826. Units zusammengefaßt sind:
  827.  
  828. WUTILS    : Allgemeine Hilfsroutinen
  829.  
  830. WTEXT     : Textausgabe und Texthandling
  831.  
  832. WFONT     : Zusatzzeichensätze im Grafikmodus, ROM-Zeichen-
  833.             sätze und BGI-Vektorzeichensätze
  834.  
  835. Folgende Bibliotheken wurden bereits mit WG-Vision
  836. entwickelt und dienen speziellen Aufgaben. Da Sie als Quell-
  837. text vorliegen, können sie als Beispiele für die Programm-
  838. entwicklung mit WG-Vision dienen:
  839.  
  840. WPCX      : Laden und Speichern von 16-farbigen PCX-Bildern
  841.  
  842.  
  843.  
  844. Programmierhandbuch                                 WG-Vision - 3 -
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852. W256PCX   : Laden und Speichern von 256-farbigen PCX-Bildern
  853.             (nur Voll- und Profi-Version)
  854.  
  855. WPALETTE  : Palettenmanipulation (VESA), Paletteneditor
  856.  
  857. WFILEDLG  : Dialoge zum Laden und Speichern von Dateien
  858.  
  859. WHELP     : kontextsensitives Hilfesystem
  860.  
  861. WCALC     : Taschenrechner
  862.  
  863. WPRINT    : Druckdialoge (Text)
  864.  
  865. WICNEDIT  : Icon-Editor für WG-VISION
  866.  
  867. WCPROC    : Erweiterte Funktionen des Coprozessors
  868.             (ab 80387), Mathematische Standardfunktionen
  869.  
  870.  
  871.  
  872.  
  873.  
  874.  
  875.  
  876.  
  877.  
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890.  
  891.  
  892.  
  893.  
  894. Programmierhandbuch                                 WG-Vision - 4 -
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902. 3. Programmierung des Desktops
  903.  
  904. Das Desktop stellt die Arbeitsfläche unseres Programms dar.
  905. Es hat das Aussehen eines einzigen großen Fensters, welches
  906. im Normalfall den gesamten Bildschirm überdeckt. Standard-
  907. mäßig besteht es aus folgenden Teilen:
  908.  
  909. - Doppelrahmen
  910.  
  911. - Titelleiste (Panel)
  912.  
  913. - Menüleiste mit den Hauptmenüeintragungen
  914.  
  915. - Arbeitsfläche
  916.  
  917. Außerdem kann es noch mit einer Statuszeile ausgestattet
  918. werden.
  919. Das Panel besitzt in der linken Seite ein Quadrat mit einem
  920. kleinen Rechteck im Zentrum. Dieses Zeichen wird als Ende-
  921. Icon bezeichnet. Wir finden es auch bei den von WG-Vision
  922. generierten Fenstern wieder. Dort verbirgt sich darunter ein
  923. kleines Pull-Down-Menü, welches in Anlehnung an Windows als
  924. "Systemmenü" bezeichnet werden soll. Wenn mit der Maus das
  925. Ende-Icon des Desktop angeklickt wird, dann wird das Pro-
  926. gramm geschlossen. Im Klartext bedeutet das, daß WG-Vision
  927. ein cmCloseApplication-Kommando (verpackt in einem Ereignis-
  928. Rekord) generiert, welches das Programm beendet und die
  929. Steuerung wieder dem Betriebssystem übergibt. Natürlich kann
  930. der Programmierer diese Botschaft abfangen und sie z.B. be-
  931. nutzen, um eine Abfrage der Form "Wollen Sie dieses Programm
  932. wirklich beenden, ja/nein" zu realisieren. Eine weitere Mög-
  933. lichkeit zum Schließen einer Applikation besteht in der Ta-
  934. stenkombination <alt><x>.
  935. Das Desktop wird von einem der grundlegensten Objekte von
  936. WG-Vision, TApp, zur Verfügung gestellt. Jedes Programm, das
  937. Sie mit WG-Vision entwickeln, muß ein Nachkomme von diesem
  938. Objekt sein.
  939. Um das Standard-Desktop auf dem Bildschirm zu zaubern, sind
  940. nur folgende Programmzeilen notwendig:
  941.  
  942.  
  943.  
  944. Programmierhandbuch                                 WG-Vision - 5 -
  945.  
  946.  
  947.  
  948.  
  949.  
  950.  
  951.  
  952. program Desktop;
  953.  
  954. uses WApp;
  955.  
  956. type TApplication=object(TApp)
  957.      end;
  958.  
  959. var MyApp:TApplication;
  960.  
  961. begin
  962.   MyApp.Init('Standard-Desktop');  {Initialisierung + Paneltext}
  963.   MyApp.Run;                       {Abarbeitungsschleife}
  964.   MyApp.Done;                      {Aufräumen und Beenden}
  965. end.
  966.  
  967. MyApp hat als Instanz von TApplication alle Eigenschaften
  968. von TApp geerbt. Natürlch hätte man auch gleich eine Instanz
  969. von TApp bilden können. In diesem Fall wäre aber eine Wei-
  970. terentwicklung des Programms nicht mehr möglich gewesen.
  971. Erst die Ableitung eines neuen Objektes erlaubt die Eigen-
  972. schaften dieses Objektes gezielt zu verändern. Das kann
  973. entweder durch das Überschreiben bereits vorhandener virtu-
  974. eller Methoden oder durch die Implementierung von neuen Me-
  975. thoden geschehen. Doch bevor wir näher darauf eingehen,
  976. schauen wir uns noch einmal das Desktop in seiner Grundein-
  977. stellung an:
  978.  
  979. - Grafik VGA (640x480x16)
  980. - Graugemusterter Arbeitsbereich
  981. - Blaues Panel mit Überschrift
  982. - Hellgrauer Doppelrahmen
  983. - Leere weiße Menüzeile
  984. - Mauszeiger bei installierten Maustreiber
  985.  
  986. Das Aussehen des Desktops läßt sich leicht verändern. Das
  987. betrifft die Größe, den Grafikmodus und die farbliche Ge-
  988. staltung.
  989.  
  990.  
  991.  
  992.  
  993.  
  994. Programmierhandbuch                                 WG-Vision - 6 -
  995.  
  996.  
  997.  
  998.  
  999.  
  1000.  
  1001.  
  1002. 3.1.  Aufbau des Desktop
  1003.  
  1004. Das Desktop besteht im Wesentlichen aus zwei Bestandteilen,
  1005. dem Rahmen (Frame) und dem Hintergrund. Um Mißverständnissen
  1006. vorzubeugen, soll folgende Sprachregelung gelten. Der Hin-
  1007. tergrund ist immer der Bereich zwischen dem Rahmen, der auf
  1008. dem Bildschirm zu sehen ist. Im Fall des Desktops ist das
  1009. der graugemusterte Arbeitsbereich. Als Untergrund soll der
  1010. rechteckige Bereich des Bildschirms bezeichnet werden, der
  1011. vom Rahmen und dem Hintergrund abgedeckt wird. Im Fall eines
  1012. Fensters lagert WG-Vision den Untergrund in eine Datei bzw.
  1013. in den EMS aus, während der Hintergrund und der Rahmen des
  1014. darüberliegenden Fensters angezeigt wird. Erst beim Schlie-
  1015. ßen des Fensters erfolgt eine Restauration des Untergrundes,
  1016. wobei das gerade aufgeblendete Fenster verschwindet.
  1017. Rahmen und Hintergrund sind zwei separate Objekte mit ganz
  1018. speziellen Eigenschaften. Bei der Initialisierung des Desk-
  1019. tops werden zwei Pointer auf Instanzen dieser Objekte er-
  1020. zeugt und in eine Liste mit dem Namen List eingefügt. Das
  1021. geschieht für Sie unsichtbar in der Unit WApp mittels der
  1022. Methode InsertItem. List ist wie alle Listenobjekte in WG-
  1023. Vision eine Instanz von TGroup. Dieses wirklich grundlegende
  1024. Objekt stellt eine doppelt verkettete Liste einschließlich
  1025. einer großen Anzahl von Methoden zu deren Verwaltung zur
  1026. Verfügung.
  1027. Damit Sie den Rahmen und den Hintergrund des Desktops nach
  1028. Ihrem Ermessen gestalten können, stellt Ihnen TApp die vir-
  1029. tuellen Methoden SetDesktopFrame und SetDesktopBackground
  1030. zur Verfügung. Diese Methoden sind virtual deklariert und
  1031. lassen sich bei Bedarf überschreiben. Wie das konkret
  1032. gemacht wird, zeigt eines der nächsten Beispiele.
  1033.  
  1034. 3.2. Gestaltung des Rahmens
  1035.  
  1036. Der Desktop-Rahmen besteht aus einem Außenrahmen, dem Panel
  1037. mit Text und dem Ende-Icon. Er ist ein eigenständiges Objekt
  1038. mit der Bezeichnung TFrame (alle Objekte in WG-Vision begin-
  1039. nen mit einem großen T, alle Typen mit einem kleinen t und
  1040. alle Zeiger auf Objekte mit einem großen P etc.). Der Rahmen
  1041.  
  1042.  
  1043.  
  1044. Programmierhandbuch                                 WG-Vision - 7 -
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052. ist sehr komplex. Er muß sich nicht nur selbst darstellen,
  1053. sondern auch auf Maus- und Tastaturereignisse reagieren kön-
  1054. nen. Diese Eigenschaften werden aber erst bei frei ver-
  1055. schieb- und skalierbaren Fenstern benötigt. Der Desktop-
  1056. Rahmen ist statisch. Es läßt sich lediglich seine Größe, die
  1057. Form (Einfach- oder Doppelrahmen) und die Färbung ändern.
  1058. Um einen neuen Rahmen zu gestalten, muß die Methode SetDesk-
  1059. topFrame überschrieben werden:
  1060.  
  1061. ...
  1062. type TApplication=object(TApp)
  1063.       procedure SetDesktopFrame(Titel:string); virtual;
  1064.      end;
  1065.  
  1066. ...
  1067.  
  1068. procedure TApplication.SetDesktopFrame(Titel:string);
  1069. var R:TRect;
  1070. begin
  1071.   with Desktop^ do
  1072.    begin
  1073.      GetBounds(R);
  1074.      Frame:=new(PFrame, Init(R,R,Titel,winDouble+winPanel+winMenu));
  1075.      Frame^.Palette:=Pal(palRed);
  1076.      List^.InsertItem(Frame):
  1077.    end;
  1078. end;
  1079.  
  1080. Welche Informationen benötigt nun das Rahmenobjekt, um sich
  1081. eine neue Form zu geben. Als Erstes seine Größe. Da der
  1082. Desktop-Rahmen im Allgemeinen den gesamten Bildschirm um-
  1083. faßt, benötigt er die Pixelmaße des Bildschirms. Diese wie-
  1084. derum hängen von der Auflösung des gerade aktiven
  1085. Grafikmodus ab. Da WG-Vision diese Maße bekannt sind (sie
  1086. ergeben sich bei der Initialisierung des Grafikmodus), brau-
  1087. chen Sie nur explizit aus den entsprechenden Variablen aus-
  1088. gelesen zu werden. Das geschieht mittels der Methode
  1089. GetBounds(R). Dabei ist R ein TRect-Objekt (d.h. nichts an-
  1090. deres als ein Rechteck mit den Diagonalpunkten A und B), in
  1091.  
  1092.  
  1093.  
  1094. Programmierhandbuch                                 WG-Vision - 8 -
  1095.  
  1096.  
  1097.  
  1098.  
  1099.  
  1100.  
  1101.  
  1102. dem nach Abarbeitung von GetBounds die Eckpunktkoordinaten
  1103. des Bildschirms gespeichert sind. Eine weitere Information
  1104. betrifft das Aussehen des Rahmens, Es wird durch folgende
  1105. vordefinierte Konstanten festgelegt:
  1106.  
  1107. winSingle / winDouble    Rahmenform
  1108. winPanel                 mit Titelleiste
  1109. winMenu                  mit Ende-Icon
  1110.  
  1111. Diese Konstanten lassen sich additiv verknüpfen und werden
  1112. zusammen mit R und dem Títeltext dem Konstruktor von TFrame
  1113. übergeben. Der Rahmen selbst wird im Heap angelegt und ein
  1114. Pointer darauf (Frame) in die Elementeliste des Desktop's
  1115. eingefügt. Um eine andere Rahmenform zu erhalten, müssen die
  1116. Rahmenkonstanten entsprechend kombiniert werden. Wünschen
  1117. Sie z.B. einen einfachen Desktop-Rahmen mit Titelleiste aber
  1118. ohne Ende-Icon, dann lautet die entsprechende Zeile im
  1119. Quelltext:
  1120.  
  1121. Frame:=new(PFrame, Init(R,R,winSingle+winPanel));
  1122.  
  1123. Wenn Sie auf eine Titelzeile verzichten, dann wird die Menü-
  1124. zeile an die Position der Titelzeile gesetzt.
  1125. Das Rechteck R beschreibt, wie bereits erwähnt, die Außmaße
  1126. des Desktops. Es enthält als TRect-Objekt nach Aufruf von
  1127. GetBounds die Koordinaten des linken oberen (Punkt A) und
  1128. des rechten unteren Eckpunktes (Punkt B) des Bildschirms. Um
  1129. das Desktop zu verkleinern, muß lediglich R verändert wer-
  1130. den. TRect-Objekte verfügen zu diesem Zweck die Methoden
  1131. Grow(a,b) und Move(dx,dy). Mit Grow verändert man die Größe
  1132. des Rechtecks, indem zu den Koordinaten der rechten unteren
  1133. Ecke a und b addiert wird. Move verschiebt das Rechteck um
  1134. dx und dy auf dem Bildschirm. Um das Desktop zu verkleinern
  1135. und anschließend zu zentrieren sind demnach zwei Schritte
  1136. notwendig:
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144. Programmierhandbuch                                 WG-Vision - 9 -
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152. ...
  1153. GetBounds(R);          {Dektop-Größe holen}
  1154. R.Grow(-200,-80);      {R verkleinern}
  1155. R.Move(100,40);        {R verschieben}
  1156. ...
  1157.  
  1158.  
  1159. Durch die Größenänderung wird auch der Arbeitsbereich klei-
  1160. ner. Dem muß man Rechnung tragen, indem man die Größe des
  1161. Workareas (d.h. der Arbeitsfläche) an die neuen Verhältnisse
  1162. anpaßt:
  1163.  
  1164. WorkArea.Assign(R.A.x+4,R.A.y+46,R.B.x-4,R.B.y-4);
  1165.  
  1166. Das Workarea beschreibt jenen Bereich des Desktops, inner-
  1167. halb dessen Fenster verschoben  oder in ihrer Größe geändert
  1168. werden können.
  1169. Wenn Sie möchten, können Sie jetzt noch die Farbe des Rah-
  1170. mens ändern. In unserem Beispiel geschieht das durch die Zu-
  1171. weisund der Standard-Palette palRed. Sie können natürlich
  1172. auch jedes Rahmenelement separat einfärben. In WG-Vision
  1173. werden Farbpaletten als Strings definiert. Jedes Zeichen
  1174. stellt einen Farbeintrag dar. Dabei werden die Turbo-Pascal-
  1175. Farbnummern mit einem vorangestellten Doppelkreuz (z.B. #12
  1176. für Hellrot) verwendet. Das ist nichts weiter als die Defi-
  1177. nition eines ASCII-Zeichens über dessen Ordinalzahl.
  1178. Die Rahmen-Palette (Palette1) hat folgenden Aufbau:
  1179.  
  1180. Eintrag     Bedeutung               Standard
  1181.  
  1182.    1        Außenrahmen             #0  Schwarz
  1183.    2        Zwischenrahmen          #7  Hellgrau
  1184.    3        Innenrahmen             #0  Schwarz
  1185.    4        Panelmischfarbe 1       #1  Blau
  1186.    5        Panelmischfarbe 2       #9  Hellblau
  1187.    6        Textfarbe Titelzeile    #15 Weiß
  1188.  
  1189.  
  1190. Palette1:=#0#7#0#1#9#15{...};
  1191.  
  1192.  
  1193.  
  1194. Programmierhandbuch                                 WG-Vision - 10 -
  1195.  
  1196.  
  1197.  
  1198.  
  1199.  
  1200.  
  1201.  
  1202. Die Einträge in geschwungenen Klammern werden von anderen
  1203. Objekten benutzt.
  1204. Neben der Zuweisung einer Standardpalette stehen noch fol-
  1205. gende Möglichkeiten zur Palettenmanipulation zur Verfügung:
  1206.  
  1207. ...
  1208. with Desktop^ do
  1209.  begin
  1210.    GetBounds(R);
  1211.    Frame:=new(PFrame, Init(R,R,Titel,winDouble+winPanel));
  1212.    Frame^.Palette:=#15#11#0#1#9#15;   {1. Möglichkeit}
  1213.    Frame^.Palette:=Pal[palGray];      {2. Möglichkeit}
  1214.    Frame^.Palette[4]:=#14;            {3. Möglichkeit}
  1215.    Frame^.Palette[2]:=#12;
  1216.    ...
  1217.  end;
  1218. ...
  1219.  
  1220. Pal ist ein array of string, wobei die Konstanten palStan-
  1221. dard, palRed, palGray und palGreen Indizes in diesem Feld
  1222. sind.
  1223. Wichtig ist, daß Sie die Farbmanipulation vor dem Einfügen
  1224. von Frame in List ausführen.
  1225. Die in diesem Abschnitt beschriebene Art der Farbmanipulati-
  1226. on gilt übrigens auch für andere Objekte innerhalb von WG-
  1227. Vision. Jeder sich selbst darstellbare Objekttyp (z.B. Fen-
  1228. ster oder einzelne Dialogelemente) besitzt eine eigene vor-
  1229. definierte Farbpalette, die nachträglich leicht manipu-
  1230. lierbar ist. Zum Teil stellt WG-Vision sogar spezielle
  1231. Methoden zur Manipulation von Farbeinträgen zur Verfügung.
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244. Programmierhandbuch                                 WG-Vision - 11 -
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252. 3.3. Gestaltung des Arbeitsbereiches (Hintergrund)
  1253.  
  1254. Für das Aussehen des Arbeitsbereiches ist das Objekt
  1255. TDsktpBgrd zuständig. Standardmäßig stellt es nichts weiter
  1256. als eine graugemusterte Fläche dar. Um Änderungen vorzuneh-
  1257. men, müssen Sie entweder die Draw-Methode des TDsktpBgrd-Ob-
  1258. jekts überschreiben oder, wenn Ihnen nur die Farbe stört,
  1259. die entsprechenden Paletteneinträge ändern.
  1260. Beginnen wir mit dem einfachsten Fall. Genauso wie der Rah-
  1261. men verwendet auch das Hintergrund-Objekt die Standardpalet-
  1262. te 1. Es benutzt jedoch nur die Einträge 7 und 8. Eintrag 7
  1263. legt den Hintergrund des Hauptmenü-Bereichs fest. Voreinge-
  1264. stellt ist die Farbe Weiß. Eintrag Nr. 8 ist für den Ar-
  1265. beitsbereich zuständig. Neben der Grundfarbe (standardmäßig
  1266. Weiß) wird immer die Farbe Schwarz dazugemischt. Damit erge-
  1267. ben sich zwangsläufig sehr dunkle Farben. Wenn das nicht
  1268. ausdrücklich gewünscht wird, dann sollten Sie sich überle-
  1269. gen, ob Sie nicht gleich den Hintergrund neu gestalten
  1270. sollten. Dazu muß lediglich die Draw-Methode des Hinter-
  1271. grund-Objekts überschrieben werden.
  1272. Folgendes Beispiel zeigt wie Sie vorgehen müssen, um den Ar-
  1273. beitsbereich mit einem grünen HatchFill-Muster zu versehen:
  1274.  
  1275. 1. Neues Hintergrundobjekt ableiten
  1276.  
  1277. ...
  1278. type PNewDTBgrd=^TNewDTBgrd;
  1279.      TNewDTBgrd=object(TDsktpBgrd)
  1280.       procedure Draw; virtual;
  1281.      end;
  1282.  ...
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.  
  1289.  
  1290.  
  1291.  
  1292.  
  1293.  
  1294. Programmierhandbuch                                 WG-Vision - 12 -
  1295.  
  1296.  
  1297.  
  1298.  
  1299.  
  1300.  
  1301.  
  1302. 2. Hintergrundobjekt in das Desktop einfügen
  1303.  
  1304. procedure TApplication.SetDesktopBackground;
  1305. var R:TRect;
  1306.     NBgrd:PNewDTBgrd;
  1307. begin
  1308.   with Desktop^ do
  1309.    begin
  1310.      R:=Frame^.Area;           {Bereich innerhalb des Rahmens bestimmen}
  1311.      NBgrd:=new(PNewDTBgrd, Init(R));    {Instanz auf dem Heap erzeugen}
  1312.      with NBgrd^ do
  1313.       begin
  1314.         Palette[7]:=#14;                         {Farben neu definieren}
  1315.         Palette[8]:=#10;
  1316.       end;
  1317.      List^.InsertItem(NBgrd);                {In Desktop-Liste einfügen}
  1318.    end;
  1319. end;
  1320.  
  1321. Beachten Sie, daß im Konstruktor das neue Hintergrundobjekt
  1322. angegeben wird. Das ist notwendig, da zur Hintergrundgestal-
  1323. tung eine neue Draw-Methode implementiert werden muß:
  1324.  
  1325. 3. Neue Draw-Methode
  1326.  
  1327. procedure TNewDTBgrd.Draw;
  1328. begin
  1329.  
  1330. Border enthält die Koordinaten des Bereichs innerhalb des Rahmens.
  1331.  
  1332.   with Border do
  1333.    begin
  1334.  
  1335. Menübereich, Hintergrund Gelb
  1336.  
  1337.      SetFillStyle(SolidFill, GetPalColor(7));
  1338.      Bar(A.x,A.y,B.x,A.y+20);
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344. Programmierhandbuch                                 WG-Vision - 13 -
  1345.  
  1346.  
  1347.  
  1348.  
  1349.  
  1350.  
  1351.  
  1352. Arbeitsbereich, Hatchfill
  1353.  
  1354.      SetFillStyle(HatchFill, GetPalColor(8));
  1355.      Bar(A.x,A.y+22,B.x,B.y);
  1356.    end;
  1357. end;
  1358.  
  1359. Die Variable Border enthält als TRect-Objekt die Koordinaten
  1360. des Bereichs innerhalb des dazugehörigen Fenster-Objekts.
  1361. Sie kann immer dann Verwendung finden, wenn der Hintergrund
  1362. eines Fensters (oder hier des Desktops) frei gestaltet wer-
  1363. den soll. Die Prozedur Draw verwendet die Punkte A und B, um
  1364. den zu füllenden Bereich konkret festzulegen. Natürlich ist
  1365. es Ihnen überlassen, was für Grafik-Befehle Sie zwischen
  1366. begin und end schreiben. Beispielsweise ist es auch möglich,
  1367. hier ein Hintergrundbild von Windows aufzublenden. Bedingung
  1368. ist, daß Sie die Windows-Bitmap zuvor in ein PCX-Bild umge-
  1369. wandelt haben. Sie können zu diesem Zweck natürlich auch je-
  1370. des x-beliebige PCX-Bild verwenden, eben das, welches Ihnen
  1371. gefällt und zu Ihrem Programm paßt. Sie müssen lediglich be-
  1372. achten, in welchem Grafikmodus WG-Vision gerade arbeitet.
  1373. PCX-Bilder mit 16 Farben unterscheiden sich eben doch von
  1374. PCX-Bildern mit 256 Farben. WG-Vision trägt dem Rechnung,
  1375. indem es zwei verschiedene Units zum Laden und Speichern
  1376. derartiger Bildern zur Verfügung stellt. WPCX arbeitet in
  1377. den 16-farbigen Standardmodi der VGA- bzw. EGA-Karte.
  1378. W256PCX erlaubt das Laden und Speichern von 256-farbigen
  1379. PCX-Bildern. Diese Unit ist natürlich nur sinnvoll, wenn ein
  1380. 256-Farb-Modus aktiv ist. Außerdem muß beachtet werden, daß
  1381. WG-Vision die ersten 16 Einträge der Farbpalette für sich
  1382. selbst benötigt und diese nicht unbedingt mit den Eintragun-
  1383. gen in der Palette der PCX-Datei übereinstimmen. Das ist
  1384. aber fast immer der Fall. Es bleibt also nichts anderes üb-
  1385. rig, als eine Farbreduktion und "Freilenken" der ersten 16
  1386. Paletteneintragungen vorzunehmen. Einige wenige Bildbearbei-
  1387. tungsprogramme sind dazu in der Lage (z.B. das Sharewarepro-
  1388. gramm IMPROCES).
  1389. Was muß man tun, um z.B. das 16-farbige PCX-Bild "WETT.PCX"
  1390. als Hintergrundbild für das Desktop zu laden ?
  1391.  
  1392.  
  1393.  
  1394. Programmierhandbuch                                 WG-Vision - 14 -
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401.  
  1402. 1. Neues Hintergrundobjekt ableiten
  1403.  
  1404. ...
  1405. type PNewDTBgrd=^TNewDTBgrd;
  1406.      TNewDTBgrd=object(TDsktpBgrd)
  1407.       BgImage:TPCXImage;            {Instanz von TPCXImage}
  1408.       procedure Draw; virtual;      {Draw-Methode}
  1409.      end;
  1410. ...
  1411.  
  1412. 2. Hintergrundobjekt in das Desktop einfügen
  1413.  
  1414. procedure TApplication.SetDesktopBackground;
  1415. var R:TRect;
  1416.     NBgrd:PNewDTBgrd;
  1417. begin
  1418.   with Desktop^ do
  1419.    begin
  1420.      R:=Frame^.Area;          {Bereich innerhalb des Rahmens bestimmen}
  1421.      NBgrd:=new(PNewDTBgrd, Init(R));   {Instanz auf dem Heap erzeugen}
  1422.      with NBgrd^ do
  1423.       begin
  1424.         Palette[7]:=#14;                        {Farben neu definieren}
  1425.         Palette[8]:=#9;
  1426.       end;
  1427.      List^.InsertItem(NBgrd);               {In Desktop-Liste einfügen}
  1428.    end;
  1429. end;
  1430.  
  1431.  
  1432.  
  1433.  
  1434.  
  1435.  
  1436.  
  1437.  
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444. Programmierhandbuch                                 WG-Vision - 15 -
  1445.  
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452. 3. Neue Draw-Methode
  1453.  
  1454. procedure TNewDTBgrd.Draw;
  1455. var R:TRect;
  1456. begin
  1457.   TDsktpBgrd.Draw;                       {Standard-Untergrund zeichnen}
  1458.   R.Copy(Border);         {Bereich innerhalb des Rahmens in R kopieren}
  1459.   R.A.y:=R.A.y+21;                             {Menübereich freihalten}
  1460.   BgImage.Init(R,'WETT.PCX');                     {Bild initialisieren}
  1461.   BgImage.LoadPCXImage(0);                                 {Bild laden}
  1462. end;
  1463.  
  1464. Als Erstes wird der Standard-Untergrund gezeichnet. Das ge-
  1465. schieht, in dem die Draw-Methode des Vorgängers (alse
  1466. TDsktpBgrd) aufgerufen wird. Als Nächstes wird der Bereich
  1467. festgelegt, in welches das Bild gezeichnet werden soll. Da-
  1468. bei müssen Sie darauf achten, daß die Menüzeile freigehalten
  1469. wird. Das erreicht man durch eine Neuzuweisung der y-Koordi-
  1470. nate der oberen linken Ecke des Ausschnitts (Punkt A). Jetzt
  1471. braucht nur noch das Bild von der Platte geladen und auf dem
  1472. Bildschirm dargestellt werden. Diese Arbeit übernehmen die
  1473. Routinen der Unit WPCX.
  1474.  
  1475.  
  1476.  
  1477.  
  1478.  
  1479.  
  1480.  
  1481.  
  1482.  
  1483.  
  1484.  
  1485.  
  1486.  
  1487.  
  1488.  
  1489.  
  1490.  
  1491.  
  1492.  
  1493.  
  1494. Programmierhandbuch                                 WG-Vision - 16 -
  1495.  
  1496.  
  1497.  
  1498.  
  1499.  
  1500.  
  1501.  
  1502. 3.4. Aufbau eines Menüs
  1503.  
  1504. Der Aufbau einer Menüstruktur ist mit WG-Vision spielend
  1505. einfach. Drei Schlüsselbefehle, MainMenu, SubMenu und New-
  1506. Line reichen aus, um ein komplexes Pull-Down-Menü zu erstel-
  1507. len, welches in Gestaltung und Bedienung weitgehend dem SAA-
  1508. Standard entspricht. Wem selbst das zu viel ist, hat noch
  1509. die Möglichkeit den Menübaum über eine Ressourcen-Datei zu
  1510. laden. Dieser Weg hat den Vorteil, daß man die Menüstruktur
  1511. einfach durch Austausch der entsprechenden Menüdatei ändern
  1512. kann ohne das Programm neu kompilieren zu müssen. Anpassun-
  1513. gen an andere Sprachen sind dadurch problemlos möglich.
  1514. WG-Vision-Menüs können genauso wie Windows-Menüs bedient
  1515. werden. Die <F10>-Taste aktiviert und deaktiviert das Haupt-
  1516. menü. Mit den Kursortasten kann man Untermenüs öffnen, Menü-
  1517. punkte auswählen und sich durch den Menübaum bewegen. Ein
  1518. Druck auf die <ESC>-Taste schließt ein gerade aktives Unter-
  1519. menü. Mit <ENTER> wird der gewünschte Menüpunkt ausgewählt.
  1520. Wer gerne mit Shortkeys arbeitet, wird auch nicht im Stich
  1521. gelassen. Die <alt>-Taste in Verbindung mit dem unterstri-
  1522. chenen Buchstaben öffnet das gewünschte Untermenü. Jetzt
  1523. braucht nur noch der entsprechende Buchstabe gedrückt wer-
  1524. den, um einen Menüpunkt aufzurufen.
  1525. Für besonders oft benötigte Funktionen können auch Hotkeys
  1526. vergeben werden. Mit ihrer Hilfe lassen sich Menüpunkte un-
  1527. ter Umgehung des Aufblendens des Menübaums aktivieren. Als
  1528. Hotkeys finden besonders die Funktionstasten Verwendung.
  1529. Am schnellsten und am Einfachsten gestaltet sich die Menü-
  1530. auswahl mit der Maus. Einfach Anklicken und fertig !
  1531. Von der Komplexität der Menüroutinen bemerken Sie als WG-Vi-
  1532. sion Programmierer praktisch nichts. Sie sind lediglich für
  1533. die Gestaltung des Menübaums zuständig.
  1534. Die zur Menüdefinition zuständige virtuelle Methode hat den
  1535. Namen InitMenuBar. Indem Sie diese Methode überschreiben,
  1536. bauen Sie nach und nach Ihr Desktop-Menü auf. Für ein einfa-
  1537. ches Malprogramm könnte es beispielsweise folgendermaßen
  1538. aussehen:
  1539.  
  1540.  
  1541.  
  1542.  
  1543.  
  1544. Programmierhandbuch                                 WG-Vision - 17 -
  1545.  
  1546.  
  1547.  
  1548.  
  1549.  
  1550.  
  1551.  
  1552. {Konstantendefinitionen für die Menü-Kommandos}
  1553.  
  1554. const cmNew    = 101;   cmRestore   = 201;
  1555.       cmLoad   = 102;   cmCut       = 202;
  1556.       cmSave   = 103;   cmCopy      = 203;
  1557.       cmPrint  = 104;   cmMove      = 204;
  1558.       cmErase  = 105;   cmTurn      = 204;
  1559.  
  1560.       cmMagni  = 301;   cmRoman     = 401;
  1561.       cmGrid   = 302;   cmScript    = 402;
  1562.       cmPencel = 303;   cmTimes     = 403;
  1563.       cmBrush  = 304;   cmNormal    = 404;
  1564.                         cmBold      = 405;
  1565.                         cmItalic    = 406;
  1566.                         cmUnderline = 407;
  1567. ...
  1568.  
  1569. type TApplication=object(TApp)
  1570.        procedure SetDesktopFrame(Titel:string);virtual;
  1571.        procedure SetDesktopBackground; virtual;
  1572.        procedure InitMenuBar; virtual;
  1573.      end;
  1574. ...
  1575.  
  1576. procedure TApplication.InitMenuBar;
  1577. begin
  1578.  
  1579. {Farbanpassung an das Desktop}
  1580.  
  1581.   Palette[1]:=#14;        {Hauptmenüzeile Hintergrundfarbe}
  1582.   Palette[5]:=#14;        {Untermenü,Hintergrundfarbe}
  1583.   Palette[4]:=#4;         {Hauptmenüzeile,Auswahlbalken}
  1584.   Palette[12]:=#4;        {Auswahlbalken}
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590.  
  1591.  
  1592.  
  1593.  
  1594. Programmierhandbuch                                 WG-Vision - 18 -
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.  
  1601.  
  1602. {Menüdefinition}
  1603.  
  1604.   MainMenu('~D~atei',1);
  1605.     SubMenu('~N~eues Bild',cmNew,0,0,false,false);
  1606.     SubMenu('Bild ~L~aden      F3',cmLoad,0,kbF3,false,false);
  1607.     SubMenu('Bild ~S~peichern  F2',cmSave,0,kbF2,false,false);
  1608.     NewLine;
  1609.     SubMenu('~D~rucken',cmPrint,0,0,false,false);
  1610.     SubMenu('Lös~c~hen',cmErase,0,0,false,false);
  1611.     NewLine;
  1612.     SubMenu('~B~eenden   Alt-X,cmCloseApplication,0,altX,false,false);
  1613.   MainMenu('~B~earbeiten',2);
  1614.     SubMenu('~R~ückgängig',cmRestore,0,0,false,false);
  1615.     NewLine;
  1616.     SubMenu('~S~chnitt',cmCut,0,0,true,false);
  1617.     SubMenu('~K~opieren',cmCopy,0,0,true,false);
  1618.     SubMenu('~V~erschieben',cmMove,0,0,true,false);
  1619.     SubMenu('~D~rehen',cmTurn,0,0,true,false);
  1620.   MainMenu('~W~erkzeuge',3);
  1621.     SubMenu('~V~ergrößern',cmMagni,0,0,false,false);
  1622.     NewLine;
  1623.     SubMenu('~R~aster',cmGrid,0,0,false,false);
  1624.     NewLine;
  1625.     SubMenu('~P~insel ändern',cmPencel,0,0,false,false);
  1626.     SubMenu('~S~pray ändern',cmBrush,0,0,false,false);
  1627.   MainMenu('~S~chrift',4);
  1628.     SubMenu('~R~oman',cmRoman,0,0,false,true);
  1629.     SubMenu('~S~cript',cmScript,0,0,false,false);
  1630.     SubMenu('~T~imes',cmTimes,0,0,false,false);
  1631.     NewLine;
  1632.     SubMenu('~N~ormal',cmNormal,0,0,false,true);
  1633.     SubMenu('~F~ett',cmBold,0,0,false,false);
  1634.     SubMenu('~K~ursiv',cmItalic,0,0,false,false);
  1635.     SubMenu('~U~nterstrichen',cmUnderline,0,0,false,false);
  1636. end;
  1637.  
  1638. Jeder Hauptmenüpunkt wird durch den Befehl MainMenu defi-
  1639. niert. Als erster Parameter folgt der Bezeichner, wobei der
  1640. "Shortkey" in Tilde-Zeichen eingeschlossen wird. Über diesen
  1641.  
  1642.  
  1643.  
  1644. Programmierhandbuch                                 WG-Vision - 19 -
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.  
  1652. Buchstaben in Kombination mit der Alt-Taste kann das dazuge-
  1653. hörige Untermenü aufgeklappt werden. Danach folgt eine von
  1654. ihnen festzulegende Zahl, der Help-Index. Er ist nur von Be-
  1655. deutung, wenn Sie ihr Programm mit einer Online-Hilfe-Funk-
  1656. tion ausstatten wollen.
  1657. Hauptmenüpunkte können keine Kommandos aussenden. Deshalb
  1658. ist eine direkte Steuerung des Programms durch Anklicken
  1659. bzw. Aktivieren eines Hauptmenüpunktes nicht möglich.
  1660. Zu jedem Hauptmenüpunkt gehört ein Untermenü mit möglichst
  1661. mehr als einem Eintrag. Es ist als Pull-Down-Menü gestaltet,
  1662. d.h. es wird nach Aktivierung des zugehörigen Hauptmenüpunk-
  1663. tes "aufgeklappt". In unserem Beispiel besitzt das Hauptmenü
  1664. "Datei" Untermenüs mit den Eintragungen "Neues Bild", "Bild
  1665. Laden", "Bild Speichern", "Drucken", "Löschen" und
  1666. "Beenden". Jedem Eintrag im Untermenü müssen Sie eine ein-
  1667. deutige Zahl zuordnen. Diese Zahl wird als Kommando bezeich-
  1668. net und im Konstantenteil ihrer Applikation vereinbart.
  1669. Kommandobezeichner werden in WG-Vision immer mit dem Präfix
  1670. "cm" versehen. Machen Sie es am besten genauso wie im Bei-
  1671. spiel. Wählen Sie als Kommandos einfach die Submenü-Bezeich-
  1672. ner mit einem vorangestellten "cm". Diese Kommandos
  1673. benötigen Sie später zur Identifizierung des ausgewählten
  1674. Menüpunktes.
  1675. Verwenden Sie als Kommandos bitte immer Zahlen >=100, da ei-
  1676. nige Kommandos, wie z.B. cmCloseApplication in WG-Vision be-
  1677. reits definiert sind. Folgende Vorgehensweise hat sich
  1678. bewährt: Die einzelnen Submenü-Punkte erhalten als Hunderter
  1679. die Nummer des dazugehörigen Hauptmenüs. Dazu addieren Sie
  1680. einfach die Untermenü-Nummern, sodaß sich beispielsweise für
  1681. das Menü "Bearbeiten" folgende Kommandofolge ergibt:
  1682.  
  1683. const cmRestore   = 201;
  1684.       cmCut       = 202;
  1685.       cmCopy      = 203;
  1686.       cmMove      = 204;
  1687.       cmTurn      = 204;
  1688.  
  1689. Neben der Aufruftaste (sie ist vorgeschrieben) können Sie
  1690. jedem Submenü-Punkt einen speziellen Hotkey zuordnen (z.B.
  1691.  
  1692.  
  1693.  
  1694. Programmierhandbuch                                 WG-Vision - 20 -
  1695.  
  1696.  
  1697.  
  1698.  
  1699.  
  1700.  
  1701.  
  1702. <F2> oder <alt><A>). Er wird als vierter Parameter in der
  1703. Parameterliste von SubMenu übergeben. Erlaubt sind alle
  1704. Scancodes. Bitte verwenden Sie die in der Unit WDecl vorde-
  1705. finierten Konstanten, z.B.
  1706.  
  1707. kbF1..kbF12
  1708. ShiftF1..ShiftF12
  1709. altF1..altF12
  1710.  
  1711. Beachten Sie dabei, das <F10> bereits zur Aktivierung des
  1712. Hauptmenüs vorgesehen ist. Weiterhin ist <F1> belegt, wenn
  1713. das Hilfesystem aktiv ist.
  1714. Natürlich können Sie auch für die Untermenüs eine Online-
  1715. Hilfe vorsehen. Der dritte Parameter stellt den Help-Index
  1716. dar. In unserem Beispiel ist er durchgängig auf 0 gesetzt
  1717. (keine Hilfe verfügbar).
  1718. Oftmals ist es günstig, einen Menüpunkt zu sperren, weil es
  1719. keinen Sinn macht, ihn zu einem bestimmten Zeitpunkt auszu-
  1720. führen. Solange z.B. in unserem fiktiven Malprogramm kein
  1721. Ausschnitt definiert ist, macht es wenig Sinn, die Bearbei-
  1722. tungsfunktionen "Verschieben", "Kopieren" usw. auszuführen.
  1723. Indem Sie den Parameter Akt auf true setzen, kann der Menü-
  1724. punkt bei Betätigung kein Kommando mehr absetzen. Auf dem
  1725. Bildschirm wird der Bezeichner in der Farbe, der durch den
  1726. Paletteneintrag 9 bzw. 10 vorgegeben ist (standardmäßig
  1727. Hellgrau), dargestellt.
  1728. Menüpunkte, die Alternativen darstellen (Ein-Aus), können
  1729. mit einem Häkchen versehen werden. Dafür ist der Parameter
  1730. Kennz zuständig.
  1731. Mit NewLine trennen Sie Gruppen von Menüeintragungen ab.
  1732.  
  1733. Syntax
  1734.  
  1735. MainMenu(Eintrag:str25;Help:byte);
  1736.  
  1737. Eintrag    Menübezeichner. Der Aufrufbuchstabe ist in Tilde-
  1738.            Zeichen eingeschlossen
  1739.  
  1740.  
  1741.  
  1742.  
  1743.  
  1744. Programmierhandbuch                                 WG-Vision - 21 -
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750.  
  1751.  
  1752. Help       HelpIndex. Dient zur Identifizierung des Hilfe-
  1753.            Textes einer On-Line-Hilfe.
  1754.  
  1755. Beispiel:
  1756.  
  1757. MainMenu('Ein~f~ügen',10);
  1758.  
  1759. SubMenu(Eintrag:str25;Kommando:word;Help,Key:byte;
  1760.         Akt,Kennz:boolean);
  1761.  
  1762. Eintrag    Menübezeichner. Der Aufrufbuchstabe ist in Tilde-
  1763.            Zeichen eingeschlossen
  1764.  
  1765. Kommando   Kommando, welches bei Aktivierung abgesetzt wird
  1766.  
  1767. Help       HelpIndex. Dient zur Identifizierung des Hilfe-
  1768.            Textes einer On-Line-Hilfe.
  1769.  
  1770. Key        Spezial-Key. Dient dem schnellen Aufruf eines
  1771.            Menüs über die Tastatur. Es sind nur ScanCodes
  1772.            erlaubt.
  1773.  
  1774. Akt        Menüpunkt deaktiviert (true) ?
  1775.  
  1776. Kennz      Häkchen gesetzt (true) ?
  1777.  
  1778. Beispiel:
  1779.  
  1780. SubMenu('~N~eues Bild',cmNew,0,0,false,false);
  1781. SubMenu('Bild ~L~aden      F3',cmLoad,0,kbF3,false,false);
  1782. SubMenu('Bild ~S~peichern  F2',cmSave,0,kbF2,false,false);
  1783.  
  1784. NewLine
  1785.  
  1786. Trennt Menübereiche ab.
  1787.  
  1788.  
  1789.  
  1790.  
  1791.  
  1792.  
  1793.  
  1794. Programmierhandbuch                                 WG-Vision - 22 -
  1795.  
  1796.  
  1797.  
  1798.  
  1799.  
  1800.  
  1801.  
  1802. 3.4.1. Farbeinstellungen
  1803.  
  1804. Das Menü als Bestandteil des Applikationsobjekts verwendet
  1805. standardmäßig eine Kopie der Palette2 aus der Unit WView.
  1806. Innerhalb der Methode InitMenuBar können Sie die Standard-
  1807. farben der einzelnen Menübestandteile leicht verändern, z.B.
  1808.  
  1809. ...
  1810. Palette[1]:=#14;        {Hauptmenüzeile Hintergrundfarbe}
  1811. Palette[4]:=#4;         {Hauptmenüzeile,Auswahlbalken}
  1812. Palette[5]:=#14;        {Untermenü,Hintergrundfarbe}
  1813. Palette[12]:=#4;        {Auswahlbalken}
  1814. ...
  1815.  
  1816. Die Positionen (Index) innerhalb des Palettenstrings haben
  1817. folgende Bedeutung:
  1818.  
  1819.  1  Hauptmenü, Hintergrundfarbe
  1820.  2  Hauptmenü, Schrift normal
  1821.  3  Hauptmenü, Schriftfarbe innerhalb des Auswahlbalkens
  1822.  4  Hauptmenü, Farbe des Auswahlbalkens
  1823.  5  Untermenü, Hintegrundfarbe
  1824.  6  Rahmenfarbe des Untermenüs
  1825.  7  Farbe des Menü-Trennstrichs
  1826.  8  Untermenü, Schrift normal
  1827.  9  Untermenü, Schriftfarbe inaktiv (Grayed=true)
  1828. 10  Untermenü, Schriftfarbe innerhalb des
  1829.     Auswahlbalkens,inaktiv
  1830. 11  Untermenü, Schriftfarbe innerhalb des
  1831.     Auswahlbalkens,aktiv
  1832. 12  Untermenü, Farbe des Auswahlbalkens
  1833.  
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.  
  1842.  
  1843.  
  1844. Programmierhandbuch                                 WG-Vision - 23 -
  1845.  
  1846.  
  1847.  
  1848.  
  1849.  
  1850.  
  1851.  
  1852. 3.4.2. Laden von Menüs aus Ressourcen
  1853.  
  1854. WG-Vision unterstützt in der vorliegenden Version noch keine
  1855. Streams. Trotzdem können Sie Menüressourcen aufbauen, die
  1856. ihr Anwendungsprogramm zur Laufzeit lädt und damit das Menü
  1857. initialisiert. Auf diese Weise lassen sich leicht Programme
  1858. in andere Sprachen portieren, da es ausreicht, die Ressour-
  1859. cendatei zu übersetzen.
  1860. Menüressourcen sind einfache ASCII-Dateien wie folgendes
  1861. Beispiel zeigt:
  1862.  
  1863. {Menü-Ressource für WG-Vision}
  1864.  
  1865. ~F~ile,1
  1866. ~N~ew Picture,101,0,0,f,f
  1867. ~L~oad         F3,102,0,61,f,f
  1868. ~S~ave         F2,103,0,60,f,f
  1869. NewLine
  1870. ~P~rint,104,0,0,f,f
  1871. ~C~lear,105,0,0,f,f
  1872. NewLine
  1873. ~E~xit      Alt-X,1,0,45,f,f
  1874. ~E~dit,2
  1875. ~U~ndo,201,0,0,f,f
  1876. NewLine
  1877. ~C~ut,202,0,0,t,f
  1878. C~o~py,203,0,0,t,f
  1879. ~M~ove,204,0,0,t,f
  1880. ~T~urn,205,0,0,t,f
  1881. ~T~ools,3
  1882. ~Z~oom,301,0,0,f,f
  1883. NewLine
  1884. ~G~rid,302,0,0,f,f
  1885. NewLine
  1886. ~P~encel change,303,0,0,f,f
  1887. ~B~rush change,304,0,0,f,f
  1888. ~T~ext,4
  1889. ~R~oman,401,0,0,f,t
  1890. ~S~cript,402,0,0,f,f
  1891.  
  1892.  
  1893.  
  1894. Programmierhandbuch                                 WG-Vision - 24 -
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902. ~T~imes,403,0,0,f,f
  1903. NewLine
  1904. ~N~ormal,404,0,0,f,t
  1905. ~B~old,405,0,0,f,f
  1906. ~I~talic,406,0,0,f,f
  1907. ~U~nderline,407,0,0,f,f
  1908. END
  1909.  
  1910. Die Reihenfolge der Parameter einer Zeile entspricht genau
  1911. dem WG-Vision-Befehl. Folgendes ist jedoch zu beachten:
  1912.  
  1913. - Kommandos werden als Nummern eingetragen. Die Nummern
  1914.   müssen mit der Konstantenliste des Programms
  1915.   übereinstimmen
  1916.  
  1917. - Codes für Hotkeys (z.B. <F2>) sind als Scancodes
  1918.   einzutragen. Kürzel sind unzulässig
  1919.  
  1920. - true wird mit t und false mit f abgekürzt
  1921.  
  1922. Das Einbinden der Menüressource erfolgt mit dem Befehl:
  1923.  
  1924. LoadMenu('<Name der Ressourcendatei>');
  1925.  
  1926.  
  1927.  
  1928.  
  1929.  
  1930.  
  1931.  
  1932.  
  1933.  
  1934.  
  1935.  
  1936.  
  1937.  
  1938.  
  1939.  
  1940.  
  1941.  
  1942.  
  1943.  
  1944. Programmierhandbuch                                 WG-Vision - 25 -
  1945.  
  1946.  
  1947.  
  1948.  
  1949.  
  1950.  
  1951.  
  1952. Beispiel:
  1953.  
  1954. procedure TApplication.InitMenuBar;
  1955. begin
  1956.  
  1957. {Farbanpassung an das Desktop}
  1958.  
  1959.   Palette[1]:=#14;    {Hauptmenüzeile Hintergrundfarbe}
  1960.   Palette[5]:=#14;    {Untermenü,Hintergrundfarbe}
  1961.   Palette[4]:=#4;     {Hauptmenüzeile,Auswahlbalken}
  1962.   Palette[12]:=#4;    {Auswahlbalken}
  1963.  
  1964. {Menüdefinition}
  1965.  
  1966.   LoadMenu('BSP8.MNU');   {das ist schon alles}
  1967.  
  1968. end;
  1969.  
  1970. Ist die Ressourcendatei offensichtlich fehlerhaft, dann
  1971. bricht das Programm während des Ladevorgangs mit einer Feh-
  1972. lermeldung ab:
  1973.  
  1974. WG-Vision-Fehler : Menüdatei nicht gefunden !
  1975.  
  1976. WG-Vision-Fehler : Zeile xxx in Menüdatei fehlerhaft !
  1977.                    Falscher Scancode für Shortkey
  1978.  
  1979. WG-Vision-Fehler : Zeile xxx in Menü-Datei fehlerhaft !
  1980.                    Menübezeichner zu lang (maximal 25
  1981.                    Zeichen
  1982.  
  1983. Die ersten beiden Zeilen der Ressourcendatei sind für Kom-
  1984. mentare vorgesehen.
  1985.  
  1986.  
  1987.  
  1988.  
  1989.  
  1990.  
  1991.  
  1992.  
  1993.  
  1994. Programmierhandbuch                                 WG-Vision - 26 -
  1995.  
  1996.  
  1997.  
  1998.  
  1999.  
  2000.  
  2001.  
  2002. 3.4.3. Verarbeitung von Menü-Kommandos, der Event-Handler
  2003.  
  2004. WG-Vision bildet das Fundament eines ereignisgesteuerten
  2005. Programms. Solch ein Ereignis wird als Event bezeichnet. Das
  2006. Programm muß sicherstellen, daß es auf ein Ereignis reagie-
  2007. ren kann. Ein Event kann über die Tastatur oder mittels der
  2008. Maus, aber auch durch das Programm selbst ausgelöst werden.
  2009. Wenn z.B. ein Menüpunkt angeklickt wird, dann wird ein Er-
  2010. eignis generiert, d.h. in der Struktur Event (dem Event-Re-
  2011. cord) wird das Feld Command mit dem Menü-Kommando (z.B.
  2012. cmRestore) besetzt. Innerhalb der Abfrageschleife des Pro-
  2013. gramms (MyApp.Run) kann dieses Kommando abgefangen und zur
  2014. Steuerung des Programms verwendet werden. Die virtuelle Me-
  2015. thode, die dafür verantwortlich ist, wird als Event-Handler
  2016. bezeichnet. Für die Auswertung von Menü-Ereignissen ist die
  2017. Methode HandleEvent von TApp zuständig:
  2018.  
  2019. type TApplication=object(TApp)
  2020.        ...
  2021.        procedure HandleEvent; virtual;
  2022.        ...
  2023.      end;
  2024. ...
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.  
  2044. Programmierhandbuch                                 WG-Vision - 27 -
  2045.  
  2046.  
  2047.  
  2048.  
  2049.  
  2050.  
  2051.  
  2052. procedure TApplication.HandleEvent;
  2053. begin
  2054.   TProgram.HandleEvent;                              {Nicht vergessen !}
  2055.   case Event.Command of
  2056.    cmNew  : begin                              {Programmteil Neues Bild}
  2057.             end;
  2058.    cmLoad : begin                              {Programmteil Bild laden}
  2059.             end;
  2060.    cmSave : begin                            {Programmteil Bild sichern}
  2061.             end;
  2062.       ...
  2063.  
  2064.    cmExit : Event.Command:=cmCloseApplication;
  2065.       ...
  2066.  
  2067.   end; {case}
  2068. end;
  2069.  
  2070. Die Schlüsselstruktur dieser Methode ist eine case-Anwei-
  2071. sung. Als Selektoren dienen die zu den Untermenüpunkten ge-
  2072. hörenden Kommandos. Für jeden Menüpunkt müssen Sie diesem
  2073. Handler die entsprechende Aktion zur Verfügung stellen. Das
  2074. kann z.B. das Aufblenden eines Dialogfensters oder die Ver-
  2075. anlassung eines Ausdrucks sein.
  2076. Bei der Implementation des Event-Handlers darf auf keinem
  2077. Fall vergessen werden, den Vorgänger (TProgram.HandleEvent)
  2078. aufzurufen. Er ermöglicht erst die Benutzung des Menüs und
  2079. verwaltet auch alle Ereignisse, die sich auf bereits aufge-
  2080. blendete und aktive Fenster beziehen. Ein Weglassen dieser
  2081. Methode hätte fatale Folgen, d.h. das Programm würde auf
  2082. Eingaben nicht mehr reagieren.
  2083. Der Event-Record ist das Behältnis, mit dem Informationen
  2084. von einem Programmteil in einen anderen Programmteil über-
  2085. tragen werden. Er ist in der Unit WEvent implementiert und
  2086. hat folgende Struktur:
  2087.  
  2088.  
  2089.  
  2090.  
  2091.  
  2092.  
  2093.  
  2094. Programmierhandbuch                                 WG-Vision - 28 -
  2095.  
  2096.  
  2097.  
  2098.  
  2099.  
  2100.  
  2101.  
  2102. type pEvent=^tEvent;
  2103.      tEvent=record
  2104.       What    : byte;
  2105.       Command : word;
  2106.       Message : word;
  2107.       Info    : word;
  2108.        case word of
  2109.         0 : (InfoPtr:Pointer);
  2110.         1 : (InfoLong:LongInt);
  2111.         2 : (InfoWord:word);
  2112.         3 : (InfoByte:byte);
  2113.         4 : (InfoChar:char);
  2114.         5 : (InfoString:string);
  2115.       end;
  2116.  
  2117. Das Feld What kann benutzt werden, um das Ereignis genauer
  2118. zu spezifizieren. Folgende Fälle sind möglich:
  2119.  
  2120. evNothing          = 0      kein Ereignis
  2121. evMouse            = 1      Mausereignis
  2122. evKeyboard         = 2      Keyboard-Ereignis
  2123. evMessage          = 3      Mitteilung oder Botschafts-
  2124.                             Ereignis
  2125. evCommand          = 4      Befehlsereignis (Kommando)
  2126. evBroadcast        = 5      Rundruf-Ereignis
  2127.  
  2128. Das What-Feld wird übrigens nur dann besetzt, wenn es wirk-
  2129. lich von Interesse ist, um was für ein Ereignis es sich han-
  2130. delt.
  2131. Command ist das wichtigste Feld des Event-Records. Es ent-
  2132. hält den jeweils letzten Befehl. Befehle oder Kommandos wer-
  2133. den in WG-Vision mit dem Präfix cm versehen, um sie leicht
  2134. von anderen Ereignissen (z.B. Mitteilungen) zu unterschei-
  2135. den.
  2136. Einige Kommandos sind bereits definiert. Sie haben eine
  2137. große Bedeutung für die interne Funktion der Klassenbiblio-
  2138. thek und sollten nicht anderweitig verwendet werden:
  2139.  
  2140.  
  2141.  
  2142.  
  2143.  
  2144. Programmierhandbuch                                 WG-Vision - 29 -
  2145.  
  2146.  
  2147.  
  2148.  
  2149.  
  2150.  
  2151.  
  2152. cmNothing          = 0     kein Kommando (Normalzustand)
  2153. cmCloseApplication = 1     Anwendungsprogramm schließen
  2154. cmCloseWindow      = 2     aktives Fenster schließen
  2155. cmWindowNewSize    = 3     aktives Fenster skalieren
  2156. cmSelectWindow     = 4     neues Fenster selektieren
  2157. cmScrollBarChanged = 5     Rollbalken verändert, intern
  2158.  
  2159. cmExit             = 6     Programm beenden (ohne Reaktion)
  2160. cmOK               = 7     Dialogfenster schließen
  2161. cmCancel           = 8     Dialog löschen (Abbrechen)
  2162.  
  2163. cmYes              =10;    Message-Box, intern
  2164. cmNo               =11;
  2165.  
  2166. cmUp               =12;    Rollbalken, intern
  2167. cmDown             =13;
  2168.  
  2169. Kommandos, die mit intern gekennzeichnet sind, sollten im
  2170. Programm nicht verwendet werden.
  2171. Mitteilungen werden oft im Zusammenhang mit Kommandos ver-
  2172. wendet und zwar immer dann, wenn neben dem Kommando eine
  2173. weitere Information übertragen werden muß. Mitteilungen wer-
  2174. den in der Regel vom Programmierer formuliert und sind am
  2175. Präfix msg leicht zu erkennen. Bitte verwenden Sie zur Co-
  2176. dierung von Mitteilungen nur Zahlen >= 10.
  2177. Um noch komplexere Informationen zu übertragen, müssen Sie
  2178. das Feld Info verwenden. Es kann gemäß der Definition eines
  2179. varianten Record mit beliebigen Datentypen besetzt werden.
  2180. Im Zusammenhang mit dem Event-Record sind noch folgende Pro-
  2181. zeduren von Interesse:
  2182.  
  2183. procedure GetEvent;      holt Tastatur- und Mausereignisse
  2184.  
  2185. procedure ClearEvent;    setzt What auf evNothing und löscht
  2186.                          die Felder Keyb.ScanCode und
  2187.                          Keyb.KeyCode. Außerdem wird
  2188.                          Mouse.DoubleKlick auf false gesetzt
  2189.  
  2190.  
  2191.  
  2192.  
  2193.  
  2194. Programmierhandbuch                                 WG-Vision - 30 -
  2195.  
  2196.  
  2197.  
  2198.  
  2199.  
  2200.  
  2201.  
  2202. procedure ClearMessage;  Event.Message wird auf msgNothing gesetzt
  2203.  
  2204. Um das Wechselspiel zwischen Menü und Eventhandler etwas ge-
  2205. nauer zu betrachten, soll im folgenden Beispiel gezeigt wer-
  2206. den, wie man zur Laufzeit ein Menü auswechseln kann.
  2207. Die beiden Menüs liegen jeweils als Ressourcendateien vor:
  2208.  
  2209. {Menü-Ressource für Programm MTEST, Menü 1}
  2210.  
  2211. ~A~uswahl,0
  2212. ~N~eues Menü laden,101,0,0,f,f
  2213. NewLine
  2214. E~x~it    <alt><x>,1,0,45,f,f
  2215.  
  2216. {Menü-Ressource für Programm MTEST, Menü 2}
  2217.  
  2218. ~A~uswahl,0
  2219. Altes ~M~enü laden,111,0,0,f,f
  2220. NewLine
  2221. E~x~it    <alt><x>,1,0,45,f,f
  2222.  
  2223. Man beachte, daß die Kommandos, die abgesetzt werden, unter-
  2224. schiedlich sind. Das ist zwar nicht immer zwingend notwen-
  2225. dig, hilft aber, die Übersicht zu bewahren. In diesem
  2226. Beispiel sind das die Kommandos 101 und 111. Sie erscheinen
  2227. nochmals im Konstanten-Deklarationsteil des Hauptprogramms:
  2228.  
  2229. program MenuTest;
  2230.  
  2231. uses WApp,
  2232.      WEvent;
  2233.  
  2234. const cmLoadNewMenu = 101;                              {Menü-Kommandos}
  2235.       cmLoadOldMenu = 111;
  2236.  
  2237. type TApplication=object(TApp)               {Neues Applikations-Objekt}
  2238.       procedure InitMenuBar; virtual;
  2239.       procedure HandleEvent; virtual;
  2240.      end;
  2241.  
  2242.  
  2243.  
  2244. Programmierhandbuch                                 WG-Vision - 31 -
  2245.  
  2246.  
  2247.  
  2248.  
  2249.  
  2250.  
  2251.  
  2252. var MyApp:TApplication;
  2253.  
  2254. {Implementation TApplication}
  2255.  
  2256. procedure TApplication.InitMenuBar;                  {erstes Menü laden}
  2257. begin
  2258.   LoadMenu('MTEST1.MNU');
  2259. end;
  2260.  
  2261. procedure TApplication.HandleEvent;
  2262. begin
  2263.   TProgram.HandleEvent;
  2264.   case Event.Command of
  2265.    cmLoadNewMenu : begin
  2266.                      ClearMenu;                     {altes Menü löschen}
  2267.                      LoadMenu('MTEST2.MNU');              {Menü 2 laden}
  2268.                      DrawMainMenu;           {Menü 2 auf den Bildschirm}
  2269.                    end;                                       {zeichnen}
  2270.    cmLoadOldMenu : begin
  2271.                      ClearMenu;
  2272.                      LoadMenu('MTEST1.MNU');
  2273.                      DrawMainMenu;
  2274.                    end;
  2275.   end; {case}
  2276. end;
  2277.  
  2278. {Hauptprogramm}
  2279.  
  2280. begin
  2281.   MyApp.Init('Menü-Test');
  2282.   MyApp.Run;
  2283.   MyApp.Done;
  2284. end.
  2285.  
  2286. Der Befehl ClearMenu löscht die Eintragungen des gerade ak-
  2287. tiven Menüs vom Heap und macht damit Platz für das neue Me-
  2288. nü, welches mit LoadMenu geladen wird. DrawMainMenu schreibt
  2289. danach das neue Hauptmenü auf den Bildschirm.
  2290. Die Abarbeitungsschleife, die sich hinter dem Befehl
  2291.  
  2292.  
  2293.  
  2294. Programmierhandbuch                                 WG-Vision - 32 -
  2295.  
  2296.  
  2297.  
  2298.  
  2299.  
  2300.  
  2301.  
  2302. MyApp.Run verbirgt, hat jetzt folgende Struktur:
  2303.  
  2304.  
  2305.  ┌─────> repeat
  2306.  │         │
  2307.  │      GetEvent
  2308.  │         │
  2309.  │         │          HandleEvent (allgemein)
  2310.  │    HandleEvent ──> HandleEvent (Menü)
  2311.  │                    HandleEvent (Applikation) - Menü laden
  2312.  │                              │
  2313.  │    ClearEvent <──────────────┘
  2314.  │         │
  2315.  │         │
  2316.  └ until Event.Command=cmCloseApplication
  2317.  
  2318. Wie Sie sehen, wird jeweils der Event-Handler des gerade ak-
  2319. tiven Elements (Menü, Dialogfenster, Dialogelement etc.) in
  2320. die Ereignisabarbeitungskette eingefügt. Das bedeutet, daß
  2321. die Funktionalität eines ereignisgesteuerten Programms in
  2322. den entsprechenden Event-Handler (z.B. eines Dialogfensters)
  2323. gelegt werden muß.
  2324.  
  2325. 3.4.4. Verschieben des Menüs in der Menüzeile
  2326.  
  2327. Die linke Position des ersten Hauptmenüeintrags läßt sich
  2328. über die Variable MPos frei festlegen. Um beispielsweise das
  2329. gesamte Hauptmenü um ca 100 Pixel nach rechts zu verschie-
  2330. ben, muß die Prozedur InitMenuBar um folgenden Eintrag er-
  2331. gänzt werden:
  2332.  
  2333. procedure TApplication.InitMenuBar;
  2334. begin
  2335.   MPos:=100;                    {erst das}
  2336.   LoadMenu('MTEST1.MNU');       {dann das}
  2337. end;
  2338.  
  2339.  
  2340.  
  2341.  
  2342.  
  2343.  
  2344. Programmierhandbuch                                 WG-Vision - 33 -
  2345.  
  2346.  
  2347.  
  2348.  
  2349.  
  2350.  
  2351.  
  2352. 3.5. Grafikmodus einstellen
  2353.  
  2354. Eine besondere Stärke von WG-Vision ist die Unterstützung
  2355. einer großen Anzahl von Super-VGA-Karten. Das Stichwort dazu
  2356. heißt VESA-Kompatibilität. Für die meisten heute im Handel
  2357. befindlichen Super-VGA's gibt es sogenannte VESA-Erweiterun-
  2358. gen, wenn die Karten nicht schon bereits BIOS-seitig VESA-
  2359. kompatibel sind. Für die meisten Grafik-Chipsätze findet man
  2360. im PD-Bereich VESA-Treiber, die als TSR-Programme geladen,
  2361. eine Super-VGA VESA-kompatibel machen. Für den Programment-
  2362. wickler ergibt sich damit die angenehme Situation, daß ein
  2363. einziger BGI-Treiber ausreicht, um eine große Zahl verschie-
  2364. dener Grafikkarten zu unterstützen. Und das noch bei allen
  2365. vom jeweiligen VESA-Treiber unterstützten Auflösungen und
  2366. mit 256 Farben !
  2367. Um auch Grafikkarten mit dem IBM8514-Chip zu unterstützen,
  2368. wurde auch der 8514-BGI-Treiber implementiert. Nur kann es
  2369. hier zu Schwierigkeiten mit der Maus kommen.
  2370.  
  2371. WG-Vision unterstützt folgende Grafikkarten
  2372.  
  2373. EGA        16 Farben
  2374. VGA        16 Farben    (Voreinstellung)
  2375. VESA      256 Farben    (VESA-Treiber muß geladen sein)
  2376. IBM8514   256 Farben
  2377.  
  2378. Die unterstützten Auflösungen hängen im konkreten Fall vom
  2379. installierten Grafikadapter bzw. vom installierten VESA-
  2380. Treiber ab. Folgende Auflösungen sind möglich:
  2381.  
  2382. M640x350
  2383. M640x480  (Voreinstellung)
  2384. M800x600  (nur VESA)
  2385. M1024x768 (VESA und IBM8514)
  2386.  
  2387. Um den Grafikmodus einzustellen, müssen Sie die virtuelle
  2388. Methode InitVideoDevice überschreiben:
  2389.  
  2390.  
  2391.  
  2392.  
  2393.  
  2394. Programmierhandbuch                                 WG-Vision - 34 -
  2395.  
  2396.  
  2397.  
  2398.  
  2399.  
  2400.  
  2401.  
  2402. procedure TApplication.InitVideoDevice;
  2403. begin
  2404.   Video.Init(VESA,M800x600);
  2405. end;
  2406.  
  2407. Das Programm schaltet beim Starten in den 800x600x256 Modus.
  2408. Zur Initialisierung verwenden Sie bitte die vordefinierten
  2409. Konstanten. Wenn ein Umschalten in den Grafikmodus nicht
  2410. möglich ist, erfolgt eine Fehlermeldung und das Programm
  2411. bricht ab. Aufgrund eines Bugs in der GRAPH-Unit erscheint
  2412. beim Fehlen eines resident geladenen VESA-Treibers bei man-
  2413. chen Grafikkarten die mißverständliche Ausschrift "No
  2414. Error".
  2415. Der Grafikmodus läßt sich prinzipiell auch während der Lauf-
  2416. zeit eines Programms ändern. Bedingung ist, daß nur die Auf-
  2417. lösung und nicht der Treiber gewechselt wird. Ein Umschalten
  2418. von VGA auf VESA ist ausgeschlossen. Ist aber beispielsweise
  2419. der VESA-Treiber installiert, dann kann zwischen allen von
  2420. diesem Treiber unterstützten Auflösungen hin und hergeschal-
  2421. ten werden.
  2422. Das folgende Beispiel zeigt die Vorgehensweise. Das Menü
  2423. wird um den Punkt "Grafik-Mode wechseln" ergänzt. Beim An-
  2424. klicken soll das Kommando "cmChangeGMode" abgesetzt werden.
  2425. Im Eventhandler erfolgt dann das Umschalten in die neue Auf-
  2426. lösung:
  2427.  
  2428.  
  2429.  
  2430.  
  2431.  
  2432.  
  2433.  
  2434.  
  2435.  
  2436.  
  2437.  
  2438.  
  2439.  
  2440.  
  2441.  
  2442.  
  2443.  
  2444. Programmierhandbuch                                 WG-Vision - 35 -
  2445.  
  2446.  
  2447.  
  2448.  
  2449.  
  2450.  
  2451.  
  2452. procedure TApplication.HandleEvent;
  2453. var i:integer;
  2454. begin
  2455.   TProgram.HandleEvent;
  2456.   case Event.Command of
  2457.    cmChangeGMode : begin
  2458.                      Mouse.HideMouse;
  2459.                      if Video.GetGrafikMode=M640x480 then
  2460.                       Video.ChangeGraficMode(M800x600)
  2461.                        else Video.ChangeGraficMode(M640x480);
  2462.                      Draw;
  2463.                      Mouse.ShowMouse;
  2464.                    end;
  2465.     ...
  2466.  
  2467.   end; {case}
  2468. end;
  2469.  
  2470. Das Objekt, welches für die eingestellten Grafikparameter
  2471. zuständig ist, hat den Namen TVideoDevice und ist in der
  2472. Unit WDriver implementiert. Eine Instanz davon ist Video.
  2473. Video wird beim Programmstart innerhalb von MyApp.Init
  2474. iniialisiert. Zu diesem Zweck wird die virtuelle Methode
  2475. InitVideoDevice abgearbeitet. Standardmäßig wird in den VGA-
  2476. Modus mit einer Auflösung von 640x480x16 geschaltet. Wie be-
  2477. reits behandelt, können Sie diese Methode überschreiben und
  2478. damit andere Grafikadapter oder Modi aktivieren. Um während
  2479. der Laufzeit die Auflösung zu ändern, müssen Sie jetzt nur
  2480. noch die Methode ChangeGraficMode von TVideoDevice aufrufen.
  2481. Übergabeparameter ist die gewünschte Auflösung.
  2482. Sie sollten vor Aufruf dieser Methode nicht vergessen, die
  2483. Maus auszuschalten. Ansonsten kann der Mausinterrupt den Um-
  2484. schaltvorgang empfindlich stören, was sich durch Fehler beim
  2485. Aufblenden des Desktops bemerkbar macht.
  2486. Der letzte Schritt besteht in der Rekonstruktion des vor dem
  2487. Umschaltvorgangs vorhandenen Bildschirms. Dazu braucht nur
  2488. die Draw-Methode des Applikationsobjekts abgearbeitet wer-
  2489. den. Sie stellt das Desktop und alle aktiven Fenster neu auf
  2490. dem Bildschirm dar.
  2491.  
  2492.  
  2493.  
  2494. Programmierhandbuch                                 WG-Vision - 36 -
  2495.  
  2496.  
  2497.  
  2498.  
  2499.  
  2500.  
  2501.  
  2502. Während es beim Übergang von einer geringeren Auflösung zu
  2503. einer höheren Auflösung keine Probleme gibt, ist der umge-
  2504. kehrte Weg etwas mit Vorsicht zu geniesen. WG-Vision kann im
  2505. Gegensatz zu Windows oder Turbo-Vision nur Fenster verwal-
  2506. ten, die vollständig auf dem Bildschirm dargestellt sind
  2507. (deshalb auch die Begrenzung von Resize- und des Move-
  2508. Bereichs auf das Workarea). Beim Umschalten auf geringere
  2509. Auflösung kann es vorkommen, daß ein Fenster nicht mehr auf
  2510. den Bildschirm paßt (das Workarea hat sich verkleinert). Das
  2511. führt zwangsläufig zu einer fehlerhaften Darstellung.
  2512. Außerdem funktionieren die Routinen zur Restauration des
  2513. Untergrunds nicht mehr. Deshalb folgende Empfehlung:
  2514. Realisieren Sie Ihr Programm so, daß ein Umschalten in einen
  2515. anderen Grafikmodus nur möglich ist, wenn sich keine Fenster
  2516. auf dem Bildschirm befinden, das Desktop also leer ist.
  2517.  
  2518.  
  2519.  
  2520.  
  2521.  
  2522.  
  2523.  
  2524.  
  2525.  
  2526.  
  2527.  
  2528.  
  2529.  
  2530.  
  2531.  
  2532.  
  2533.  
  2534.  
  2535.  
  2536.  
  2537.  
  2538.  
  2539.  
  2540.  
  2541.  
  2542.  
  2543.  
  2544. Programmierhandbuch                                 WG-Vision - 37 -
  2545.  
  2546.  
  2547.  
  2548.  
  2549.  
  2550.  
  2551.  
  2552. 3.6. Wechseln der Desktop-Farben zur Laufzeit
  2553.  
  2554. Dadurch, daß man durch Abarbeitung der Draw-Methode des Ap-
  2555. plikationsobjekts alle Objekte auf dem Bildschirm restaurie-
  2556. ren kann, ist eine Änderung der Desktop-Farben (z.B.
  2557. gesteuert durch einen Farbauswahl-Dialog entsprechend Win-
  2558. dows) zur Laufzeit relativ leicht möglich.
  2559. Was muß man zu diesem Thema wissen ? Das Desktop-Objekt ver-
  2560. waltet in der Struktur List (doppelt verkettete Liste, Nach-
  2561. komme von TGroup) seine einzelnen Bestandteile in der
  2562. Reihenfolge ihrer Implementation:
  2563.  
  2564. 1.Position   Rahmen      (Index in der Liste=1)
  2565. 2.Position   Hintergrund (Index in der Liste=2)
  2566.  
  2567. Jedes dieser Objekte besitzt eine eigene Farbpalette. Das
  2568. Rahmenobjekt verwendet standardmäßig die Eintragungen 1 bis
  2569. 6 und das Hintergrundobjekt die Paletteneintragungen 7 und 8
  2570. der Palette1 (Unit WViews). Es hat jedoch keinen Zweck, etwa
  2571. die Standardpalette 1 zu verändern oder zu überschreiben.
  2572. Vielmehr muß die objekteigene Palette verändert werden. Dazu
  2573. sind folgende Schritte notwendig:
  2574.  
  2575. Einen Pointer auf das erste Element von List setzen:
  2576.  
  2577.    with DeskTop^ do {"Eigentümer" von List}
  2578.     begin
  2579.       LfdPtr:=List^.GetItems(1);
  2580.       ...
  2581.  
  2582. LfdPtr ist ein Pointer vom Typ PGroup. Mit GetItems wird die
  2583. Adresse des ersten Eintrags der doppelt verketteten Liste
  2584. List geholt und LfdPtr zugewiesen.
  2585. Um auf das Feld Palette zuzugreifen, ist noch ein Typecast
  2586. notwendig (woher soll denn sonst der Rechner wissen, um was
  2587. für einen Objekttyp es sich konkret bei LfdPtr handelt ?):
  2588.  
  2589.    with PFrame(LfdPtr)^ do
  2590.     Palette:=#2#13#2#10#3#0;
  2591.  
  2592.  
  2593.  
  2594. Programmierhandbuch                                 WG-Vision - 38 -
  2595.  
  2596.  
  2597.  
  2598.  
  2599.  
  2600.  
  2601.  
  2602. Jetzt können Sie die Rahmenpalette nach Ihren eigenen Vor-
  2603. stellungen verändern. Wie diese Palette aufgebaut ist, steht
  2604. im Kapitel "Gestaltung des Rahmens".
  2605. Ganz analog wird auch die Farbe des Hintergrundobjektes ge-
  2606. ändert:
  2607.  
  2608. LfdPtr:=List^.GetItems(2);
  2609. with PDsktpBgrd(LfdPtr)^ do
  2610.  begin
  2611.    Palette[7]:=#14;        {Menübereich auf Gelb}
  2612.    Palette[8]:=#9;     {Hintergrund auf Hellblau}
  2613.  end;
  2614.  
  2615. Zum Schluß muß nur noch die Farbe des Menüs angepaßt werden.
  2616. Da das Menü die gleiche Palette benutzt wie das Applikati-
  2617. onsobjekt, braucht lediglich die Variable Palette auf neue
  2618. Werte gesetzt werden:
  2619.  
  2620. Palette:=#14#0#15#4#9#15#15#11#7#15#7#4;
  2621.  
  2622. oder, wenn Sie z.B. nur die Hintergrundfarbe der Hauptme-
  2623. nüzeile ändern möchten:
  2624.  
  2625. Palette[1]:=#14;
  2626.  
  2627. Eine komplette Farbumschaltung könnte innerhalb des Event-
  2628. Handlers des Applikationsobjekts etwa so aussehen:
  2629.  
  2630.  ...
  2631.  
  2632. case Event.Command of
  2633.   cmChangeDTColor : begin
  2634.                       Mouse.HideMouse;
  2635.                       with DeskTop^ do
  2636.                        begin
  2637.                          LfdPtr:=List^.GetItems(1);             {Rahmen}
  2638.                          with PFrame(LfdPtr)^ do
  2639.                           Palette:=#2#13#2#10#3#0;
  2640.                          LfdPtr:=List^.GetItems(2);        {Hintergrund}
  2641.  
  2642.  
  2643.  
  2644. Programmierhandbuch                                 WG-Vision - 39 -
  2645.  
  2646.  
  2647.  
  2648.  
  2649.  
  2650.  
  2651.  
  2652.                          with PDsktpBgrd(LfdPtr)^ do
  2653.                           begin
  2654.                             Palette[7]:=#14;
  2655.                             Palette[8]:=#9;
  2656.                           end;
  2657.                        end;
  2658.                       Palette:=#14#0#15#4#9#15#15#11#7#15#7#4;    {Menü}
  2659.                       Draw;
  2660.                       Mouse.ShowMouse;
  2661.                     end;
  2662.  ...
  2663.  
  2664. Mit diesem Wissen ist es dann nicht mehr sonderlich schwie-
  2665. rig, einen Dialog zur freien Gestaltung der Desktop-Farben
  2666. zu entwickeln.
  2667.  
  2668.  
  2669.  
  2670.  
  2671.  
  2672.  
  2673.  
  2674.  
  2675.  
  2676.  
  2677.  
  2678.  
  2679.  
  2680.  
  2681.  
  2682.  
  2683.  
  2684.  
  2685.  
  2686.  
  2687.  
  2688.  
  2689.  
  2690.  
  2691.  
  2692.  
  2693.  
  2694. Programmierhandbuch                                 WG-Vision - 40 -
  2695.  
  2696.  
  2697.  
  2698.  
  2699.  
  2700.  
  2701.  
  2702. 3.7. Umschalten in den Alpha-Mode
  2703.  
  2704. WG-Vision merkt sich beim Initialisieren der Grafik den ur-
  2705. sprünglich aktiven Alphamodus. Mit dem Befehl Video.SetText-
  2706. Mode kann dann problemlos von der graphischen Oberfläche in
  2707. den Textmodus zurückgeschalten werden. Folgendes Programm-
  2708. fragment, welches in den Eventhandler der Applikation einge-
  2709. baut werden muß, zeigt, wie man einen solchen Vorgang
  2710. programmiert:
  2711.  
  2712.  ...
  2713.  
  2714. case Event.Command of
  2715.  cmRestoreCRTMode : begin
  2716.                       Mouse.HideMouse;
  2717.                       Video.SetTextMode;
  2718.                       ...
  2719.  
  2720.                       {Hier kommt der Programmteil im Textmodus}
  2721.  
  2722.                       ...
  2723.  
  2724.                       Video.ChangeGraphicMode(M640x480);
  2725.                       Draw;                     {Desktop neu darstellen}
  2726.                       Mouse.ShowMouse;
  2727.                     end;
  2728.  ...
  2729.  
  2730. Noch besser ist es, wenn Sie bevor Sie in den Alphamodus
  2731. wechseln, den gesamten Grafikbildschirm in den EMS oder in
  2732. eine Swapdatei retten. Anstelle der Abarbeitung der Draw-
  2733. Methode brauchen Sie dann nur noch den Grafikbildschirm
  2734. rekonstruieren. Das geht bedeutend schneller, als wenn Sie
  2735. alle Objekte inklusive Desktop neu zeichnen lassen.
  2736.  
  2737.  
  2738.  
  2739.  
  2740.  
  2741.  
  2742.  
  2743.  
  2744. Programmierhandbuch                                 WG-Vision - 41 -
  2745.  
  2746.  
  2747.  
  2748.  
  2749.  
  2750.  
  2751.  
  2752. 4. Heap-und EMS-Überwachung
  2753.  
  2754. Bei der objektorientierten Programmierung erzeugt man In-
  2755. stanzen, die man als ordentlicher Programmierer möglichst
  2756. auf dem Heap ablegt. Da kann es sehr schnell vorkommen, daß
  2757. man Objekte zwar initialisiert, man aber vergißt, sie wieder
  2758. vom Heap zu entfernen. Solchen Fehlern ist sehr schwer auf
  2759. die Schliche zu kommen. Ergebnis ist ein immer kleiner wer-
  2760. dender und mehr und mehr fragmentierter Heap. Damit es nicht
  2761. zu solchen Fehlern kommt, stellt ihnen WG-Vision einen Heap-
  2762. wächter zur Verfügung, der ihnen den noch freien Heap und
  2763. den größten freien Speicherblock anzeigt. Diesen Heapwächter
  2764. sollten Sie während der Entwicklungsphase Ihres Programms
  2765. immer in die Methode HandleEvent einbauen:
  2766.  
  2767. procedure TApplication.HandleEvent;
  2768. begin
  2769.   Heap^.ShowHeapStatus(523,8,White);         {Position und Schriftfarbe}
  2770.   TProgram.HandleEvent;
  2771.   ...
  2772.  
  2773. end;
  2774.  
  2775. In der Titelzeile des Desktops an der Position (523,8) kön-
  2776. nen Sie jetzt den jeweiligen Zustand des Heaps ablesen. Wenn
  2777. Sie z.B. ein Untermenü aufklappen, sehen Sie, wie das Pro-
  2778. gramm Speicher für den Untergrund allokiert. Beim Deaktivie-
  2779. ren geht der Wert für den freien Speicher wieder auf seinen
  2780. alten Wert zurück. Wenn das nicht der Fall sein sollte, ha-
  2781. ben Sie vergessen, irgendein Objekt vom Heap wieder zu ent-
  2782. fernen. Das kann u.U. zu einer lustigen und kurzweiligen
  2783. Sucherei nach den Ursachen führen.
  2784. Wenn Sie mit EMS-Speicher arbeiten, ist natürlich dessen
  2785. Status auch sehr interessant. Mit folgender Zeile
  2786.  
  2787. EMS^.ShowEMSStatus(x,y,Farbe);
  2788.  
  2789. können Sie sich zu jeden Zeitpunkt über den noch freien EMS-
  2790. Speicher und der Anzahl noch freier Pages informieren.
  2791.  
  2792.  
  2793.  
  2794. Programmierhandbuch                                 WG-Vision - 42 -
  2795.  
  2796.  
  2797.  
  2798.  
  2799.  
  2800.  
  2801.  
  2802. Hier noch ein Achtung für alle, die mit Borland-Pascal ar-
  2803. beiten. Trotz nach Ihrer Meinung reichlich vorhandenen EMS-
  2804. Speicher zeigt ShowEMSStatus immer Null freie Pages an. Der
  2805. Grund dafür ist, daß Borland Pascal einen DPMI-Server nutzt,
  2806. damit die Entwicklungsumgebung im Protected Mode arbeiten
  2807. kann. Dieser Server allokiert standardmäßig den gesamten Er-
  2808. weiterungsspeicher und deaktiviert somit auch den EMS-Trei-
  2809. ber.
  2810.  
  2811.  
  2812.  
  2813.  
  2814.  
  2815.  
  2816.  
  2817.  
  2818.  
  2819.  
  2820.  
  2821.  
  2822.  
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831.  
  2832.  
  2833.  
  2834.  
  2835.  
  2836.  
  2837.  
  2838.  
  2839.  
  2840.  
  2841.  
  2842.  
  2843.  
  2844. Programmierhandbuch                                 WG-Vision - 43 -
  2845.  
  2846.  
  2847.  
  2848.  
  2849.  
  2850.  
  2851.  
  2852. 5. Schöne neue Fensterwelt
  2853.  
  2854. Beginnen wir etwas akademisch. Fenster sind für den Compu-
  2855. terfreak nicht nur Öffnungen in der Wand, wo nachts der Mond
  2856. hineinscheint. Fenster sind vielmehr Bildschirmbereiche, die
  2857. durch einen Rahmen begrenzt sind und in deren Innern Infor-
  2858. mationen dargestellt werden. Ein richtiges Fenster läßt sich
  2859. obendrein noch mit der Maus beliebig auf dem Bildschirm ver-
  2860. schieben und sich vergrößern bzw. verkleinern.
  2861. Folgendes Minimalprogramm zaubert genau solch ein Fenster
  2862. auf Ihren Computerbildschirm:
  2863.  
  2864. program Fenstertest;
  2865.  
  2866. uses WDecl,
  2867.      WEvent,
  2868.      WApp,
  2869.      WDlg;
  2870.  
  2871. const cmNewWindow=101;
  2872.  
  2873. type TApplication=object(TApp)
  2874.       procedure InitMenuBar; virtual;
  2875.       procedure HandleEvent; virtual;
  2876.       procedure NewWindow;
  2877.      end;
  2878.  
  2879. {Implementation TApplication}
  2880.  
  2881. procedure TApplication.InitMenuBar;
  2882. begin
  2883.   MainMenu('~F~enster',0);
  2884.    SubMenu('~T~estfenster',cmNewWindow,0,0,false,false);
  2885.    SubMenu('E~x~it  Alt-X',cmCloseApplication,0,altX,false,false);
  2886.  end;
  2887.  
  2888.  
  2889.  
  2890.  
  2891.  
  2892.  
  2893.  
  2894. Programmierhandbuch                                 WG-Vision - 44 -
  2895.  
  2896.  
  2897.  
  2898.  
  2899.  
  2900.  
  2901.  
  2902. procedure TApplication.HandleEvent;
  2903. begin
  2904.   TProgram.HandleEvent;
  2905.    case Event.Command of
  2906.    cmNewWindow:NewWindow;
  2907.   end; {case}
  2908. end;
  2909.  
  2910. {und hier unser Fensterlein ...}
  2911.  
  2912. procedure TApplication.NewWindow;
  2913. var R:TRect;
  2914.     Window:PWindow;
  2915. begin
  2916.   R.Assign(60,80,400,280);
  2917.   Window:=new(PWindow,Init(R,'Testfenster',winDouble+winPanel+winMenu
  2918.               +winKey));
  2919.   InsertDesktop(Window);
  2920. end;
  2921.  
  2922. var MyApp:TApplication;
  2923.  
  2924. {Hauptprogramm}
  2925.  
  2926. begin
  2927.   MyApp.Init('Fenster-Test');
  2928.   MyApp.Run;
  2929.   MyApp.Done;
  2930. end.
  2931.  
  2932. Probieren Sie bitte dieses Programm einmal aus. Das Fenster,
  2933. welches nach Anklicken des Menüpunktes "Testfenster" auf dem
  2934. Bildschirm erscheint, hat fast alle Eigenschaften, die ein
  2935. Fenster unter Windows auch hat:
  2936. Es kann beliebig innerhalb des Workareas verschoben wer-
  2937. den.Ein Herausschieben aus dem Bildschirm wie bei Windows
  2938. oder Turbo-Vision ist jedoch nicht möglich. Dazu Klicken Sie
  2939. das Panel an und bewegen die Maus bei gedrückter linker
  2940. Maustaste. Sie können das Fenster aber auch mit Hilfe der
  2941.  
  2942.  
  2943.  
  2944. Programmierhandbuch                                 WG-Vision - 45 -
  2945.  
  2946.  
  2947.  
  2948.  
  2949.  
  2950.  
  2951.  
  2952. Tastatur bewegen. Einmal <ESC> drücken öffnet das Systemme-
  2953. nü. Daraus wählen Sie den Menüpunkt Verschieben (bzw. Move).
  2954. Anschließend können Sie mit Hilfe der Kursortasten das Fen-
  2955. ster neu auf dem Bildschirm positionieren. <ENTER> beendet
  2956. die Prozedur.
  2957. Die Fenstergröße kann verändert werden (Skalierung). Wenn
  2958. die Maus den Rahmen des Fensters berührt, ändert sich in Ab-
  2959. hängigkeit von der momentanen Position die Form des Mauszei-
  2960. gers. Wenn Sie jetzt mit gedrückter linker Maustaste die
  2961. Maus bewegen, verändert sich (dargestellt durch ein farbiges
  2962. Rechteck) die Größe des Fensters. Einschränkend muß noch er-
  2963. wähnt werden, daß eine freie Skalierung über die Tastatur
  2964. nicht möglich ist. Alle skalierbaren Fenster besitzen in der
  2965. rechten oberen Ecke der Titelzeile zwei Schalter. Wenn Sie
  2966. auf den rechten Schalter drücken, verändert sich das Fenster
  2967. auf die Größe des aktiven Workareas. Der linke Schalter ver-
  2968. kleinert es wieder auf die Größe, wie es im Programm defi-
  2969. niert wurde (Unterschied zu einem Windows-Fenster). Die
  2970. gleichen Aktionen können Sie auch über die Tastenkombinatio-
  2971. nen <Ctrl><PgUp> und <Ctrl><PgDn> erreichen.
  2972. Wenn ein Standardfenster aufgeblendet wird, bleibt weiterhin
  2973. das Hauptmenü aktiv. Solch ein Fenster wird als nicht-modal
  2974. bezeichnet. Sie können jetzt das Fenster verschieben und an-
  2975. schließend ein weiteres Fenster aufblenden usw. Diesen Vor-
  2976. gang können Sie solange wiederholen, bis Ihr Programm wegen
  2977. Speichermangels abbricht (hier bewährt sich zum Test wieder
  2978. der Heapwächter). Wie Sie sehen, können Sie quasi beliebig
  2979. viele Fenster erzeugen. Das jeweils vorletzte wird deakti-
  2980. viert, was man an der Farbänderung des Rahmens beobachten
  2981. kann. Man sagt auch, daß es seinen Fokus verliert. Nur das
  2982. gerade aktive Fenster ist fokussiert und reagiert auf Ereig-
  2983. nisse.
  2984. Wenn Sie ein deaktiviertes Fenster anklicken, wird es wieder
  2985. aktiviert. Wenn es durch Teile von anderen Fenstern verdeckt
  2986. war, werden die Fenster so umsortiert, daß es wieder "oben"
  2987. zu liegen kommt.
  2988. Um ein Fenster zu schließen, brauchen Sie nur das Ende-Icon
  2989. zweimal mit der Maus kurz anzuklicken. Auch die Tastenkombi-
  2990. nation <ESC><ENTER> oder <ESC><S> bzw. <ESC><C> (englische
  2991.  
  2992.  
  2993.  
  2994. Programmierhandbuch                                 WG-Vision - 46 -
  2995.  
  2996.  
  2997.  
  2998.  
  2999.  
  3000.  
  3001.  
  3002. Variante) entfernt das Fenster vom Bildschirm.
  3003.  
  3004. 5.1. Programmierung
  3005.  
  3006. Alle Fenster leiten sich vom Objekt TWindow ab, welches in
  3007. der Unit WDlg implementiert ist. Wenn Sie ein Fenster mit
  3008. Leben erfüllen wollen, müssen Sie von diesem Objekt einen
  3009. Nachkommen erzeugen und ihn mit allen gewünschten Eigen-
  3010. schaften ausstatten. Im obigen Beispiel wurde direkt auf
  3011. TWindow zurückgegriffen. Es zeigt also ein Fenster in seinem
  3012. "Urzustand".
  3013. Das Einfügen des Fensters in die Window-Liste des Desktops
  3014. erfolgt innerhalb einer neuen Methode des Applikationsob-
  3015. jekts (procedure NewWindow) mit dem Befehl InsertDesktop.
  3016. Zuvor werden über den Konstruktor von TWindow die Eigen-
  3017. schaften des Fensters festgelegt. Das sind
  3018.  
  3019. - Position und Größe
  3020. - Eigenschaften (ergibt sich aus dem Rahmentyp)
  3021.  
  3022. ...
  3023. R.Assign(60,80,440,280);               {Größe und Position des Fensters}
  3024. Window:=new(PWindow,
  3025.              │ Init(R,'Testfenster',winDouble+winPanel+winMenu+winKey));
  3026. ...          │      │      │            │
  3027.              │      │      │            └─ Rahmenform
  3028.              │      │      └─ Paneltext
  3029.              │      └─ Position und Größe (TRect)
  3030.              └─ Zeiger auf Fenstertyp
  3031.  
  3032.  
  3033. In WG-Vision werden die Eigenschaften der Fenster durch die
  3034. Art des Rahmens bestimmt. So lassen sich z.B. alle Fenster
  3035. mit Panel verschieben. Fenster mit Resize-Schalter sind in
  3036. ihrer Größe veränderbar.
  3037. Die Rahmenform wird als Parameter im Konstruktor übergeben.
  3038. Zur Vereinfachung stellt WG-Vision folgende additiv ver-
  3039. knüpfbare Konstanten zur Verfügung:
  3040.  
  3041.  
  3042.  
  3043.  
  3044. Programmierhandbuch                                 WG-Vision - 47 -
  3045.  
  3046.  
  3047.  
  3048.  
  3049.  
  3050.  
  3051.  
  3052. winSingle      einfacher Rahmen
  3053. winDouble      Doppelrahmen
  3054. winPanel       Fenster mit Titelleiste      (verschiebbar)
  3055. winMenu        Fenster mit Systemmenü
  3056. winKey         Fenster mit Resize-Schalter  (skalierbar)
  3057.  
  3058. Folgende Kombinationen sind sinnvoll:
  3059.  
  3060. winSingle
  3061. Stationäres Fenster mit einfachen Rahmen. Rahmengröße nach
  3062. unten nicht begrenzt.
  3063.  
  3064. winDouble
  3065. Stationäres Fenster mit Doppelrahmen. Rahmengröße nach unten
  3066. nicht begrenzt.
  3067.  
  3068. Folgende Rahmen besitzen das Minimalmaß 100x86 Pixel. Sie
  3069. lassen sich nicht weiter verkleinern. Wenn ein Rahmenbereich
  3070. kleiner als diese Größe festgelegt wird, dann wird es von
  3071. WG-Vision automatisch auf dieses Maß vergrößert.
  3072.  
  3073. winSingle+winPanel
  3074. Verschiebbares Fenster mit einfachen Rahmen und Titelleiste
  3075.  
  3076. winDouble+winPanel
  3077. Verschiebbares Fenster mit Doppelrahmen und Titelleiste
  3078.  
  3079. winSingle+winPanel+winMenu
  3080. Verschiebbares Fenster mit einfachen Rahmen,Panel und Sys-
  3081. temmenü
  3082.  
  3083. winDouble+winPanel+winMenu
  3084. Verschiebbares Fenster mit Doppelrahmen, Panel und System-
  3085. menü
  3086.  
  3087. winSingle+winPanel+winMenu+winKey
  3088. Verschiebbare Fenster mit einfachen Rahmen, Panel, System-
  3089. menü und Resize-Schalter
  3090.  
  3091.  
  3092.  
  3093.  
  3094. Programmierhandbuch                                 WG-Vision - 48 -
  3095.  
  3096.  
  3097.  
  3098.  
  3099.  
  3100.  
  3101.  
  3102. winDouble+winPanel+winMenu+winKey
  3103. Verschiebbare Fenster mit Doppelrahmen, Panel, Systemmenü
  3104. und Resize-Schalter
  3105.  
  3106. Fenster ohne Sytemmenü lassen sich explizit nicht schließen.
  3107.  
  3108. 5.1.1. Eigenschaften eines Fensters festlegen
  3109.  
  3110. Ein Fenster wird erst dann interessant, wenn es irgendetwas
  3111. tut, z.B. Informationen anzeigt oder einen Text aufblendet.
  3112. Diese Eigenschaften müssen Sie als Programmierer selbst
  3113. festlegen. Leiten Sie dazu von TWindow einen Nachfahren ab
  3114. und geben Sie ihm einen Namen, der in etwa seine Funktion
  3115. (z.B. TDigitalUhr, TDrawWindow etc.) bezeichnet:
  3116.  
  3117. PNewWindow=^TNewWindow;
  3118. TNewWindow=object(TWindow)
  3119.  ... {überschriebene bzw. neue Methoden}
  3120. end;
  3121.  
  3122. Bei größeren Projekten empfehle ich, daß diese neuen Objekt-
  3123. definitionen nicht im Hauptprogramm, sondern in themenbezo-
  3124. genen Units implementiert werden. Die Unit WFileDlg von WG-
  3125. Vision ist z.B. eine solche themenbezogene Unit.
  3126.  
  3127. - Modalität des Fensters ändern
  3128.  
  3129. TWindow-Objekte sind von Haus aus nicht-modal. Das kann sich
  3130. in Anwendungsfällen als ungünstig erweisen. Durch Aufruf der
  3131. Methode
  3132.  
  3133. SetWindowAttrib(false)
  3134.  
  3135. kann man jedoch die Modalität erzwingen. Wird ein derartiges
  3136. Fenster aufgeblendet, dann werden sofort das Menü und alle
  3137. anderen Fenster deaktiviert, indem deren Eventhandler aus
  3138. der Abarbeitungsschleife ausgeklingt werden. Das Hauptmenü
  3139. erscheint beispielsweise in dezenten Grau und ist nicht mehr
  3140. ansprechbar.
  3141.  
  3142.  
  3143.  
  3144. Programmierhandbuch                                 WG-Vision - 49 -
  3145.  
  3146.  
  3147.  
  3148.  
  3149.  
  3150.  
  3151.  
  3152. constructor TNewWindow.Init;
  3153. var R:TRect;
  3154. begin
  3155.   R.Assign(60,80,440,280);             {Größe und Position des Fensters}
  3156.   Init(R,'Test-Fenster',winDouble+winPanel+winMenu+winKey);
  3157.   SetWindowAttrib(false);
  3158. end;
  3159.  
  3160. Der Aufruf innerhalb des Applikationsobjekts sieht jetzt
  3161. folgendermaßen aus:
  3162.  
  3163. procedure TApplication.NewWindow;
  3164. var Window:PNewWindow;
  3165. begin
  3166.   Window:=new(PNewWindow, Init);
  3167.   InsertDesktop(Window);
  3168. end;
  3169.  
  3170. - Fensterfarbe änden
  3171.  
  3172. Die Farbgestaltung eines Fensters erfolgt analog der Farbge-
  3173. bung des Desktops. Da der Rahmen die Farbe des Fensters be-
  3174. stimmt (der Hintergrund wird durch ein separates Objekt
  3175. verwaltet), wird standardmäßig auch hier Palette1 verwendet.
  3176. Die Zuordnung erfolgt innerhalb der virtuellen Methode Set-
  3177. Palette. Diese Methode kann leicht überschrieben werden, so
  3178. daß Sie selbst festlegen können, in welcher Farbkombination
  3179. Ihr Fenster erscheinen soll:
  3180.  
  3181.  
  3182.  
  3183.  
  3184.  
  3185.  
  3186.  
  3187.  
  3188.  
  3189.  
  3190.  
  3191.  
  3192.  
  3193.  
  3194. Programmierhandbuch                                 WG-Vision - 50 -
  3195.  
  3196.  
  3197.  
  3198.  
  3199.  
  3200.  
  3201.  
  3202. procedure TNewWindow.SetPalette;   {einfarbig Grün}
  3203. begin
  3204.   Palette:=#2#2#2#2#2#15#15#15#15#8#0#15#7
  3205. end;        │ │ │ │ │  │  │  │  │   │  │ │
  3206.             │ │ │ │ │  │  │  │  │   │  │ └─ Textfarbe Feld gesperrt
  3207.             │ │ │ │ │  │  │  │  │   │  └─ Textfarbe Auswahlbalken
  3208.             │ │ │ │ │  │  │  │  │   └─ Textfarbe normal
  3209.             │ │ │ │ │  │  │  │  └─ Auswahlbalken
  3210.             │ │ │ │ │  │  │  └─ Menü-Hintergrund
  3211.             │ │ │ │ │  │  └─ reserviert
  3212.             │ │ │ │ │  └─ Textfarbe Titelzeile
  3213.             │ │ │ │ └─ Panelmischfarbe 2
  3214.             │ │ │ └─ Panelmischfarbe 1
  3215.             │ │ └─ Innenrahmen
  3216.             │ └─ Zwischenrahmen
  3217.             └─ Außenrahmen
  3218.  
  3219.  
  3220. In diesem Beispiel wurde die ganze Palette neu gesetzt. Wenn
  3221. Sie nur einige wenige Paletteneintragungen verändern möch-
  3222. ten, empfiehlt sich folgende Vorgehensweise:
  3223.  
  3224. procedure TNewWindow.SetPalette;
  3225. begin
  3226.   TWindow.SetPalette;                               {Vorgänger aufrufen}
  3227.   Palette[2]:=#12;                                 {Innenrahmen auf Rot}
  3228.   Palette[6]:=#14;                                  {Titelzeile in Gelb}
  3229. end;
  3230.  
  3231. oder für ein gelbes Fenster:
  3232.  
  3233. procedure TNewWindow.SetPalette;
  3234. var i:integer;
  3235. begin
  3236.   TWindow.SetPalette;                               {Vorgänger aufrufen}
  3237.   for i:=2 to 5 do Palette[i]:=#14;
  3238.   Palette[3]:=#7;
  3239.   Palette[6]:=#1;
  3240. end;
  3241.  
  3242.  
  3243.  
  3244. Programmierhandbuch                                 WG-Vision - 51 -
  3245.  
  3246.  
  3247.  
  3248.  
  3249.  
  3250.  
  3251.  
  3252. Ansonsten können Sie natürlich alle Register der Stringmani-
  3253. pulation zur Festlegung der Farbpalette nutzen.
  3254. Eine weitere Möglichkeit besteht in der Wahl einer der vor-
  3255. definierten und speziell für WG-Vision-Fenster ausgelegten
  3256. Spezialpaletten. Sie werden über einen Index angesprochen,
  3257. für die Sie folgende Konstanten-Bezeichner verwenden können:
  3258.  
  3259. palStandard
  3260. palRed
  3261. palGray
  3262. palGreen;
  3263.  
  3264. procedure TNewWindow.SetPalette;
  3265. begin
  3266.   Palette:=Pal[palGreen];
  3267. end;
  3268.  
  3269. - Fensterhintergrund
  3270.  
  3271. Ein Standard-Fenster besteht aus drei verschiedenen Schich-
  3272. ten, die in einer doppelt verketteten Liste verwaltet wer-
  3273. den. Diese Schichten sind
  3274.  
  3275. a) der Untergrund
  3276. Der Untergrund ist der Bereich des Bildschirms, welcher vom
  3277. Fenster abgedeckt wird. Dieser Untergrund muß bevor ein Fen-
  3278. ster aufgeblendet wird (d.h. dessen Draw-Methode abgearbei-
  3279. tet) gerettet werden. Das geschieht übrigens völlig
  3280. automatisch. Ist beispielsweise genügend EMS-Speicher vor-
  3281. handen, dann wird der Untergrund in den Expanded Memory ge-
  3282. schrieben. Diesen Vorgang können Sie übrigens sehr schön
  3283. beobachten, wenn Sie den EMS-Wächter installiert haben und
  3284. das Programm nicht gerade unter Borland Pascal 7 starten.
  3285. Reicht der EMS-Speicher nicht mehr aus oder ist gar keiner
  3286. vorhanden, dann schreibt WG-Vision den Untergrund in eine
  3287. temporäre Datei (Zufallszahl+Extension ".$$$") auf den gera-
  3288. de aktiven Datenträger (i.A. die Festplatte),
  3289.  
  3290.  
  3291.  
  3292.  
  3293.  
  3294. Programmierhandbuch                                 WG-Vision - 52 -
  3295.  
  3296.  
  3297.  
  3298.  
  3299.  
  3300.  
  3301.  
  3302. b) der Rahmen
  3303. Der Rahmen ist halt nur ein Rahmen, obwohl das Objekt recht
  3304. intelligent ist. Es muß ja immerhin auf die Lage des Maus-
  3305. kursors reagieren und gegebenenfalls die Form des Mauskursor
  3306. verändern. Außerdem ist er noch für Verschiebungen und Ska-
  3307. lierungen sowie für das Systemmenü zuständig. Alle diese
  3308. Vorgänge laufen innerhalb des Eventhandlers des Frame-Objek-
  3309. tes ab.
  3310.  
  3311. c. der Hintergrund
  3312. Der Hintergrund ist der Teil des Fensters, der sich inner-
  3313. halb des Rahmens befindet. Er ist so wichtig, daß er durch
  3314. ein eigenes Objekt verwaltet wird. Es ist das gleiche Ob-
  3315. jekt, welches auch für den Hintergrund des Desktops verant-
  3316. wortlich ist: TBackGround.
  3317.  
  3318. Später werden wir zu diesen drei Schichten noch eine weitere
  3319. hinzufügen, den Scrollbereich mit Rollbalken.
  3320. Der Hintergrund ist in der Voreinstellung eine weiße Fläche.
  3321. Um das zu ändern, muß ein neues Objekt von TBackground abge-
  3322. leitet und in die Liste mit den Fensterbestandteilen einge-
  3323. fügt werden:
  3324.  
  3325. PNewBackGround=^TNewBackGround;
  3326. TNewBackGround=object(TBackGround)
  3327.  procedure Draw; virtual;
  3328. end;
  3329.  
  3330. WG-Vision verwendet dann zum Aufblenden des Fensterhinter-
  3331. grundes nicht mehr die Draw-Methode von TBackGround, sondern
  3332. die von TNewBackground.
  3333. Bei der Implementation von TNewBackGround.Draw muß man wis-
  3334. sen, wie groß der Bereich innerhalb des Rahmens ist. Sie
  3335. brauchen jetzt aber nicht zum Zollstock zu greifen, denn WG-
  3336. Vision stellt Ihnen die Größe des Hintergrundobjektes mund-
  3337. gerecht als TRect-Objekt in der Variablen Border zur Verfü-
  3338. gung:
  3339.  
  3340.  
  3341.  
  3342.  
  3343.  
  3344. Programmierhandbuch                                 WG-Vision - 53 -
  3345.  
  3346.  
  3347.  
  3348.  
  3349.  
  3350.  
  3351.  
  3352. procedure TNewBackGround.Draw;
  3353. begin
  3354.   with Border do
  3355.    FBar(A.x,A.y,B.x,B.y,LightBlue);
  3356. end;
  3357.  
  3358. Border enthält im Punkt A (TPoint-Objekt) die Koordinaten
  3359. der linken oberen Ecke und im Punkt B die Koordinaten der
  3360. rechten unteren Ecke des Hintergrundbereiches.
  3361. Die Prozedur FBar wird durch die Unit WUtils zur Verfügung
  3362. gestellt und zeichnet einen durch die Punkte A und B gegebe-
  3363. nen gefüllten rechteckigen Bereich. Der letzte Parameter ist
  3364. die Füllfarbe.
  3365.  
  3366. Komplexbeispiel     Ausgabe der momentan verfügbaren
  3367.                     Speicherressourcen des Systems
  3368.  
  3369. Aufgabenstellung:
  3370. In einem Fenster soll der momentan freie Arbeitsspeicher
  3371. (Heap), der freie Expansionsspeicher und die noch vorhandene
  3372. freie Kapazität der Festplatte C ausgegeben werden.
  3373.  
  3374. program Komplexbeispiel_1;
  3375.  
  3376. uses WDecl,
  3377.      WEvent,
  3378.      WUtils,
  3379.      WApp,
  3380.      WViews,
  3381.      WDlg,
  3382.      graph;
  3383.  
  3384.  
  3385. const cmGetMemory=101;       {Kommando zum Aufblenden des Info-Fensters}
  3386.  
  3387.  
  3388.  
  3389.  
  3390.  
  3391.  
  3392.  
  3393.  
  3394. Programmierhandbuch                                 WG-Vision - 54 -
  3395.  
  3396.  
  3397.  
  3398.  
  3399.  
  3400.  
  3401.  
  3402. type TApplication=object(TApp)                      {Applikationsobjekt}
  3403.       procedure InitMenuBar; virtual;
  3404.       procedure HandleEvent; virtual;
  3405.       procedure GetMemoryStatus;
  3406.      end;
  3407.  
  3408.      PMemoryInfo=^TMemoryInfo;                            {Info-Fenster}
  3409.      TMemoryInfo=object(TWindow)
  3410.       constructor Init;
  3411.       procedure InitBackground; virtual;
  3412.      end;
  3413.  
  3414.      PMemoryInfoBgrd=^TMemoryInfoBgrd;             {Fenster-Hintergrund}
  3415.      TMemoryInfoBgrd=object(TBackground)
  3416.       procedure Draw; virtual;
  3417.      end;
  3418.  
  3419.  
  3420. var MyApp:TApplication;
  3421.  
  3422.  
  3423. {Implementation TApplication}
  3424.  
  3425. procedure TApplication.InitMenuBar;
  3426. begin
  3427.   MainMenu('~F~enster',0);
  3428.    SubMenu('~S~peicher-Ressourcen',cmGetMemory,0,0,false,false);
  3429.    SubMenu('E~x~it
  3430.          Alt+X',cmCloseApplication,0,altX,false,false);
  3431. end;
  3432.  
  3433. procedure TApplication.HandleEvent;
  3434. begin
  3435.   TProgram.HandleEvent;
  3436.   case Event.Command of
  3437.    cmGetMemory:GetMemoryStatus;
  3438.   end; {case}
  3439. end;
  3440.  
  3441.  
  3442.  
  3443.  
  3444. Programmierhandbuch                                 WG-Vision - 55 -
  3445.  
  3446.  
  3447.  
  3448.  
  3449.  
  3450.  
  3451.  
  3452. procedure TApplication.GetMemoryStatus;   {Mit diesem "Zweizeiler" wird}
  3453. var Window:PMemoryInfo;                {das Info-Fenster in die Window-}
  3454. begin                                     {Liste des Desktops eingefügt}
  3455.   Window:=new(PMemoryInfo, Init);
  3456.   InsertDesktop(Window);
  3457. end;
  3458.  
  3459. Die Implementation von TMemoryInfo und TMemoryInfoBgrd kann natürlich
  3460. auch in einer eigenen Unit stehen und ist dann ohne Änderungen allgemein
  3461. verwendbar
  3462.  
  3463. {Implementation TMemoryInfo}
  3464.  
  3465. constructor TMemoryInfo.Init;     {... und hier das eigentliche Fenster}
  3466. var R:TRect;
  3467. begin
  3468.   R.Assign(60,80,450,320);
  3469.   TWindow.Init(R,'Speicher-Ressourcen',winDouble+winPanel+winMenu);
  3470.   SetWindowAttrib(false);           {modal-machen, damit keine weiteren}
  3471. end;     {Fenster aufgeblendet werden können und das Menü gesperrt wird}
  3472.  
  3473. procedure TMemoryInfo.InitBackground;
  3474. var R:TRect;
  3475. begin
  3476.   R:=Frame^.Area;      {hier wird die Größe innerhalb des Rahmens geholt}
  3477.   Bgrd:=new(PMemoryInfoBgrd, Init(R));             {und jetzt kennt auch}
  3478.                                  {└─TMemoryInfoBgrd diesen Wert (Border)}
  3479.   List^.InsertItem(Bgrd);
  3480. end;
  3481.  
  3482.  
  3483.  
  3484.  
  3485.  
  3486.  
  3487.  
  3488.  
  3489.  
  3490.  
  3491.  
  3492.  
  3493.  
  3494. Programmierhandbuch                                 WG-Vision - 56 -
  3495.  
  3496.  
  3497.  
  3498.  
  3499.  
  3500.  
  3501.  
  3502. {Implementation TMemoryInfoBgrd}
  3503.  
  3504. procedure TMemoryInfoBgrd.Draw;
  3505. var z:string;
  3506.     EMS:PEMS;          {diese Speicherverwaltungsobjekte werden von der}
  3507.     HD:PHardDisk;                   {Unit WViews zur Verfügung gestellt}
  3508. begin
  3509.   with Border do
  3510.    begin
  3511.      FillBar(A.x,A.y,B.x,B.y,Yellow,White,SolidFill);
  3512.  
  3513.      {ist doch hübsch,oder?}
  3514.  
  3515.      str(MemAvail:8,z); SetColor(Red);                      {freier Heap}
  3516.      OutTextXY(A.x+10,A.y+25,'Hauptspeicher');
  3517.      OutTextXY(A.x+10,A.y+100,'Expanded Memory');
  3518.      OutTextXY(A.x+10,A.y+160,'Festplatte C');
  3519.      SetColor(Blue);
  3520.      OutTextXY(A.x+10,A.y+45,'freier RAM (Heap)           :   '+z+'
  3521.                                                               Byte');
  3522.      str(MaxAvail:8,z);
  3523.      OutTextXY(A.x+10,A.y+65,'größter zusammenhängender');
  3524.      OutTextXY(A.x+10,A.y+75,'freier Speicherblock        :   '+z+'
  3525.                                                               Byte');
  3526.      EMS:=new(PEMS, Init(Border));
  3527.      str(EMS^.FreeMemory:8,z);
  3528.      OutTextXY(A.x+10,A.y+120,'verfügbarer Speicher        :   '+z+'
  3529.                                                               Byte');
  3530.      str(EMS^.FreeMemory div 16384:8,z);
  3531.      OutTextXY(A.x+10,A.y+140,'verfügbare Seiten           :   '+z+'
  3532.                                                               Pages');
  3533.      dispose(EMS, Done);                               {Adios Amigos !}
  3534.      HD:=new(PHardDisk, Init(Border));
  3535.      str(HD^.FreeMemory:8,z);
  3536.      OutTextXY(A.x+10,A.y+180,'verfügbare Plattenkapazität :   '+z+'
  3537.                                                               Byte');
  3538.      dispose(HD, Done);                                {Adios Amigos !}
  3539.    end;
  3540. end;
  3541.  
  3542.  
  3543.  
  3544. Programmierhandbuch                                 WG-Vision - 57 -
  3545.  
  3546.  
  3547.  
  3548.  
  3549.  
  3550.  
  3551.  
  3552. {Hauptprogramm}
  3553.  
  3554. begin
  3555.   MyApp.Init('Speicher-Ressourcen');
  3556.   MyApp.Run;
  3557.   MyApp.Done;
  3558. end.
  3559.  
  3560. Dieses kleine Programm, das fast völlig ohne Schnörkel aus-
  3561. kommt, zeigt deutlich die Vorgehensweise bei der Programmie-
  3562. rung eines Anwendungsprogramms mit WG-Vision. Hier noch
  3563. einmal die wesentlichsten Schritte:
  3564.  
  3565. 1. Ableitung eines Applikationsobjektes von TApp und
  3566.    Anpassung des Desktops (Farben, Hintergrundgestaltung
  3567.    etc.)
  3568.  
  3569. 2. Menü definieren und Eventhandler einrichten
  3570.  
  3571. 3. Fenster in das Desktop einfügen und ihren Aufruf über den
  3572.    Eventhandler sicherstellen
  3573.  
  3574. 4. Neue Fensterobjekt ableiten und ihre Eigenschaften der
  3575.    Problemstellung anpassen
  3576.  
  3577. Nun noch einige Worte zum obigen Programm. Es mag etwas be-
  3578. fremdlich erscheinen, daß zur Initalisierung der Speicher-
  3579. verwaltung eine TRect-Variable übergeben werden muß. Der
  3580. Grund dafür ist recht einfach. Die Speicherobjekte von WG-
  3581. Vision (TEMS, THardDisk und THeap) sind so ausgelegt, daß
  3582. sie rechteckige Ausschnitte des Grafikbildschirms über ihre
  3583. Save-Methoden speichern können. Die im Konstruktor übergebe-
  3584. nen Koordinaten legen diese Ausschnitte fest. In unserem
  3585. obigen Beispiel sind diese Koordinaten jedoch völlig belang-
  3586. los, da lediglich abgefragt wird, wieviel Speicher denn noch
  3587. verfügbar sei. Anstatt Border hätten wir deshalb zur Initia-
  3588. lisierung auch jedes x-beliebige TRect-Objekt verwenden
  3589. können. Der Bequemlichkeit halber wird jedoch auf Border zu-
  3590. rückgegriffen.
  3591.  
  3592.  
  3593.  
  3594. Programmierhandbuch                                 WG-Vision - 58 -
  3595.  
  3596.  
  3597.  
  3598.  
  3599.  
  3600.  
  3601.  
  3602. Achten Sie bei der Implementation der Draw-Methode eines
  3603. Hintergrundobjekts immer darauf, daß Sie mit Koordinaten re-
  3604. lativ zu Border arbeiten (also "A.x + Irgendwas" und nicht
  3605. "Irgendwas"). Nur so kann sichergestellt werden, daß WG-Vi-
  3606. sion bei einer Verschiebung oder Skalierung eines Fensters
  3607. die Koordinaten richtig transformiert. Bei der Hintergrund-
  3608. gestaltung eines skalierbaren Fensters muß außerdem auf ein
  3609. ordentliches Clipping entlang des Innenrahmens geachtet wer-
  3610. den (SetViewPort) wenn man nicht möchte, daß beim Verklei-
  3611. nern eines Fensters die Schrift über den Rand hinausschießt.
  3612. Im nächsten Beispiel soll gezeigt werden, wie man es errei-
  3613. chen kann, daß sich der Inhalt des Hintergrundes permanent
  3614. verändert. Kurz gesagt, wir wollen eine Digitaluhr program-
  3615. mieren. Auf den ersten Blick erscheint das Unterfangen als
  3616. recht schwierig. Denn ein permanentes Öffnen und Schließen
  3617. eines Fensters nur zur permanenten Aktualisierung des Fen-
  3618. sterhintergrundes dürfte selbst bei einem sehr schnellen
  3619. Rechner wenig akzeptabel sein.
  3620. Die Lösung des Problems besteht darin, die Anzeige der Uhr-
  3621. zeit gänzlich vom Fensterhintergrund abzutrennen und immer
  3622. nur die Ziffern zu aktualisieren, die sich wirklich gerade
  3623. ändern. Dieser Mechanismus muß in einem Programmteil unter-
  3624. gebracht werden, der ständig durchlaufen wird. Solch ein
  3625. Programmteil ist der Eventhandler eines Fensters, der, nach-
  3626. dem das Fenster aufgeblendet und fokussiert wurde, in die
  3627. Ereignisabarbeitungsschleife des Hauptprogramms eingehangen
  3628. wird (MyApp.Run).
  3629. Damit wir unsere Digitaluhr ohne große Probleme auch in an-
  3630. deren Programmen verwenden können, werden alle Routinen in
  3631. einer neuen Unit, WUhr, zusammengefaßt. Diese Unit kann auch
  3632. als Overlay deklariert werden was den Vorteil hat, daß die
  3633. darin enthaltenen Objekte erst zur Laufzeit Speicher allo-
  3634. kieren.
  3635.  
  3636.  
  3637.  
  3638.  
  3639.  
  3640.  
  3641.  
  3642.  
  3643.  
  3644. Programmierhandbuch                                 WG-Vision - 59 -
  3645.  
  3646.  
  3647.  
  3648.  
  3649.  
  3650.  
  3651.  
  3652. UNIT WUhr;
  3653.  
  3654. INTERFACE
  3655.  
  3656. uses WDecl,
  3657.      WViews,
  3658.      WDlg,
  3659.      WDriver,
  3660.      dos,
  3661.      graph;
  3662.  
  3663. type PDigitalUhr=^TDigitalUhr;                              {Unsere Uhr}
  3664.      TDigitalUhr=object(TWindow)
  3665.       constructor Init(x,y:integer);
  3666.       procedure SetPalette; virtual;
  3667.       procedure InitBackground; virtual;
  3668.       procedure HandleEvent; virtual;
  3669.      end;
  3670.  
  3671.      PUhrBgrd=^TUhrBgrd;                             {Uhren-Hintergrund}
  3672.      TUhrBgrd=object(TBackground)
  3673.       Stunde  : word;                     {Warum das ? --> siehe Text !}
  3674.       Minute  : word;
  3675.       Sekunde : word;
  3676.       procedure Draw; virtual;
  3677.      end;
  3678.  
  3679. IMPLEMENTATION
  3680.  
  3681. {Implementation TDigitalUhr}
  3682.  
  3683. constructor TDigitalUhr.Init(x,y:integer);  {Neuer Konstruktor, x und y}
  3684. var R:TRect;                    {dienen der Positionierung des Fensters}
  3685. begin
  3686.   R.Assign(x,y,x+190,y+105);
  3687.   TWindow.Init(R,'Uhr',winDouble+winPanel+winMenu);
  3688.   SetWindowAttrib(false);                 {Modal machen ! (warum nur ?)}
  3689. end;
  3690.  
  3691.  
  3692.  
  3693.  
  3694. Programmierhandbuch                                 WG-Vision - 60 -
  3695.  
  3696.  
  3697.  
  3698.  
  3699.  
  3700.  
  3701.  
  3702. procedure TDigitalUhr.SetPalette;
  3703. begin
  3704.   Palette:=Pal[palRed];                   {eine Uhr mit roten Rahmen ..}
  3705. end;
  3706.  
  3707. procedure TDigitalUhr.InitBackground;
  3708. var R:TRect;
  3709. begin
  3710.   R:=Frame^.Area;
  3711.   Bgrd:=new(PUhrBgrd, Init(R));
  3712.   List^.InsertItem(Bgrd);
  3713. end;
  3714.  
  3715. procedure TDigitalUhr.HandleEvent;
  3716. var Std,Min,Sek,HSek,                                   {aktuelle Zeit}
  3717.     StdOld,MinOld,SekOld : word;                            {alte Zeit}
  3718.     LfdPtr:PGroup;
  3719.  
  3720. procedure WriteTime(Nr,x,y:integer;Zeit1,Zeit2:word);
  3721. var zz:string[2];
  3722. begin
  3723.   Mouse.HideMouse;                           {Zeitanzeige aktualisieren}
  3724.   str(Zeit1:2,zz);
  3725.   SetColor(Blue);
  3726.   OutTextXY(x,y,zz);                           {alte Zeit überschreiben}
  3727.   str(Zeit2:2,zz);
  3728.   SetColor(LightCyan);
  3729.   OutTextXY(x,y,zz);                                         {neue Zeit}
  3730.   if Nr<3 then OutTextXY(x+38,y,':');         {Zeitbegrenzer (:) setzen}
  3731.   Mouse.ShowMouse;
  3732. end;
  3733.  
  3734.  
  3735.  
  3736.  
  3737.  
  3738.  
  3739.  
  3740.  
  3741.  
  3742.  
  3743.  
  3744. Programmierhandbuch                                 WG-Vision - 61 -
  3745.  
  3746.  
  3747.  
  3748.  
  3749.  
  3750.  
  3751.  
  3752. {------}
  3753.  
  3754. begin
  3755.   TWindow.HandleEvent;                               {nicht vergessen !}
  3756.   SetTextStyle(TriplexFont,HorizDir,4);
  3757.   GetTime(Std,Min,Sek,HSek);         {Onkel DOS fragen, wie spät es ist}
  3758.   LfdPtr:=List^.GetItems(3);      {hier wird es interessant, siehe Text}
  3759.   with PUhrBgrd(LfdPtr)^ do
  3760.    begin
  3761.      StdOld:=Stunde;
  3762.      MinOld:=Minute;
  3763.      SekOld:=Sekunde;
  3764.    end;
  3765.   if StdOld<>Std then WriteTime(1,Origin.x+30,Origin.y+40,StdOld,Std);
  3766.   if MinOld<>Min then WriteTime(2,Origin.x+80,Origin.y+40,MinOld,Min);
  3767.   if SekOld<>Sek then WriteTime(3,Origin.x+130,Origin.y+40,SekOld,Sek);
  3768.   with PUhrBgrd(LfdPtr)^ do
  3769.    begin
  3770.      Stunde:=Std;
  3771.      Minute:=Min;
  3772.      Sekunde:=Sek;
  3773.    end;
  3774.   SetTextStyle(DefaultFont,HorizDir,0);
  3775. end;
  3776.  
  3777. {Implementation TUhrBgrd}
  3778.  
  3779. procedure TUhrBgrd.Draw;
  3780. begin
  3781.   Stunde:=0; Minute:=0; Sekunde:=0;
  3782.   with Border do
  3783.    begin                {Blau ist eine schöne Farbe (Himmel, Meer etc.)}
  3784.      SetFillStyle(SolidFill,Blue);
  3785.      Bar(A.x,A.y,B.x,B.y);
  3786.    end;
  3787. end;
  3788.  
  3789. END.
  3790.  
  3791.  
  3792.  
  3793.  
  3794. Programmierhandbuch                                 WG-Vision - 62 -
  3795.  
  3796.  
  3797.  
  3798.  
  3799.  
  3800.  
  3801.  
  3802. Im Objekt TUhrBgrd wird die jeweils aktuelle Zeit gespei-
  3803. chert. Wenn das Fenster beispielsweise bewegt wird (das soll
  3804. ja ab und an mal vorkommen), wird die Zeit wieder auf Null
  3805. gesetzt, damit die entsprechende Routine im Eventhandler die
  3806. gesamte Zeichenkette mit der Uhrzeit neu im Fenster dar-
  3807. stellt.
  3808. Der Zugriff auf die Daten im TUhrBgrd-Objekt erfolgt über
  3809. einen Typecast. Zuvor wird der Zeiger auf dieses Objekt aus
  3810. der doppelt verketteten Elementenliste mit dem Namen List
  3811. ausgelesen:
  3812.  
  3813. LfdPtr:=List^.GetItems(3);
  3814.  
  3815. List enthält, wie Sie bereits wissen, alle Elemente eines
  3816. Fensters in der Reihenfolge Untergrund, Rahmen und
  3817. Hintergrund. Da der Hintergrund immer das dritte Objekt in
  3818. dieser Liste ist, wird als Parameter für GetItems 3
  3819. übergeben. Um jetzt auf die Datenfelder zugreifen zu können,
  3820. ist noch ein Typecast notwendig:
  3821.  
  3822. with PUhrBgrd(LfdPtr)^ do
  3823.  begin
  3824.    StdOld:=Stunde;
  3825.    MinOld:=Minute;
  3826.    SekOld:=Sekunde;
  3827.  end;
  3828.  
  3829. Eine Typüberprüfung entsprechend
  3830.  
  3831. if TypeOf(LfdPtr^)=TypeOf(PUhrBgrd) then ...
  3832.  
  3833. ist nicht erforderlich, da das Ergebnis eindeutig ist.
  3834. Auf die gleiche Weise wird die aktualisierte Zeit in das Ob-
  3835. jekt TUhrBgrd zurückgeschrieben.
  3836. Und noch etwas, der Triplex-Font muß für das Programm ver-
  3837. fügbar sein sonst brauchen Sie eventuell eine Brille zum
  3838. Lesen der Zeitanzeige.
  3839.  
  3840.  
  3841.  
  3842.  
  3843.  
  3844. Programmierhandbuch                                 WG-Vision - 63 -
  3845.  
  3846.  
  3847.  
  3848.  
  3849.  
  3850.  
  3851.  
  3852. 5.1.2. Hintergrundinformationen zur Fenstertechnik
  3853.  
  3854. Alle sichtbaren Elemente des Bildschirms wie Rahmen, Fen-
  3855. ster, Dialogelemente usw. werden in doppelt verketteten Li-
  3856. sten verwaltet. Diese Listen sind Instanzen des Objektes
  3857. TGroup. TGroup enthält Methoden, um derartige Listen zu ver-
  3858. walten:
  3859.  
  3860. TGroup=object(TView)
  3861.   First    : PGroup;       {erstes Element der Liste}
  3862.   Last     : PGroup;       {letztes Element der Liste}
  3863.   Current  : PGroup;       {gerade aktives Element}
  3864.   CurrNo   : word;         {Index des gerade aktiven Elements}
  3865.   AnzElem  : word;         {Anzahl der Elemente in der Liste}
  3866.   constructor Init;
  3867.   destructor Done; virtual;
  3868.   ...
  3869.   procedure InsertItem(Item:PGroup);  {Element in die Liste einfügen}
  3870.   procedure DeleteItems;              {Alle Elemente löschen}
  3871.   function GetItems(Nr:word):PGroup;  {Pointer auf das Element mit}
  3872.                                       {dem Index i}
  3873.   procedure DelItem(N:PGroup);        {Element N löschen}
  3874.   procedure DelLastItem;              {Letztes Element der Liste}
  3875.                                       {löschen}
  3876.   procedure Draw; virtual;            {alle Elemente auf dem}
  3877.                                       {Bildschirm darstellen}
  3878.   procedure Hide; virtual;            {Alle Elemente vom Bildschirm}
  3879.                                       {löschen}
  3880.   ...
  3881.  
  3882. end;
  3883.  
  3884. Das Objekt TDesktop verwaltet z.B. den Rahmen und den
  3885. Hintergrund in der Liste List. Deshalb müssen Sie auch einen
  3886. neuen Hintergrund mit dem Befehl
  3887.  
  3888. List^.InsertItem(Bgrd);
  3889.  
  3890.  
  3891.  
  3892.  
  3893.  
  3894. Programmierhandbuch                                 WG-Vision - 64 -
  3895.  
  3896.  
  3897.  
  3898.  
  3899.  
  3900.  
  3901.  
  3902. in diese Liste einbauen. Auf die gleiche Art und Weise wer-
  3903. den auch Fenster in das Desktop eingefügt. Nur das hier die
  3904. Liste WinList für die Verwaltung zuständig ist. Zur Verein-
  3905. fachung stellt TApp dafür die Methode InsertDesktop zur Ver-
  3906. fügung:
  3907.  
  3908. InsertDesktop(Window);
  3909.  
  3910. Seine Implementation sieht folgendermaßen aus:
  3911.  
  3912. procedure TProgram.InsertDesktop(Item:PGroup);
  3913. begin
  3914.   with Desktop^ do
  3915.    begin
  3916.      WinList^.InsertItem(Item);
  3917.      inc(WinCount);                     {Window-Zähler}
  3918.    end;
  3919. end;
  3920.  
  3921. Die Variable WinCount enthält die Anzahl der z.Z. instal-
  3922. lierten Fensterobjekte.
  3923. Ein Fenster, d.h. ein Nachfahre oder eine Instanz von TWin-
  3924. dow, verwaltet seine Elemente analog. Auch hier heißt die
  3925. Elementeliste List.
  3926. Zur Darstellung auf dem Bildschirm werden jeweils die Draw-
  3927. Methoden der einzelnen Listenelemente aufgerufen. Zum Ent-
  3928. fernen verwendet man die dazugehörigen Hide-Methoden.
  3929. Mit folgendem Programm können Sie durch einfaches Drücken
  3930. der <F8>-Taste beliebig viele Fenster auf dem Desktop erzeu-
  3931. gen ("beliebig" bedeutet weniger als 256 oder bis sich ihr
  3932. Programm mangels Heap von selbst verabschiedet ...):
  3933.  
  3934.  
  3935.  
  3936.  
  3937.  
  3938.  
  3939.  
  3940.  
  3941.  
  3942.  
  3943.  
  3944. Programmierhandbuch                                 WG-Vision - 65 -
  3945.  
  3946.  
  3947.  
  3948.  
  3949.  
  3950.  
  3951.  
  3952. program ZufallsFenster;
  3953.  
  3954. uses WApp,
  3955.      WDecl,
  3956.      WEvent,
  3957.      WViews,
  3958.      WDlg,
  3959.      graph;
  3960.  
  3961. const cmStandard        = 101;
  3962.       cmCloseAllWindows = 102;
  3963.  
  3964. type TApplication=object(TApp)
  3965.        procedure InitMenuBar; virtual;
  3966.        procedure HandleEvent; virtual;
  3967.        procedure NewWindow;
  3968.        procedure CloseAllWindows;
  3969.      end;
  3970.  
  3971. var MyProg:TApplication;
  3972.  
  3973.  
  3974. procedure TApplication.InitMenuBar;
  3975. begin
  3976.   MainMenu('~F~enster',0);
  3977.    SubMenu('~Z~ufalls-Fenster  F8',cmStandard,0,kbF8,false,false);
  3978.    SubMenu('~F~enster schließen',cmCloseAllWindows,0,0,false,false);
  3979.    SubMenu('E~x~it  Alt-X',cmCloseApplication,0,altX,false,false);
  3980. end;
  3981.  
  3982. procedure TApplication.HandleEvent;
  3983. begin
  3984.   Heap^.ShowHeapStatus(523,8,White);
  3985.   TProgram.HandleEvent;
  3986.   case Event.Command of
  3987.    cmStandard        : NewWindow;
  3988.    cmCloseAllWindows : CloseAllWindows;
  3989.   end; {case}
  3990. end;
  3991.  
  3992.  
  3993.  
  3994. Programmierhandbuch                                 WG-Vision - 66 -
  3995.  
  3996.  
  3997.  
  3998.  
  3999.  
  4000.  
  4001.  
  4002. procedure TApplication.NewWindow;
  4003. var R:TRect;
  4004.     x,y:integer;
  4005.     Window:PWindow;
  4006. begin
  4007.   x:=Random(480)+4;
  4008.   y:=Random(328)+48;
  4009.   R.Assign(x,y,x+150,y+100);
  4010.   Window:=new(PWindow, Init(R,'ZufallsFenster',
  4011.               winDouble+winPanel+winMenu+winKey));
  4012.   InsertDesktop(Window);
  4013. end;
  4014.  
  4015. procedure TApplication.CloseAllWindows;
  4016. var i:integer;
  4017.     LfdPtr:PGroup;
  4018. begin
  4019.   with Desktop^ do
  4020.    begin
  4021.      for i:=WinCount downto 1 do  {WinList von hinten nach vorn abbauen}
  4022.       begin
  4023.         LfdPtr:=WinList^.GetItems(i);         {Pointer holen über Index}
  4024.         LfdPtr^.Hide;       {Fenster schließen, Untergrund restaurieren}
  4025.         WinList^.DelLastItem;      {Pointer aus der Liste entfernen und}
  4026.       end;                                     {Speicherplatz freigeben}
  4027.      WinCount:=0; WinAnz:=0;                                {Das wars !}
  4028.    end;
  4029. end;
  4030.  
  4031. {Hauptprogramm}
  4032.  
  4033. begin
  4034.   MyProg.Init('Zufallsfenster');
  4035.   MyProg.Run;
  4036.   MyProg.Done;
  4037. end.
  4038.  
  4039.  
  4040.  
  4041.  
  4042.  
  4043.  
  4044. Programmierhandbuch                                 WG-Vision - 67 -
  4045.  
  4046.  
  4047.  
  4048.  
  4049.  
  4050.  
  4051.  
  4052. Damit Sie nicht jedes Fenster zwecks Löschung einzeln an-
  4053. klicken müssen, wurde der Menüpunkt "Fenster schließen" in
  4054. das Programm integriert. Die eigentliche Arbeit übernimmt
  4055. die Prozedur CloseAllWindows, die wir uns hier noch etwas
  4056. genauer ansehen wollen:
  4057.  
  4058. procedure TApplication.CloseAllWindows;
  4059. var i:integer;
  4060.     LfdPtr:PGroup;
  4061. begin
  4062.   with Desktop^ do
  4063.    begin
  4064.      for i:=WinCount downto 1 do             { --> A }
  4065.       begin
  4066.         LfdPtr:=WinList^.GetItems(i);        { --> B }
  4067.         LfdPtr^.Hide;                        { --> C }
  4068.         WinList^.DelLastItem;                { --> D }
  4069.       end;
  4070.      WinCount:=0; WinAnz:=0;                 { --> E }
  4071.    end;
  4072. end;
  4073.  
  4074. WinCount und WinAnz sind zwei Zähler, die beide gleich Null
  4075. sind, wenn sich keine Fenster auf dem Desktop befinden.
  4076. Ansonsten enthalten sie die Anzahl der geöffneten Fenster.
  4077.  
  4078. A :  Alle geöffneten Fenster sind in der Liste WinList, die
  4079.      ein Bestandteil des Desktop ist, enthalten. Da die
  4080.      Fenster in der entgegengesetzten Richtung ihrer
  4081.      Implementation wieder abgebaut werden müssen, muß auch
  4082.      der Index i entsprechend laufen.
  4083.  
  4084. B :  Einem Pointer wird die Adresse des i-ten Eintrages der
  4085.      Windowliste zugeordnet
  4086.  
  4087. C :  Schließen des Fensters. Die Hide-Methode eines
  4088.      Standardfensters sieht folgendermaßen aus (Unit WDlg):
  4089.  
  4090.  
  4091.  
  4092.  
  4093.  
  4094. Programmierhandbuch                                 WG-Vision - 68 -
  4095.  
  4096.  
  4097.  
  4098.  
  4099.  
  4100.  
  4101.  
  4102.      procedure TWindow.Hide;
  4103.      var LfdPtr:PGroup;
  4104.          i:integer;
  4105.      begin
  4106.        Mouse.HideMouse;
  4107.        with List^ do
  4108.         for i:=AnzElem downto 1 do     {Hintergrund, Rahmen, Untergrund}
  4109.          begin
  4110.            LfdPtr:=GetItems(i);
  4111.            LfdPtr^.Hide;                                {Adios Amigos !}
  4112.          end;
  4113.        Mouse.ShowMouse;                      {jetzt darf ich wieder ...}
  4114.      end;
  4115.  
  4116.      Eine verblüffende Ähnlichkeit, nicht wahr ?
  4117.  
  4118. D :  Letztes Element der Windowliste löschen und
  4119.      Speicherfreigabe. Wenn Sie diesen Befehl vergessen,
  4120.      funktioniert das Programm trotzdem. Der von der Liste
  4121.      im Heap beanspruchte Speicher wird jedoch nicht
  4122.      freigegeben und ist damit verloren. An dieser Stelle
  4123.      erweist sich übrigens die Nützlichkeit des Heap-
  4124.      Wächters.
  4125.  
  4126. E :  Fensterzähler auf Null setzen
  4127.  
  4128. Sie werden verstehen, daß ich im Rahmen dieses Handbuches
  4129. keine erschöpfende Abhandlung über verkettete Listen schrei-
  4130. ben kann. Alle glücklichen Besitzer der Profiversion sollten
  4131. in diesem Zusammenhang ruhig einmal einen Nachmittag lang
  4132. den Quelltext des Objekts TGroup durchforsten. Wenn dann im-
  4133. mer noch nicht der Groschen fällt (und ich nehme das nieman-
  4134. den übel), dann hilft nur noch das Studium von Arne Schäpers
  4135. Klassiker "Turbo Pascal 6.0 - Konzepte, Analysen, Tips &
  4136. Tricks" Seite 574 ff. Und für alle die Trost brauchen : als
  4137. WG-Vision Programmierer kommen Sie (man ist geneigt, "Gott-
  4138. seidank" zu sagen) mit den eigentlichen Listen-Innereien
  4139. kaum in Berührung.
  4140.  
  4141.  
  4142.  
  4143.  
  4144. Programmierhandbuch                                 WG-Vision - 69 -
  4145.  
  4146.  
  4147.  
  4148.  
  4149.  
  4150.  
  4151.  
  4152. 5.1.3. Fenster mit Rollbalken
  4153.  
  4154. Rollbalken sind Elemente, die sich genauso wie der Rahmen
  4155. oder der Hintergrund bei Bedarf in die Liste der Fensterele-
  4156. mente einfügen lassen. Der Hintergrundbereich des Fensters
  4157. wird dann nicht mehr durch ein TBackground-Objekt bestimmt,
  4158. sondern durch ein TScroller-Objekt. Das TScroller-Objekt
  4159. kann auf Ereignisse reagieren, welche die Rollbalken abset-
  4160. zen. Als Programmierer müssen Sie lediglich festlegen, wie
  4161. das TScroller-Objekt auf diese Ereignisse reagieren soll.
  4162. Bevor wir näher auf den Mechanismus eingehen, möchte ich Ih-
  4163. nen folgenden kleinen Quelltextlister vorstelle:
  4164.  
  4165. program Lister;
  4166.  
  4167. uses WApp,
  4168.      WEvent,
  4169.      WDecl,
  4170.      WViews,
  4171.      WDriver,
  4172.      WDlg,
  4173.      graph;
  4174.  
  4175. const cmList = 101;
  4176.  
  4177. type TApplication=object(TApp)
  4178.        procedure InitMenuBar; virtual;
  4179.        procedure HandleEvent; virtual;
  4180.        procedure NewWindow;
  4181.      end;
  4182.  
  4183.      PNewScroller=^TNewScroller;
  4184.  
  4185.      PScrollWindow=^TScrollWindow;
  4186.      TScrollWindow=object(TWindow)
  4187.        Scroller:PNewScroller;
  4188.        procedure InitWindowScroller; virtual;
  4189.        destructor Done; virtual;
  4190.      end;
  4191.  
  4192.  
  4193.  
  4194. Programmierhandbuch                                 WG-Vision - 70 -
  4195.  
  4196.  
  4197.  
  4198.  
  4199.  
  4200.  
  4201.  
  4202.      TNewScroller=object(TScroller)                     {Scroll-Bereich}
  4203.        procedure CreateData;    {Daten bereitstellen (hier Textstrings)}
  4204.        procedure ScrollDraw; virtual;         {Scrollbereich darstellen}
  4205.      end;
  4206.  
  4207.  
  4208. var MyApp:TApplication;
  4209.  
  4210. procedure TApplication.InitMenuBar;
  4211. begin
  4212.   MainMenu('~F~enster',0);
  4213.    SubMenu('~Q~elltext-Lister',cmList,0,0,false,false);
  4214.    SubMenu('E~x~it  Alt-X',cmCloseApplication,0,altX,false,false);
  4215. end;
  4216.  
  4217. procedure TApplication.HandleEvent;
  4218. begin
  4219.   Heap^.ShowHeapStatus(523,8,White);
  4220.   TProgram.HandleEvent;
  4221.   case Event.Command of
  4222.    cmList : NewWindow;
  4223.   end; {case}
  4224. end;
  4225.  
  4226. procedure TApplication.NewWindow;
  4227. var R:TRect;
  4228.     Window:PScrollWindow;
  4229. begin
  4230.   R.Assign(60,80,440,280);
  4231.   Window:=new(PScrollWindow, Init(R,'ScrollWindow / Quelltext-Lister',
  4232.               winDouble+winPanel+winMenu+winKey));
  4233.   InsertDesktop(Window);
  4234. end;
  4235.  
  4236.  
  4237.  
  4238.  
  4239.  
  4240.  
  4241.  
  4242.  
  4243.  
  4244. Programmierhandbuch                                 WG-Vision - 71 -
  4245.  
  4246.  
  4247.  
  4248.  
  4249.  
  4250.  
  4251.  
  4252. {Implementation TScrollWindow}
  4253.  
  4254. procedure TScrollWindow.InitWindowScroller;
  4255. var R:TRect;
  4256.     SBH1,SBV1:PScrollBar;
  4257. begin
  4258.   R:=Frame^.Area;
  4259.   SBH1:=new(PScrollBar, Init(R,HorizDir));     {horizontaler Rollbalken}
  4260.   SBV1:=new(PScrollBar, Init(R,VertDir));        {vertikaler Rollbalken}
  4261.   Scroller:=new(PNewScroller, Init(R,SBH1,SBV1));      {Scroller-Objekt}
  4262.   Scroller^.CreateData;            {Daten für die Anzeige bereitstellen}
  4263.   List^.InsertItem(Scroller);               {und jetzt in List einfügen}
  4264. end;
  4265.  
  4266. destructor TScrollWindow.Done;
  4267. begin
  4268.   TWindow.Done;          {natürlich muß jetzt auch der Scroller aus dem}
  4269.   dispose(Scroller, Done);                           {Heap verschwinden}
  4270. end;
  4271.  
  4272. {Implementation TNewScroller}
  4273.  
  4274. Mit dieser Prozedur werden die Zeilen des Quelltextes von LIST.PAS in
  4275. die Struktur TLine eingelesen, die nichts anderes als eine Pointerliste
  4276. darstellt. Ein Nachteil dieser Methode ist, daß mit dem Text der Heap
  4277. belastet wird, was nicht immer gut sein muß. Aber letztendlich bleibt es
  4278. ja dem Programmierer überlassen, wie er seinem Rollfenster die Daten
  4279. überläßt. Im Abschnitt über den EMS zeige ich Ihnen eine Möglichkeit,
  4280. wie Sie Texte im Expanded Memory ablegen können,
  4281.  
  4282. procedure TNewScroller.CreateData;
  4283. var dat:text;
  4284.     LfdPtr:PLine;
  4285. begin
  4286.   assign(dat,'B:LIST.PAS');
  4287.   reset(dat);
  4288.   while not EOF(dat) do
  4289.    begin
  4290.      LfdPtr:=new(PLine, Init);
  4291.  
  4292.  
  4293.  
  4294. Programmierhandbuch                                 WG-Vision - 72 -
  4295.  
  4296.  
  4297.  
  4298.  
  4299.  
  4300.  
  4301.  
  4302.      readln(dat,LfdPtr^.Eintrag);
  4303.      Liste^.InsertItem(LfdPtr); {rein in die bereits vorbereitete Liste}
  4304.    end;
  4305.   SetLimit(25,Liste^.AnzElem-1,8,16);  {sehr wichtig ! --> Beschreibung}
  4306. end;
  4307.  
  4308. Draw-Bereich aktualisieren. Diese Methode erhält ihre Informationen
  4309. direkt von den Rollbalken (Delta.y, WDelta.y, Delta.x, Zeilen).
  4310.  
  4311. procedure TNewScroller.ScrollDraw;
  4312. var i:integer;
  4313.     LfdPtr:PGroup;
  4314.  
  4315. function clip(p,n:byte;z:string):string; {Zeile so zusammenstutzen, daß}
  4316. begin                                          {sie in das Fenster paßt}
  4317.   clip:=copy(z,p,n);
  4318. end;
  4319.  
  4320. begin
  4321.   Mouse.HideMouse;
  4322.   with Border do
  4323.    begin
  4324.      SetFillStyle(SolidFill,GetPalColor(1));
  4325.      SetColor(GetPalColor(2));
  4326.      for i:=Delta.y to WDelta.y do
  4327.       begin
  4328.         LfdPtr:=Liste^.GetItems(i); {i-te Zeile aus der Textliste holen}
  4329.         Bar(A.x,A.y+(i-Delta.y)*Py+10,B.x,A.y+(i-Delta.y)*Py+10+Py);
  4330.         OutTextXY(A.x+20,A.y+(i-Delta.y)*Py+10,clip(Delta.x,
  4331.                   Spalten*8 div 8-5,PLine(LfdPtr)^.Eintrag));
  4332.       end;
  4333.      if VertiScrollBar<>nil then
  4334.       for i:=(WDelta.y-Delta.y)+1 to Zeilen do
  4335.        Bar(A.x,A.y+i*Py+10,B.x,A.y+i*Py+10+Py);
  4336.    end;
  4337.   Mouse.ShowMouse;
  4338. end;
  4339.  
  4340.  
  4341.  
  4342.  
  4343.  
  4344. Programmierhandbuch                                 WG-Vision - 73 -
  4345.  
  4346.  
  4347.  
  4348.  
  4349.  
  4350.  
  4351.  
  4352. {Hauptprogramm}
  4353.  
  4354. begin
  4355.   MyApp.Init('Beispiel :  LISTER');
  4356.   MyApp.Run;
  4357.   MyApp.Done;
  4358. end.
  4359.  
  4360. - Fenster mit Rollbalken ausstatten
  4361.  
  4362. Das Objekt TWindow soll um die Fähigkeit, Rollbalken darzu-
  4363. stellen und zu verwalten, erweitert werden. Dazu müssen Sie
  4364. auf der Grundlage von TWindow ein neues Objekt erzeugen und
  4365. die virtuelle Methode InitWindowScroller überschreiben.
  4366. Außerdem benötigen Sie noch ein TScroller-Objekt, da Sie ja
  4367. irgendetwas im Fenster darstellen wollen:
  4368.  
  4369. PScrollWindow=^TScrollWindow;
  4370. TScrollWindow=object(TWindow)
  4371.   Scroller:PNewScroller;
  4372.   procedure InitWindowScroller; virtual;
  4373.   destructor Done; virtual;
  4374. end;
  4375.  
  4376. Der Scroller ist der Bereich auf dem Bildschirm, der sich
  4377. innerhalb der Rollbalken befindet. Die wesentlichsten Felder
  4378. dieses Objekts sind:
  4379.  
  4380. HorizScrollBar   Zeiger auf einen horizontalen Rollbalken
  4381.  
  4382. VertiScrollBar   Zeiger auf einen vertikalen Rollbalken
  4383.  
  4384. Delta,WDelta     relative Position des Scrollobjekts in
  4385.                  bezug (TPoint) auf die Einstellung der
  4386.                  Rollbalken
  4387.  
  4388. Limit (TPoint)   Ausmaße des im Scroller sichtbaren Daten-
  4389.                  bereichs in Zeilen (Limit.x) und Spalten
  4390.                  (Limit.y)
  4391.  
  4392.  
  4393.  
  4394. Programmierhandbuch                                 WG-Vision - 74 -
  4395.  
  4396.  
  4397.  
  4398.  
  4399.  
  4400.  
  4401.  
  4402. Px,Py            Anzahl der Pixel, die jeweils einer Zeilen-
  4403.                  und Spaltenbreite entsprechen
  4404.  
  4405. Zeilen           Anzahl der Zeilen im Scrollfenster
  4406.  
  4407. Spalten          Anzahl der Spalten im Scrollfenster
  4408.  
  4409. Liste            verkette Liste, welche Strings aufnehmen
  4410.                  kann
  4411.  
  4412. Für den Programmierer ist nur die Methode SetLimit wichtig.
  4413. Die anderen Felder, welche sich auf die momentane Lage des
  4414. Scrollbereiches beziehen, werden innerhalb des Eventhandlers
  4415. von TScroller durch die Rollbalken bedient. Jede Änderung
  4416. der Rollbalkenposition führt damit automatisch zu einer
  4417. neuen Anzeige des Scrollers (TScroller.Draw) mit ent-
  4418. sprechend verschobenen Datenausschnitt. Wie sieht das nun
  4419. konkret aus. Im Eventhandler von TScroller werden als Erstes
  4420. die Eventhandler der Rollbalken abgearbeitet. Im Normalfall
  4421. passiert dabei nichts bis ein Rollbalken verändert wird. In
  4422. diesem Fall wird das interne Kommando cmScrollBarChanged
  4423. gesendet und außerdem das Feld Event.Info mit einer
  4424. Identifikationsnummer gefüllt, welches dem Eventhandler von
  4425. TScroller erlaubt, die Werte Delta und WDelta den neuen
  4426. Gegebenheiten anzupassen. Anschließend wird die Draw-Methode
  4427. aufgerufen, wodurch der Inhalt des Scrollfensters
  4428. aktualisiert wird.
  4429. Das ist jedoch noch lange nicht alles, was das TScroller-
  4430. Objekt können muß um richtig zu funktionieren. Da sich auch
  4431. skalierbare Fenster mit Scrollbalken versehen lassen, muß es
  4432. natürlich auch auf Änderungen der Fenstergröße reagieren.
  4433. Das führt zu einigen sehr komplizierten Programmabläufen,
  4434. auf die hier aus verständlichen Gründen nicht näher einge-
  4435. gangen werden kann (ich möchte es nicht verhelen, selbst der
  4436. Autor brauchte eine ganze Weile, bis er die Funktionsweise
  4437. wieder verstanden hat. Die Scrollbalkengeschichte hat ihm
  4438. nicht umsonst einige Wochen Arbeit gekostet ...).
  4439.  
  4440.  
  4441.  
  4442.  
  4443.  
  4444. Programmierhandbuch                                 WG-Vision - 75 -
  4445.  
  4446.  
  4447.  
  4448.  
  4449.  
  4450.  
  4451.  
  4452. - Rollbalken einbauen und Scroller initialisieren
  4453.  
  4454. procedure TScrollWindow.InitWindowScroller;
  4455. var R:TRect;
  4456.     SBH1,SBV1:PScrollBar;
  4457. begin
  4458.   R:=Frame^.Area;
  4459.   SBH1:=new(PScrollBar, Init(R,HorizDir));
  4460.   SBV1:=new(PScrollBar, Init(R,VertDir));
  4461.   Scroller:=new(PNewScroller, Init(R,SBH1,SBV1));
  4462.   Scroller^.CreateData;
  4463.   List^.InsertItem(Scroller);
  4464. end;
  4465.  
  4466. TScrollBar ist der eigentliche Rollbalken. Er tritt in zwei
  4467. Formen auf, als horizontaler und als vertikaler Rollbalken.
  4468. Seine Position wird durch das Rechteck R festgelegt. Die
  4469. linke untere Ecke des horizontalen Rollbalken hat z.B. die
  4470. Koordinaten R.A.x und R.B.y.
  4471. In unserem Beispiel schmiegen sich die Rollbalken unten und
  4472. rechts an den Innenrahmen des Fensters. Es steht nichts im
  4473. Wege, die Rollbalken beliebig im Fenster zu positionieren.
  4474. Sie müssen dazu nur R entsprechend verändern. Erlaubt ist
  4475. das jedoch nur bei Windows, deren Größe sich nicht ändern
  4476. läßt und die sich nicht verschieben lassen. Das sind alle
  4477. Windows ohne Resize-Schalter und bei denen die Variable
  4478. DragMode auf dmNoMove gesetzt ist:
  4479.  
  4480. procedure TApplication.NewWindow;
  4481. var R:TRect;
  4482.     Window:PScrollWindow;
  4483.     x,y:integer;
  4484. begin
  4485.   R.Assign(60,80,540,380);
  4486.   Window:=new(PScrollWindow, Init(R,'ScrollWindow / Quelltext-
  4487.               Lister',winDouble+winPanel+winMenu));
  4488.   with Window^ do Frame^.DragMode:=dmNoMove;
  4489.   InsertDesktop(Window);
  4490. end;
  4491.  
  4492.  
  4493.  
  4494. Programmierhandbuch                                 WG-Vision - 76 -
  4495.  
  4496.  
  4497.  
  4498.  
  4499.  
  4500.  
  4501.  
  4502. ...
  4503.  
  4504. procedure TScrollWindow.InitWindowScroller;
  4505. var R:TRect;
  4506.     SBH1,SBV1:PScrollBar;
  4507. begin
  4508.   R:=Frame^.Area;       {Größe des Bereichs innerhalb des Rahmens holen}
  4509.   R.Grow(-120,-30);                                       {Größe ändern}
  4510.   R.Move(30,15);                                           {Verschieben}
  4511.   SBH1:=new(PScrollBar, Init(R,HorizDir));         {Rollbalken einbauen}
  4512.   SBV1:=new(PScrollBar, Init(R,VertDir));
  4513.   Scroller:=new(PNewScroller, Init(R,SBH1,SBV1));  {Scroller initialis.}
  4514.   Scroller^.CreateData;                            {Daten bereitstellen}
  4515.   List^.InsertItem(Scroller);                             {und einbauen}
  4516. end;
  4517.  
  4518. 5.1.3.1. Farbgestaltung der Rollbalken und des Scrollbereichs
  4519.  
  4520. Die farbliche Gestaltung der Rollbalken und des Scrollerbe-
  4521. reichs erfolgt wieder bequem über die Manipulation der dazu-
  4522. gehörigen Palette.
  4523. Standardmäßig ist Palette3 für Rollbalken und Scroller zu-
  4524. ständig. Sie wird bereits bei der Initialisierung dieser Ob-
  4525. jekte geladen.
  4526.  
  4527. Palettenlayout
  4528.  
  4529. Eintrag      Bedeutung                       Standard
  4530.  
  4531.    1         Hintergrund Scrollbereich       #15  Weiß
  4532.    2         Schriftfarbe Scroller           #0   Schwarz
  4533.    3         Tastenfarbe                     #7   Hellgrau
  4534.    4         Balkenfarbe (Gray50)            #7   Hellgrau
  4535.    5         Randfarbe Taste                 #15  Weiß
  4536.    6         Begrenzungslinien               #0   Schwarz
  4537.    7         Pfeile                          #8   Dunkelgrau
  4538.  
  4539.  
  4540.  
  4541.  
  4542.  
  4543.  
  4544. Programmierhandbuch                                 WG-Vision - 77 -
  4545.  
  4546.  
  4547.  
  4548.  
  4549.  
  4550.  
  4551.  
  4552. Beispiel
  4553.  
  4554. ...
  4555.  
  4556. SBH1:=new(PScrollBar, Init(R,HorizDir));
  4557. SBV1:=new(PScrollBar, Init(R,VertDir));
  4558. with SBH1^ do
  4559.  begin
  4560.    Palette[3]:=#2;
  4561.    Palette[4]:=#14;
  4562.    Palette[5]:=#14;
  4563.    Palette[7]:=#4;
  4564.  end;
  4565. with SBV1^ do
  4566.  begin
  4567.    Palette[3]:=#2;
  4568.    Palette[4]:=#14;
  4569.    Palette[5]:=#14;
  4570.    Palette[7]:=#4;
  4571.  end;
  4572. Scroller:=new(PNewScroller, Init(R,SBH1,SBV1));
  4573. Scroller^.CreateData;
  4574. Scroller^.Palette[1]:=#11;    {muß mit Fensterhintergrund harmonieren !}
  4575. List^.InsertItem(Scroller);
  4576. ...
  4577.  
  4578. 5.1.3.2. Programmierung des Scrollers
  4579.  
  4580. Der Scroller ist gewissermaßen das Fenster, durch das man
  4581. ein Teil eines größeren Datenbereiches betrachten kann. Es
  4582. ist allein für den Inhalt des Scrollbereiches zuständig und
  4583. muß vom Programmierer für die jeweilige Aufgabe angepaßt
  4584. werden. Zwei Methoden, CreateData und ScrollDraw stehen da-
  4585. für zur Verfügung.
  4586. In unserem Beispiel werden alle Zeilen des Quelltextes von
  4587. LIST.PAS in eine Liste, deren Elemente durch Objekte vom Typ
  4588. TLine repräsentiert werden, übertragen. Diese Liste wird im
  4589. Heap angelegt. Was Sie konkret in diese Liste einlesen,
  4590. hängt davon ab, was für Texte Sie auf den Bildschirm dar-
  4591.  
  4592.  
  4593.  
  4594. Programmierhandbuch                                 WG-Vision - 78 -
  4595.  
  4596.  
  4597.  
  4598.  
  4599.  
  4600.  
  4601.  
  4602. stellen wollen. Um z.B. alle Dateien im aktuellen Verzeich-
  4603. nis aufzulisten, müssen Sie CreateData folgendermaßen
  4604. implementieren:
  4605.  
  4606. procedure TNewScroller.CreateData;
  4607. var SRec:SearchRec;
  4608.     LfdPtr:PLine;
  4609. begin
  4610.   FindFirst('*.*',Archive,SRec);
  4611.   if SRec.Name<>'' then
  4612.    repeat
  4613.      LfdPtr:=new(PLine, Init);
  4614.      LfdPtr^.Eintrag:=SRec.Name;
  4615.      Liste^.InsertItem(LfdPtr);
  4616.      FindNext(SRec);
  4617.    until DOSError=18;
  4618.   SetLimit(12,Liste^.AnzElem-1,CharLength,CharHeight);
  4619. end;
  4620.  
  4621. Da die Dateinamen maximal eine Länge von 12 Zeichen
  4622. aufweisen, lohnt sich ein horizontaler Rollbalken nicht.
  4623. Deshalb setzen Sie ihn bei der Implementation einfach auf
  4624. nil:
  4625.  
  4626. Scroller:=new(PNewScroller, Init(R,nil,SBV1));
  4627.                                     │
  4628.                                     └─ horiz. Rollbalken
  4629.  
  4630. Sehr wichtig ist die Methode
  4631.  
  4632. SetLimit(x,y,Pxx,Pyy:integer)
  4633.  
  4634. Sie legt die horizontale und die vertikale Schrittweite bei
  4635. einem Scrollschritt fest.
  4636.  
  4637. x    horizontale Ausdehnung des Datenobjekts (Länge der
  4638.      Zeichenkette)
  4639.  
  4640.  
  4641.  
  4642.  
  4643.  
  4644. Programmierhandbuch                                 WG-Vision - 79 -
  4645.  
  4646.  
  4647.  
  4648.  
  4649.  
  4650.  
  4651.  
  4652. y    vertikale Ausdehnung des Datenobjekts = Anzahl der
  4653.      Elemente in der Liste
  4654.  
  4655. Pxx  horizontale Schrittweite = Buchstabenbreite (+Offset)
  4656.  
  4657. Pyy  vertikale Schrittweite   = Buchstabenhöhe   (+Offset)
  4658.  
  4659. Die Darstellung der Daten im Scrollbereich erfolgt mittels
  4660. der virtuellen Methode ScrollDraw:
  4661.  
  4662. procedure TNewScroller.ScrollDraw;
  4663. var i:integer;
  4664.     LfdPtr:PGroup;
  4665.  
  4666. function clip(p,n:byte;z:string):string;         { --> A }
  4667. begin
  4668.   clip:=copy(z,p,n);
  4669. end;
  4670.  
  4671. begin
  4672.   Mouse.HideMouse;
  4673.   with Border do
  4674.    begin
  4675.      SetFillStyle(SolidFill,GetPalColor(1));
  4676.      SetColor(GetPalColor(2));
  4677.      for i:=Delta.y to WDelta.y do
  4678.       begin
  4679.         LfdPtr:=Liste^.GetItems(i);
  4680.         Bar(A.x,A.y+(i-Delta.y)*Py+10,B.x,A.y+(i-Delta.y)*Py+10+Py);
  4681.         OutTextXY(A.x+20,A.y+(i-Delta.y)*Py+10,clip(Delta.x,
  4682.                   Spalten*8 div 8-5,PLine(LfdPtr)^.Eintrag));
  4683.       end;
  4684.      if VertiScrollBar<>nil then
  4685.       for i:=(WDelta.y-Delta.y)+1 to Zeilen do
  4686.        Bar(A.x,A.y+i*Py+10,B.x,A.y+i*Py+10+Py);
  4687.    end;
  4688.   Mouse.ShowMouse;
  4689. end;
  4690.  
  4691.  
  4692.  
  4693.  
  4694. Programmierhandbuch                                 WG-Vision - 80 -
  4695.  
  4696.  
  4697.  
  4698.  
  4699.  
  4700.  
  4701.  
  4702. Die Hilfsfunktion clip dient der Anpassung der darzustellen-
  4703. den Zeichenkette an den horizontalen Fensterbereich. {-->A}
  4704. Delta.y und WDelta.y werden bei Betätigung eines Rollbalkens
  4705. jeweils aktualisiert. Danach erfolgt ein Kommando (cmScroll-
  4706. BarChanged), welches dazu führt, daß der Eventhandler des
  4707. Scroller die Methode ScrallDraw aufruft und damit den
  4708. Scrollbereich neu darstellt.
  4709.  
  4710. 5.1.3.3. Bedienung des Rollbalkens mit der Tastatur
  4711.  
  4712. Wenn die Taste ScrollLock (Rollen) eingeschaltet ist, können
  4713. Sie mit den Kursortasten den Rollbalken bedienen. <PgUp> und
  4714. <PgDn> sind in der vorliegenden Version von WG-Vision noch
  4715. nicht implementiert. Es ist aber möglich, den Eventhandler
  4716. von TScroller zu überschreiben und weitere Funktionen
  4717. einzubauen.
  4718.  
  4719. 5.1.3.4. Verwendung der Sonderzeichensätze
  4720.  
  4721. In der Unit WText sind z.Z. 6 Sonderzeichensätze enthalten,
  4722. die Sie in den 16-Farben-Modi der Klassenbibliothek verwen-
  4723. den können. Arbeiten Sie mit 256 Farben, dann passiert auch
  4724. nicht viel. Die Toolbox verwendet in diesem Fall wieder den
  4725. normalen 8x16 Zeichensatz via OutTextXY.
  4726. Wenn Sie jedoch mit diesen Zusatzzeichensätzen arbeiten wol-
  4727. len, dann müssen Sie die Prozedur OutTextXY durch WriteText
  4728. ersetzen. Standardmäßig wird der Zeichensatz Wndw19 verwen-
  4729. det. Der eigentliche Vorteil dieser Zeichensätze liegt in
  4730. ihrer Schreibgeschwindigkeit. Die Prozedur WriteText ist die
  4731. einzige Stelle in WG-Vision, wo ich von meinem Vorsatz, kei-
  4732. nen Assembler zu verwenden, abgewichen bin.
  4733. Um den aktiven Zeichensatz zu wechseln, müssen Sie den Be-
  4734. fehl
  4735.  
  4736. SetFont(<Bezeichner>)
  4737.  
  4738. in den Quelltext einfügen.
  4739.  
  4740.  
  4741.  
  4742.  
  4743.  
  4744. Programmierhandbuch                                 WG-Vision - 81 -
  4745.  
  4746.  
  4747.  
  4748.  
  4749.  
  4750.  
  4751.  
  4752. Folgende Bezeichner können Sie verwenden. Die dazugehörigen
  4753. Zeichensätze liegen als OBJ-Dateien WG-Vision bei:
  4754.  
  4755. Thin8 / Thin14 / Thin16 / Brdwy19 / Wndw19 / Sans19 / VGAF
  4756.  
  4757. VGAF ist der VGA-Standardzeichensatz von Turbo/Borland -
  4758. Pascal.
  4759.  
  4760. Beispiel
  4761.  
  4762. procedure TNewScroller.ScrollDraw;
  4763. ...
  4764.  
  4765. begin
  4766.   SetFont(Brdwy19);                       {Neuen Zeichensatz aktivieren}
  4767.   ...
  4768.   {statt OutTextXY}
  4769.   WriteText(...)
  4770.   ...
  4771.  
  4772. end;
  4773.  
  4774. Um die Parameter CharLength und CharHeight in der Methode
  4775. SetLimit brauchen Sie sich nicht zu kümmern. Sie werden beim
  4776. Laden des Zusatzzeichensatzes automatisch auf die richtigen
  4777. Werte gesetzt.
  4778.  
  4779.  
  4780.  
  4781.  
  4782.  
  4783.  
  4784.  
  4785.  
  4786.  
  4787.  
  4788.  
  4789.  
  4790.  
  4791.  
  4792.  
  4793.  
  4794. Programmierhandbuch                                 WG-Vision - 82 -
  4795.  
  4796.  
  4797.  
  4798.  
  4799.  
  4800.  
  4801.  
  4802. 5.1.3.5. Grafiken in einem Scrollfenster darstellen
  4803.  
  4804. Das folgende Beispiel zeigt, wie man in einem Scrollfenster
  4805. ein PCX-Bild aufblenden kann. Dieses Beispiel hat vorerst
  4806. nur akademisches Interesse, da in einem realen Anwendungs-
  4807. fall auch die Routinen, welche das Bild letztendlich auf dem
  4808. Bildschirm bringen, angepaßt werden müssen. In diesem Bei-
  4809. spiel verwenden wir die Unit WPCX (Achtung ! --> funktio-
  4810. niert nur im VGA-Standardmodus mit 16 Farben, da diese Unit
  4811. direkt in den Bildwiederholspeicher schreibt !), welche aber
  4812. immerhin schon erlaubt, ein Bild in y-Richtung zu verschie-
  4813. ben (Parameter AddY in der Methode LoadPCXImage). Auf einen
  4814. Nachteil möchte ich schon hier hinweisen. Bei jedem Scroll-
  4815. vorgang wird das Bild neu von der Festplatte geladen, ein
  4816. Fakt, den man in einem realen Malprogramm natürlich umgehen
  4817. muß. In einem solchen Anwendungsfall sollte man das Bild
  4818. vollständig in einen Puffer (Heap oder EMS) laden und auf
  4819. dessen Grundlage eine geeignete Aufblend-Methode entwickeln.
  4820. In unserem Beispiel kommen wir mit einem Rollbalken aus, da
  4821. wir das Bild aus den genannten Einschränkungen heraus sowie-
  4822. so nur vertikal verschieben können:
  4823.  
  4824. {Implementation TScrollWindow}
  4825.  
  4826. procedure TScrollWindow.InitWindowScroller;
  4827. var R:TRect;
  4828.     SBV1:PScrollBar;
  4829. begin
  4830.   R:=Frame^.Area;
  4831.   SBV1:=new(PScrollBar, Init(R,VertDir));
  4832.   Scroller:=new(PNewScroller, Init(R,nil,SBV1));
  4833.   Scroller^.CreateData;              {└─ wir benötigen nur einen}
  4834.                                           {vertikalen Rollbalken}
  4835.   List^.InsertItem(Scroller);
  4836. end;
  4837.  
  4838.  
  4839.  
  4840.  
  4841.  
  4842.  
  4843.  
  4844. Programmierhandbuch                                 WG-Vision - 83 -
  4845.  
  4846.  
  4847.  
  4848.  
  4849.  
  4850.  
  4851.  
  4852. destructor TScrollWindow.Done;
  4853. begin
  4854.   TWindow.Done;
  4855.   dispose(Scroller, Done);
  4856. end;
  4857.  
  4858. {Implementation TNewScroller}
  4859.  
  4860. {In die Typdeklaration des Objekt TNewScroller muß als neues Feld eine
  4861. Instanz von TPCXImage eingefügt werden: Image : TPCXImage}
  4862.  
  4863. procedure TNewScroller.CreateData;
  4864. begin
  4865.   Image.Init(Border,'WETT.PCX');  {TPCXImage-Objekt Bild initialisieren}
  4866.   SetLimit(640,480 div 16,8,16);
  4867. end;
  4868.  
  4869. SetLimit bewirkt, daß ein Rollschritt genau 16 Pixel umfaßt. Wenn Sie
  4870. möchten, können Sie diesen Parameter auch ändern. Die Werte für die x-
  4871. Richtung sind ohne Bedeutung. Sie dürfen aber nicht auf Null gesetzt
  4872. werden, weil es sonst innerhalb der Toolbox zum berühmten Division by
  4873. Zero -Fehler kommt. Das 640x480 die Größe des zu ladenden Bildes ist,
  4874. dürfte wohl klar sein.
  4875.  
  4876. procedure TNewScroller.ScrollDraw;
  4877. var i:integer;
  4878.     LfdPtr:PGroup;
  4879.  
  4880. begin
  4881.   Mouse.HideMouse;
  4882.   with Border do
  4883.    begin
  4884.      Image.T:=Border;            {aktuelle Bildgröße an den Rahmen des}
  4885.      Image.T.Move(-4,0);        {Scrollfensters anpassen und Korrektur}
  4886.      Image.LoadPCXImage(Delta.y);  {PCX-Bild um Delta.y versetzt laden}
  4887.    end;
  4888.   Mouse.ShowMouse;
  4889. end;
  4890.  
  4891.  
  4892.  
  4893.  
  4894. Programmierhandbuch                                 WG-Vision - 84 -
  4895.  
  4896.  
  4897.  
  4898.  
  4899.  
  4900.  
  4901.  
  4902. Dadurch, daß die Routinen innerhalb der Unit WPCX direkt in
  4903. den Bildwiederholspeicher schreiben, kann ein PCX-Bild nur
  4904. entlang von Scanlines, die um jeweils 4 Pixel versetzt in x-
  4905. Richtung angeordnet sind, gezeichnet werden. Da sich das
  4906. Scrollfenster aber pixelgenau verschieben läßt, kann es zu
  4907. Versetzungen des PCX-Bildes innerhalb des Scrollbereiches
  4908. kommen. Das macht sich an einem schmalen Rand bemerkbar. Da-
  4909. mit u.U. nicht ein Teil des Rollbalkens überschrieben wird,
  4910. erfolgt mit T.Move(-4,0) eine kleine Korrektur. T ist inner-
  4911. halb des TPCXImage-Objekts der Bildschirm-Bereich, in wel-
  4912. ches das PCX-Bild linksbündig gezeichnet wird.
  4913.  
  4914.  
  4915.  
  4916.  
  4917.  
  4918.  
  4919.  
  4920.  
  4921.  
  4922.  
  4923.  
  4924.  
  4925.  
  4926.  
  4927.  
  4928.  
  4929.  
  4930.  
  4931.  
  4932.  
  4933.  
  4934.  
  4935.  
  4936.  
  4937.  
  4938.  
  4939.  
  4940.  
  4941.  
  4942.  
  4943.  
  4944. Programmierhandbuch                                 WG-Vision - 85 -
  4945.  
  4946.  
  4947.  
  4948.  
  4949.  
  4950.  
  4951.  
  4952. 5.2. Programmierung von Dialogen
  4953.  
  4954. Dialogfenster dienen der Kommunikation zwischen dem Nutzer
  4955. des Programms und dem Programm selbst. Sie enthalten in der
  4956. Regel verschiedene Eingabefelder, Buttons zur Programmsteue-
  4957. rung oder auch Bereiche, wo Informationen dargestellt wer-
  4958. den. Kurz gesagt, ein Dialogfenster ist ein spezialisiertes
  4959. Fensterobjekt, mit dessen Hilfe Sie dem Programm Daten und
  4960. Informationen übermitteln können, die es zu einer fehler-
  4961. freien Ausführung benötigt.
  4962. Es hat sich bewährt, daß man im Menü einer Applikation dem
  4963. Menüpunkt, welcher ein Dialogfenster öffnet, immer drei
  4964. Punkte nachstellt (z.B. Optionen ...). Auf diese Weise wird
  4965. der Nutzer vorgewarnt, daß u.U. jetzt noch einige Eingaben
  4966. folgen.
  4967. Ein Dialogfenster ist ein direkter Nachkomme von TWindow und
  4968. erbt damit alle seine Eigenschaften. Lediglich eine Skalie-
  4969. rung ist nicht mehr möglich weil auch nicht sinnvoll. Außer-
  4970. dem wird ein Dialogfenster immer modal dargestellt, d.h.
  4971. nach dem Aufblenden einer Dialogbox werden alle anderen auf
  4972. dem Bildschirm aktiven Elemente (einschließlich Menü) deak-
  4973. tiviert.
  4974. Dialogboxen können weitere Fenster, sogenannte Childfenster,
  4975. enthalten. Dabei gilt folgende Regel: In ein Dialogfenster
  4976. lassen sich beliebig viele Childfenster implementieren. Zu
  4977. einem konkreten Zeitpunkt darf jedoch nur eines davon aktiv
  4978. sein. Ein Childfenster darf kein weiteres Fenster aufblenden
  4979. (in diesem Fall wäre der Eventhandler des TApp-Objekts maß-
  4980. los überfordert und es würde zu Fehlern kommen. Vielleicht
  4981. baue ich mir einmal in einer ruhigen Minute einen rekursiven
  4982. Algorithmus zusammen, der eine Liste der Form Dialogfenster
  4983. - Childfenster - Child-Childfenster etc. verdauen kann. Nur
  4984. ist die Sache leider nicht trivial ...).
  4985. In ein Dialogfenster lassen sich in beliebiger Anzahl und
  4986. Reihenfolge aktive und passive Dialogelemente einbauen. WG-
  4987. Vision unterstützt in der vorliegenden Version folgende Dia-
  4988. logelemente:
  4989.  
  4990.  
  4991.  
  4992.  
  4993.  
  4994. Programmierhandbuch                                 WG-Vision - 86 -
  4995.  
  4996.  
  4997.  
  4998.  
  4999.  
  5000.  
  5001.  
  5002. Element                   Objekt          Typ      Bemerkung
  5003.  
  5004. Drucktasten               TPushButton     passiv   kann Kommandos
  5005.                                                    absetzen
  5006. Optionsschaltflächen      TRadioButton    aktiv
  5007. Kontrollfelder            TCheckButton    aktiv
  5008. Textfelder                TInputLine      aktiv    Texteingabe
  5009. Numerische Eingabefelder  TNumButton      aktiv    Zälschalter mit
  5010.                                                    Eingebe
  5011. Listenfelder              TListBox        aktiv
  5012. Rollbalken                TScrollBar      aktiv
  5013.  
  5014. Gruppenrahmen             TGroupFrame     passiv
  5015. Sinnbilder (Icons)        TIcon           passiv   32x32 und 16x16 Icons
  5016. Statischer Text           TStaticText     passiv
  5017.  
  5018.  
  5019. Weitere Dialogelemente können bei Beachtung aller Konventio-
  5020. nen leicht programmiert werden (i.A. benötigen Sie dafür
  5021. aber die Quelltexte der Profi-Version).
  5022.  
  5023. 5.2.1. Pushbuttons (Drucktasten)
  5024.  
  5025. Pushbuttons haben die Eigenschaft, daß sie bei Betätigung
  5026. Kommandos absetzen, die im Feld Command des Event-Records
  5027. verpackt werden. Sie können innerhalb des Eventhandlers des
  5028. Dialogfensters oder auch außerhalb der Dialogbox von anderen
  5029. Objekten abgefangen werden. Das Standard-Kommando cmClose-
  5030. Window schließt z.B. das gerade aktive Fenster.
  5031.  
  5032.  
  5033.  
  5034.  
  5035.  
  5036.  
  5037.  
  5038.  
  5039.  
  5040.  
  5041.  
  5042.  
  5043.  
  5044. Programmierhandbuch                                 WG-Vision - 87 -
  5045.  
  5046.  
  5047.  
  5048.  
  5049.  
  5050.  
  5051.  
  5052. Beispiel
  5053.  
  5054. Dialogfenster mit drei Pushbuttons
  5055.  
  5056. procedure TApplication.DialogWindow;
  5057. var R:TRect;
  5058.     Window:PDlgWindow;
  5059. begin
  5060.   R.Assign(60,80,440,280);
  5061.   Window:=new(PDlgWindow, Init(R,'Dialogfenster',
  5062.               winDouble+winPanel+winMenu));
  5063.   with Window^ do
  5064.    begin
  5065.      SetPushButton(15,40,80,22,'OK',cmCloseWindow);
  5066.      SetPushButton(15,70,80,0,'#ICON.I32/1',cmNothing);
  5067.      SetPushButton(15,120,80,22,'Piep-Ton',99);
  5068.    end;                                    └─ modulinternes Kommando
  5069.   InsertDesktop(Window);
  5070. end;
  5071.  
  5072. Ein Dialogfenster leitet sich vom Objekt TDlgWindow ab. Die-
  5073. ses Objekt besitzt alle Eigenschaften, um die unter-
  5074. schiedlichsten Dialogelemente zu verwalten. In unserem
  5075. Beispiel werden drei Druckschalter implementiert, bei denen
  5076. nur das Erste eine Reaktion zeigt. Die anderen beiden sind
  5077. "Dummys", erkennbar am Kommando cmNothing. Das zweite Push-
  5078. buttons wurde an Stelle einer Beschriftung mit einem Icon
  5079. versehen. Die Schalterbreite kann in diesem Fall getrost auf
  5080. Null gesetzt werden, da sich das Pushbutton selbständig an
  5081. die Größe des Icons anpaßt. In diesem speziellen Fall ist
  5082. das ein Icon der Größe 32x32 Pixel (erkennbar an der Exten-
  5083. sion .I32). Icon werden in speziellen Icon-Dateien seriell
  5084. gespeichert. Die Zeichenkette "#ICON .I32/1" bedeutet, daß
  5085. die Draw-Methode des Pushbuttons die Icon-Datei ICON.I32
  5086. öffnen und daraus das 1.Icon laden soll.
  5087. Dialogelemente werden in der Reihenfolge ihrer Implementati-
  5088. on angesprochen (fokussiert). Ein fokussiertes Pushbutton
  5089. erkennen Sie an der breiten Umrandung. Den Fokussierzustand
  5090. können Sie entweder durch Anklicken mit der Maus oder durch
  5091.  
  5092.  
  5093.  
  5094. Programmierhandbuch                                 WG-Vision - 88 -
  5095.  
  5096.  
  5097.  
  5098.  
  5099.  
  5100.  
  5101.  
  5102. Betätigung der Tabulatator- bzw. Shift-Tabulatortaste än-
  5103. dern. Es ist selbstverständlich, daß sich neben dem Pushbut-
  5104. ton nur aktive und nicht gesperrte Dialogelemente
  5105. fokussieren lassen. Das "Anklicken" erfolgt über die Tasta-
  5106. tur mit der <Space>-Taste.
  5107.  
  5108. Syntax
  5109.  
  5110. SetPushButton(x,y,xl,yl:integer;Bez:str25;Kommando:word);
  5111.  
  5112. x,y       Position der linken oberen Ecke relativ zum
  5113.           Fenster (!)
  5114. xl,yl     Länge und Breite der Drucktaste
  5115. Bez       Bezeichner, wird standardmäßig zentriert in die
  5116.           Mitte der Drucktaste geschrieben. Wenn Sie Short-
  5117.           cuts zur Fokussierung verwenden möchten, müssen
  5118.           Sie den entsprechenden Buchstaben in Tilde-Zeichen
  5119.           einschließen.Drucktasten können auch mit einem
  5120.           Icon versehen werden. Dazu geben Sie als Be-
  5121.           zeichner den Dateinamen der Icondatei (mit Exten-
  5122.           sion) und dahinter, durch einen Schrägstrich ge-
  5123.           trennt, die Nummer des Icons an. Dem Dateinamen
  5124.           muß ein Doppelkreuz (#) vorangestellt werden.
  5125. Kommando  Wird bei Betätigung der Taste abgesetzt
  5126.  
  5127. Ein Dialogfenster, welches sich wie bei unserem Beispiel di-
  5128. rekt von TDlgWindow ableitet, ist in der Regel zu nichts zu
  5129. gebrauchen, weil es einfach nicht flexibel genug ist. Des-
  5130. halb immer einen Nachkommen von TDlgWindow erzeugen und ihn
  5131. mit den gewünschten Eigenschaften ausstatten.
  5132.  
  5133.  
  5134.  
  5135.  
  5136.  
  5137.  
  5138.  
  5139.  
  5140.  
  5141.  
  5142.  
  5143.  
  5144. Programmierhandbuch                                 WG-Vision - 89 -
  5145.  
  5146.  
  5147.  
  5148.  
  5149.  
  5150.  
  5151.  
  5152. Beispiel
  5153.  
  5154. Verbessertes Dialogfenster
  5155.  
  5156. type PNewDialog=^TNewDialog;
  5157.      TNewDialog=object(TDlgWindow)
  5158.       constructor Init(x,y:integer);
  5159.       procedure HandleEvent; virtual;
  5160.      end;
  5161.  
  5162. {Implementation TNewDialog}
  5163.  
  5164. constructor TNewDialog.Init(x,y:integer);
  5165. var RR:TRect;
  5166. begin
  5167.   RR.Assign(x,y,x+380,yy+200);
  5168.   TDlgWindow.Init(RR,'Dialogfenster',
  5169.               winDouble+winPanel+winMenu));
  5170.   SetPushButton(15,40,80,22,'OK',cmCloseWindow);
  5171.   SetPushButton(15,70,80,0,'#ICON.I32/1',cmNothing);
  5172.   SetPushButton(15,120,80,22,'Piep-Ton',99);
  5173. end;
  5174.  
  5175. procedure TNewDialog.HandleEvent;
  5176. begin
  5177.   TDlgWindow.HandleEvent;
  5178.   if Event.Command=99 then
  5179.    begin
  5180.      Beep(100);
  5181.      Event.Command:=cmNothing;
  5182.    end;
  5183. end;
  5184.  
  5185. Diese Dialogbox braucht jetzt nur noch in die Fensterliste
  5186. des Applikationsobjekts eingefügt werden:
  5187.  
  5188.  
  5189.  
  5190.  
  5191.  
  5192.  
  5193.  
  5194. Programmierhandbuch                                 WG-Vision - 90 -
  5195.  
  5196.  
  5197.  
  5198.  
  5199.  
  5200.  
  5201.  
  5202. procedure TApplication.DialogWindow;
  5203. var Window:PNewDialog;
  5204. begin
  5205.   Window:=new(PNewDialog, Init(60,80));
  5206.   InsertDesktop(Window);
  5207. end;
  5208.  
  5209. Dieses Beispiel zeigt in stark vereinfachter Form auch, wie
  5210. Ereignisse, die eine Dialogbox generiert, sofort verarbeitet
  5211. werden können. Immer dann, wenn Sie die Taste mit der Auf-
  5212. schrift "Piep-Ton" drücken, wird das Kommando "99" abgesetzt
  5213. (von TDlgWindow.HandleEvent). Dieses Kommando wird im Event-
  5214. handler der Dialogbox "herausgefischt" und daraufhin ein
  5215. Piep-Ton generiert. Zum Abschluß wird ein ordentlicher Pro-
  5216. grammierer Event.Command wieder auf cmNothing setzen.
  5217.  
  5218. 5.2.1.1. Farbgestaltung
  5219.  
  5220. Damit Sie bei Ihren Programmierversuchen nicht nur auf Ta-
  5221. sten in dezenten Mausgrau zurückgreifen müssen, wurde dem
  5222. TDlgWindow-Objekt die Methode ChangePalColor mitgegeben, mit
  5223. deren Hilfe sie die Farben der meisten Dialogelemente den
  5224. eigenen Wünschen anpassen können.
  5225. Den Pushbuttons wird die Farbpalette 4 (Palette4 in WView)
  5226. zugeordnet:
  5227.  
  5228. Eintrag       Bedeutung                  Standard
  5229.  
  5230.    1          Außenrahmen                #0   Schwarz
  5231.    2          Hintergrund                #15  Weiß
  5232.    3          Taste aktiv                #7   Hellgrau
  5233.    4          Taste, unten und rechts    #0   Schwarz
  5234.    5          Taste, inaktiv             #15  Weiß (Gray50)
  5235.    6          Beschriftung               #0   Schwarz
  5236.    7          Focus-Bereich              #0   Schwarz
  5237.    8          Fenster-Hintergrund        #15  Weiß
  5238.  
  5239. Die Änderung der Paletteneinträge erfolgt mit dem Befehl
  5240. ChangePalColor(Eintrag, Farbe:byte). Dieser Befehl bzw. eine
  5241.  
  5242.  
  5243.  
  5244. Programmierhandbuch                                 WG-Vision - 91 -
  5245.  
  5246.  
  5247.  
  5248.  
  5249.  
  5250.  
  5251.  
  5252. Folge von derartigen Befehlen muß sofort nach dem Befehl
  5253. SetPushButton implementiert werden (einrücken):
  5254.  
  5255. ...
  5256. SetPushButton(15,120,80,22,'Farbtest',cmNothing);
  5257.  ChangePalColor(3,Red);
  5258.  ChangePalColor(6,White);
  5259.  ChangePalColor(4,Blue);
  5260.  ChangePalColor(1,Blue);
  5261.  ChangePalColor(2,LightCyan);
  5262. SetPushButtons(15,160,80,22,'Fonts',cmNothing);
  5263.  ChangePalColor(3,Green);
  5264.  ChangePalColor(6,White)
  5265. ...
  5266.  
  5267. 5.2.1.2. Verändern der Textposition
  5268.  
  5269. Mit dem Befehl SetTextPosition können Sie die Lage des Be-
  5270. zeichners relativ zur Tastenmitte verändern:
  5271.  
  5272. ...
  5273. SetPushButton(150,40,80,22,'OK',cmCloseWindow);
  5274.  SetTextPosition(0,22);  {22 Pixel nach unten}
  5275. SetPushButton(150,120,80,0,'#ICON.I32/2',cmNothing);
  5276. ...
  5277.  
  5278. Hinweis:  Icons lassen sich nicht verschieben !
  5279.  
  5280.  
  5281.  
  5282.  
  5283.  
  5284.  
  5285.  
  5286.  
  5287.  
  5288.  
  5289.  
  5290.  
  5291.  
  5292.  
  5293.  
  5294. Programmierhandbuch                                 WG-Vision - 92 -
  5295.  
  5296.  
  5297.  
  5298.  
  5299.  
  5300.  
  5301.  
  5302. Komplexbeispiel  "Klavier-Simulator"
  5303.  
  5304. Das folgende Beispiel soll Ihnen zeigen, wie man sich sein
  5305. eigenes Tasteninstrument programmieren kann. Es ist gewis-
  5306. sermaßen eine minimale Minimalversion, die Sie, wenn Sie
  5307. Zeit haben, bis zu einer High-End-Soundblaster-Ansteuerungs-
  5308. software "auf-blastern" können. Hier verwenden wir zur Ton-
  5309. erzeugung einfach den PC-Piepser, was auch erklärt, warum
  5310. die "Herz-Routine" dieses Simulationsprogramms "Pieps"
  5311. heißt.
  5312. Die Bedienung des "Klavier-Simulators" erfolgt durch Ankli-
  5313. ken der Tasten mit der Maus. Eine Tastaturunterstützung wäre
  5314. natürlich auch noch möglich gewesen, hätte das Programm aber
  5315. etwas komplizierter gemacht. Deshalb wurde darauf verzich-
  5316. tet.
  5317.  
  5318. program Klavier;
  5319.  
  5320. uses WApp,
  5321.      WEvent,
  5322.      WDecl,
  5323.      WViews,
  5324.      WDlg,
  5325.      WUtils,
  5326.      crt;
  5327.  
  5328. const cmKlavier=101;
  5329.  
  5330. type TApplication=object(TApp)
  5331.        procedure InitMenuBar; virtual;
  5332.        procedure HandleEvent; virtual;
  5333.        procedure PlayWindow;
  5334.      end;
  5335.  
  5336.      PPiano=^TPiano;                                   {Unser "Klavier"}
  5337.      TPiano=object(TDlgWindow)
  5338.        constructor Init(x,y:integer);
  5339.        procedure HandleEvent; virtual;
  5340.      end;
  5341.  
  5342.  
  5343.  
  5344. Programmierhandbuch                                 WG-Vision - 93 -
  5345.  
  5346.  
  5347.  
  5348.  
  5349.  
  5350.  
  5351.  
  5352. var MyApp:TApplication;
  5353.  
  5354. procedure TApplication.InitMenuBar;
  5355. begin
  5356.   MainMenu('~F~enster',0);
  5357.    SubMenu('~K~lavier',cmKlavier,0,0,false,false);   {etwas übertrieben}
  5358.    SubMenu('E~x~it  Alt-X',cmCloseApplication,0,altX,false,false);
  5359. end;
  5360.  
  5361. procedure TApplication.HandleEvent;
  5362. begin
  5363.   Heap^.ShowHeapStatus(523,8,White);                   {wir testen noch}
  5364.   TProgram.HandleEvent;
  5365.   case Event.Command of
  5366.    cmKlavier : PlayWindow;
  5367.   end; {case}
  5368. end;
  5369.  
  5370. procedure TApplication.PlayWindow;   {was es alles für Fenster gibt ...}
  5371. var Window:PPiano;
  5372. begin
  5373.   Window:=new(PPiano, Init(60,80));
  5374.   InsertDesktop(Window);
  5375. end;
  5376.  
  5377. {Implementation TPiano}
  5378.  
  5379. constructor TPiano.Init(x,y:integer);
  5380. var RR:TRect;
  5381. begin
  5382.   RR.Assign(x,y,x+184,y+102);
  5383.   TDlgWindow.Init(RR,'Klavier',winDouble+winPanel+winMenu);
  5384.   SetPushButton(6,26,22,70,'C',90);
  5385.    ChangePalColor(8,LightGray);                        {nur eine Oktave}
  5386.   SetPushButton(31,26,22,70,'D',91);
  5387.    ChangePalColor(8,LightGray);
  5388.   SetPushButton(56,26,22,70,'E',92);
  5389.    ChangePalColor(8,LightGray);
  5390.  
  5391.  
  5392.  
  5393.  
  5394. Programmierhandbuch                                 WG-Vision - 94 -
  5395.  
  5396.  
  5397.  
  5398.  
  5399.  
  5400.  
  5401.  
  5402.   SetPushButton(81,26,22,70,'F',93);
  5403.    ChangePalColor(8,LightGray);
  5404.   SetPushButton(106,26,22,70,'G',94);
  5405.    ChangePalColor(8,LightGray);
  5406.   SetPushButton(131,26,22,70,'A',95);
  5407.    ChangePalColor(8,LightGray);
  5408.   SetPushButton(156,26,22,70,'H',96);
  5409.    ChangePalColor(8,LightGray);
  5410. end;
  5411.  
  5412. procedure TPiano.HandleEvent;
  5413.  
  5414. procedure Pieps(Frequenz:integer);
  5415. begin                             {der PC-Piepser kann halt nur piepsen}
  5416.   sound(Frequenz);
  5417.   delay(100);
  5418.   nosound;
  5419. end;
  5420.  
  5421. {-------}
  5422.  
  5423. begin
  5424.   TDlgWindow.HandleEvent;
  5425.   case Event.Command of       {und hier wird in der 4.Oktave gepiepst !}
  5426.    90 : Pieps(262);
  5427.    91 : Pieps(294);
  5428.    92 : Pieps(330);
  5429.    93 : Pieps(349);
  5430.    94 : Pieps(392);
  5431.    95 : Pieps(440);
  5432.    96 : Pieps(494);
  5433.   end; {case}
  5434. end;
  5435.  
  5436.  
  5437.  
  5438.  
  5439.  
  5440.  
  5441.  
  5442.  
  5443.  
  5444. Programmierhandbuch                                 WG-Vision - 95 -
  5445.  
  5446.  
  5447.  
  5448.  
  5449.  
  5450.  
  5451.  
  5452. {Hauptprogramm}
  5453.  
  5454. begin
  5455.   MyApp.Init('Klavier-Simulation');        {klingt bombastisch, nicht ?}
  5456.   MyApp.Run;
  5457.   MyApp.Done;
  5458. end.
  5459.  
  5460. Zu diesem Programm gibt es eigentlich nicht viel zu sagen.
  5461. Es zeigt sehr schön, wie man Pushbutton-Kommandos abfangen
  5462. und damit Aktionen steuern kann. In Perfektion können Sie
  5463. die Vorgehensweise innerhalb des Taschenrechner-Objekts
  5464. TCalc studieren, welches Bestandteil von WG-Vision ist.
  5465.  
  5466.  
  5467.  
  5468.  
  5469.  
  5470.  
  5471.  
  5472.  
  5473.  
  5474.  
  5475.  
  5476.  
  5477.  
  5478.  
  5479.  
  5480.  
  5481.  
  5482.  
  5483.  
  5484.  
  5485.  
  5486.  
  5487.  
  5488.  
  5489.  
  5490.  
  5491.  
  5492.  
  5493.  
  5494. Programmierhandbuch                                 WG-Vision - 96 -
  5495.  
  5496.  
  5497.  
  5498.  
  5499.  
  5500.  
  5501.  
  5502. 5.2.2. Statische Texte
  5503.  
  5504. In ein Dialogfenster können an jeder beliebigen Stelle sta-
  5505. tische Texte eingefügt werden. Mit der Methode SetStaticText
  5506. legen Sie fest, was für ein Text an welcher Stelle in wel-
  5507. cher Justierung ausgegeben werden soll. Außerdem können Sie
  5508. bei Verwendung einer der Vektorzeichensätze noch die
  5509. Schriftgröße und den Zeichensatz auswählen (mit dem Befehl
  5510. SetTextParameters). Statische Texte werden von WG-Vision wie
  5511. Dialogelemente verwaltet. Sie sind jedoch nicht fokussierbar
  5512. (warum auch ?). Dieser Befehl ist deshalb nicht geeignet,
  5513. einen Text auf ein Hintergrundobjekt zu schreiben. Dort
  5514. sollten Sie die normalen, von Turbo-Pascal unterstützten
  5515. Textausgabebefehle verwenden.
  5516.  
  5517. Syntax
  5518.  
  5519. SetStaticText(x,y:integer;Bez:string;RichPos:byte);
  5520.  
  5521. x,y     Bezugspunkt des Textes
  5522. Bez     auszugebender Text
  5523. RichPos Ausrichtung relativ zu x und y. Folgende
  5524.         vordefinierten
  5525.         Konstanten können verwendet werden:
  5526.  
  5527.         LeftText     linksbündig
  5528.         RightText    rechtsbündig
  5529.         Centertext   zentriert
  5530.  
  5531. Eine Anwendung zeigt folgendes Beispiel:
  5532.  
  5533. procedure TApplication.DialogText;
  5534. var R:TRect;
  5535.     Window:PDlgWindow;
  5536. begin
  5537.   R.Assign(60,80,440,280);
  5538.   Window:=new(PDlgWindow, Init(R,'Textausgabe im Dialogfenster',
  5539.                                winDouble+winPanel+winMenu));
  5540.  
  5541.  
  5542.  
  5543.  
  5544. Programmierhandbuch                                 WG-Vision - 97 -
  5545.  
  5546.  
  5547.  
  5548.  
  5549.  
  5550.  
  5551.  
  5552.   with Window^ do
  5553.    begin
  5554.      SetPushButton(15,40,80,22,'OK',cmCloseWindow);
  5555.      SetStaticText(150,40,'Standard-Zeichensatz',LeftText);
  5556.    end;
  5557.   InsertDesktop(Window);
  5558. end;
  5559.  
  5560. Für die Textfarbe ist der Paletteneintrag 10 zuständig. Soll
  5561. z.B. die Zeichenkette in Rot ausgegeben werden, dann ist der
  5562. Quelltext um den Befehl ChangePalColor zu ergänzen:
  5563.  
  5564. ...
  5565.  
  5566. SetStaticText(150,40,'Standardzeichensatz',LeftText);
  5567.  ChangePalColor(10, Red);
  5568. ...
  5569.  
  5570. Mit dem Befehl SetTextParameters können Sie den Zeichensatz,
  5571. die Größe der Buchstaben und die Ausrichtung des Textes
  5572. beeinflussen.
  5573. Unterstützt werden neben dem Standardzeichensatz DefaultFont
  5574. folgende 9 Vektorzeichensätze:
  5575.  
  5576. TriplexFont         TRIP.CHR
  5577. SmallFont           LITT.CHR
  5578. SansSerifFont       SANS.CHR
  5579. GothicFont          GOTH.CHR
  5580. ScriptFont          SCRI.CHR
  5581. SimpleFont          SIMP.CHR
  5582. TSCRFont            TSCR.CHR
  5583. LCOMFont            LCOM.CHR
  5584. EuroFont            EURO.CHR
  5585.  
  5586. Die in einem Programm verwendeten Zeichensätze müssen zur
  5587. Laufzeit im Verzeichnis des Programms vorhanden sein. Aus
  5588. Speicherplatzgründen wurde auf eine Einbindung als Objektda-
  5589. tei in WG-Vision verzichtet.
  5590.  
  5591.  
  5592.  
  5593.  
  5594. Programmierhandbuch                                 WG-Vision - 98 -
  5595.  
  5596.  
  5597.  
  5598.  
  5599.  
  5600.  
  5601.  
  5602. Für die Textausrichtung verwenden Sie bitte die Konstanten
  5603. HorizDir und VertDir.
  5604.  
  5605. Syntax
  5606.  
  5607. SetTextParameters(Fnt,Direct:word;CharSz:byte);
  5608.  
  5609. Fnt      Zeichensatz (DefaultFont ... EuroFont)
  5610. Direct   Ausrichtung (HorizDir, VertDir)
  5611. CharSz   Buchstabengröße
  5612.  
  5613. Beispiel
  5614.  
  5615. ...
  5616.  
  5617. SetStaticText(150,40,'Gotischer Zeichensatz',LeftText);
  5618.  SetTextParameters(GothicFont,HorizDir,1);
  5619. SetStaticText(150,65,'Triplex -  Zeichensatz',LeftText);
  5620.  SetTextParameters(TriplexFont,HorizDir,1);
  5621. SetStaticText(150,90,'Small -  Zeichensatz',LeftText);
  5622.  SetTextParameters(SmallFont,HorizDir,6);
  5623. ...
  5624.  
  5625. Folgendes Beispiel zeigt alle verfügbaren Vektorzeichensätze
  5626. in einem Dialogfenster an:
  5627.  
  5628. program ShowFonts;
  5629.  
  5630. uses WDecl,
  5631.      WEvent,
  5632.      WViews,
  5633.      WDlg,
  5634.      WApp,
  5635.      graph;
  5636.  
  5637. const cmDialog = 101;
  5638.  
  5639.  
  5640.  
  5641.  
  5642.  
  5643.  
  5644. Programmierhandbuch                                 WG-Vision - 99 -
  5645.  
  5646.  
  5647.  
  5648.  
  5649.  
  5650.  
  5651.  
  5652. type TApplication=object(TApp)
  5653.        procedure InitMenuBar; virtual;
  5654.        procedure HandleEvent; virtual;
  5655.        procedure DialogWindow;
  5656.      end;
  5657.  
  5658. var MyApp:TApplication;
  5659.  
  5660. {Implementation TApplication}
  5661.  
  5662. procedure TApplication.InitMenuBar;
  5663. begin
  5664.   Palette[1]:=#14;                     {diesmal ein etwas bunteres Menü}
  5665.   Palette[5]:=#14;
  5666.   Palette[4]:=#4;
  5667.   Palette[12]:=#4;
  5668.   MainMenu('~F~enster',0);
  5669.    SubMenu('~D~ialogfenster',cmDialog,0,0,false,false);
  5670.    SubMenu('E~x~it  Alt-X',cmCloseApplication,0,altX,false,false);
  5671. end;
  5672.  
  5673. procedure TApplication.HandleEvent;
  5674. begin
  5675.   Heap^.ShowHeapStatus(523,8,White);
  5676.   TProgram.HandleEvent;
  5677.   case Event.Command of
  5678.    cmDialog : DialogWindow;
  5679.   end; {case}
  5680. end;
  5681.  
  5682. procedure TApplication.DialogWindow;
  5683. var R:TRect;
  5684.     Window:PDlgWindow;
  5685. begin
  5686.   R.Assign(60,80,440,360);
  5687.   Window:=new(PDlgWindow, Init(R,'Beispiel 18 : Vektor-Zeichensätze',
  5688.                                winDouble+winPanel+winMenu+winKey));
  5689.  
  5690.  
  5691.  
  5692.  
  5693.  
  5694. Programmierhandbuch                                 WG-Vision - 100 -
  5695.  
  5696.  
  5697.  
  5698.  
  5699.  
  5700.  
  5701.  
  5702.   with Window^ do     {die Zeichensätze müssen natürlich verfügbar sein}
  5703.    begin
  5704.      SetPushButton(15,40,80,22,'Schließen',cmCloseWindow);
  5705.      SetStaticText(150,40,'Gotischer Zeichensatz',LeftText);
  5706.       SetTextParameters(GothicFont,HorizDir,1);
  5707.      SetStaticText(150,65,'Triplex - Zeichensatz',LeftText);
  5708.       SetTextParameters(TriplexFont,HorizDir,1);
  5709.      SetStaticText(150,90,'Small - Zeichensatz',LeftText);
  5710.       SetTextParameters(SmallFont,HorizDir,6);
  5711.      SetStaticText(150,110,'Sanserif - Zeichensatz',LeftText);
  5712.       SetTextParameters(SansSerifFont,HorizDir,1);
  5713.      SetStaticText(150,125,'Script - Zeichensatz',LeftText);
  5714.       SetTextParameters(5,HorizDir,1);
  5715.      SetStaticText(150,147,'Simple - Zeichensatz',LeftText);
  5716.       SetTextParameters(6,HorizDir,1);
  5717.      SetStaticText(150,168,'TSCR - Zeichensatz',LeftText);
  5718.       SetTextParameters(7,HorizDir,1);
  5719.      SetStaticText(150,185,'LCOM - Zeichensatz',LeftText);
  5720.       SetTextParameters(8,HorizDir,1);
  5721.      SetStaticText(60,210,'Euro - Zeichensatz',LeftText);
  5722.       SetTextParameters(9,HorizDir,1);
  5723.      SetStaticText(40,140,'Vertical - Small',RightText);
  5724.       SetTextParameters(SmallFont,VertDir,4);
  5725.    end;
  5726.   InsertDesktop(Window);
  5727. end;
  5728.  
  5729. {Hauptprogramm}
  5730.  
  5731. begin
  5732.   MyApp.Init('Zeichensätze im Dialogfenster');
  5733.   MyApp.Run;
  5734.   MyApp.Done;
  5735. end.
  5736.  
  5737.  
  5738.  
  5739.  
  5740.  
  5741.  
  5742.  
  5743.  
  5744. Programmierhandbuch                                 WG-Vision - 101 -
  5745.  
  5746.  
  5747.  
  5748.  
  5749.  
  5750.  
  5751.  
  5752. 5.2.3. Rahmen, Gruppenrahmen
  5753.  
  5754. Ein wichtiges passives Dialogelement ist der Gruppenrahmen.
  5755. Er dient der übersichtlichen Gestaltung eines Dialogfen-
  5756. sters. Mit Gruppenrahmen werden funktional zusammengehörende
  5757. Dialogelemente (z.B. eine Gruppe von Radiobuttons) versehen,
  5758. um ihre Zusammengehörigkeit hervorzuheben.
  5759. Gruppenrahmen müssen immer vor den Dialogelementen implemen-
  5760. tiert werden, die der Rahmen einfassen soll (bei den Grup-
  5761. penrahmen handelt es sich um Rahmen mit "Füllung").
  5762.  
  5763. Syntax
  5764.  
  5765. SetGroupFrame(x,y,xl,yl:integer;Bez:str25;FrameTyp:word);
  5766.  
  5767. x,y       linke obere Ecke
  5768. xl,yl     Länge und Breite des Rahmens
  5769. FrameTyp  Rahmentyp. Folgende Rahmentypen sind verfügbar:
  5770.  
  5771.           NormWidth     normale Linienstärke
  5772.           ThickWidth    dreifache Linienstärke
  5773.  
  5774. Der Bezeichner wird, wie bei Windows üblich, links oben in
  5775. den Rahmen eingefügt. Er kann aber auch beliebig positio-
  5776. niert werden, indem ihm mit SetTextPosition eine neue Posi-
  5777. tion im Dialogfenster zugeordnet wird. In diesem Fall
  5778. schließt sich der Rahmen zu einem vollständigen Rechteck.
  5779. Die Positionierung des Bezeichners erfolgt absolut innerhalb
  5780. des durch den Rahmen des Dialogfensters gegebenen Koordina-
  5781. tensystems (siehe Beispiel).
  5782.  
  5783.  
  5784.  
  5785.  
  5786.  
  5787.  
  5788.  
  5789.  
  5790.  
  5791.  
  5792.  
  5793.  
  5794. Programmierhandbuch                                 WG-Vision - 102 -
  5795.  
  5796.  
  5797.  
  5798.  
  5799.  
  5800.  
  5801.  
  5802. 5.2.3.1. Farbgestaltung
  5803.  
  5804. Für die farbliche Gestaltung des Gruppenrahmens ist Palette
  5805. 5 zuständig:
  5806.  
  5807. Palettenlayout
  5808.  
  5809. Eintrag      Bedeutung                       Standard
  5810.  
  5811.    1         Rahmenfarbe                     #0   Schwarz
  5812.    2         Hintergrund                     #15  Weiß
  5813.    4         Bezeichner                      #0   Schwarz
  5814.  
  5815. Beispiel
  5816.  
  5817. procedure TApplication.DialogWindow;
  5818. var R:TRect;
  5819.     Window:PDlgWindow;
  5820. begin
  5821.   R.Assign(60,80,440,360);
  5822.   Window:=new(PDlgWindow, Init(R,'Beispiel 19 :
  5823.               Gruppenfenster',winDouble+winPanel+winMenu));
  5824.   with Window^ do
  5825.    begin
  5826.      SetPushButton(15,40,80,22,'OK',cmCloseWindow);
  5827.      SetGroupFrame(130,40,210,60,'Gruppenfenster 1',NormWidth);
  5828.      SetGroupFrame(130,120,210,60,'Gruppenfenster 2',ThickWidth);
  5829.      SetGroupFrame(130,200,210,60,'Gruppenfenster 3',ThickWidth);
  5830.       ChangePalColor(1,Blue);      {Rahmen}
  5831.       ChangePalColor(2,Yellow);    {Hintergrund}
  5832.       ChangePalColor(4,Green);     {Text}
  5833.      SetGroupFrame(15,160,80,60,'Rahmen 4',ThickWidth);
  5834.       SetTextPosition(15,145);     {neue Textposition relativ zum}
  5835.                                    {Fenster}
  5836.       ChangePalColor(4,Magenta);
  5837.       ChangePalColor(2,LightRed);
  5838.    end;
  5839.   InsertDesktop(Window);
  5840. end;
  5841.  
  5842.  
  5843.  
  5844. Programmierhandbuch                                 WG-Vision - 103 -
  5845.  
  5846.  
  5847.  
  5848.  
  5849.  
  5850.  
  5851.  
  5852. 5.2.4. Icons
  5853.  
  5854. Seitdem es Windows gibt, werden Icons immer beliebter. Dem
  5855. will auch WG-Vision nicht nachstehen. Im Gegensatz zu Win-
  5856. dows werden aber nur statische Icons unterstützt. Das sind
  5857. Sinnbilder, die als passives Dialogelement fest (und nicht
  5858. mit der Maus verschiebbar) in einem Dialogfenster angeordnet
  5859. werden. Außerdem lassen sie sich sehr gut zur Ausschmückung
  5860. von Pushbuttons (z.B. für eine Icon-Leiste) verwenden.
  5861. Die von WG-Vision verwendeten Icons sind nicht Windows-kom-
  5862. patibel. Sie werden, nachdem sie in einem Icon-Editor er-
  5863. stellt worden sind, mit GetImage ausgelesen und via
  5864. BlockWrite in eine Datei geschrieben. Solch eine Datei kann
  5865. beliebig viele Icons gleicher Größe (z.B. 32x32 Pixel) ent-
  5866. halten und wird als Icon-Ressource bezeichnet. Der Aufruf
  5867. eines Icons erfolgt über seinen Index (d.h. Position) inner-
  5868. halb dieser Datei.
  5869. WG-Vision verwendet Icons der Größe 16x16 und 32x32 Pixel.
  5870. Eine Icon-Ressource kann nur Icons eines Typs (erkenntlich
  5871. an den Extensionen .I16 und .I32) enthalten. Außerdem muß
  5872. noch beachtet werden, daß Icons für EGA- und VGA-Grafikkarte
  5873. nicht in den VESA-Super-VGA-Modi verwendet werden können
  5874. (andere Organisation des Bildwiederholspeichers und der
  5875. Farbcodierung).
  5876.  
  5877. Syntax
  5878.  
  5879. SetIcon(x,y:integer;Bez:str25);
  5880.  
  5881. x,y  Koordinate der linken oberen Ecke
  5882. Bez  Dateiname + Iconnummer
  5883.  
  5884. Beispiel
  5885.  
  5886. SetIcon(100,120,'#ICON.I32/5');
  5887.                    │    │  └─ Icon Nr. 5
  5888.                    │    └─ Extension I32, 32x32 Pixel-Icon
  5889.                    └─ Dateiname, das Doppelkreuz muß
  5890.                       zusätzlich angegeben werden
  5891.  
  5892.  
  5893.  
  5894. Programmierhandbuch                                 WG-Vision - 104 -
  5895.  
  5896.  
  5897.  
  5898.  
  5899.  
  5900.  
  5901.  
  5902. 5.2.5. Aktive Dialogelemente in WG-Vision
  5903.  
  5904. Der eigentliche Sinn von Dialogboxen besteht in der Eingabe
  5905. von Informationen, auf die i.A. andere Programmteile zugrei-
  5906. fen sollen. Das bedeutet, daß die Daten, die Sie in ein Dia-
  5907. logfenster eingeben, auch außerhalb dieses Dialogfensters
  5908. verfügbar sein müssen. Um diese Forderung zu erfüllen, be-
  5909. nutzt WG-Vision spezielle Datenrecords (Dialog-Record), die
  5910. für jedes Dialogfenster individuell erstellt werden. Die Re-
  5911. cordvariablen sind Programm- bzw. Modul-global. Ihr Inhalt
  5912. kann damit von beliebigen Programmteilen gelesen werden.
  5913.  
  5914. Prinzipielles Herangehen
  5915.  
  5916. 1. Deklaration eines Programm- bzw. Modul-globalen
  5917.    Datenrecords für jedes Dialogfenster
  5918.  
  5919. type tFontDataRec=record
  5920.                     Schalter:string[9];
  5921.                   end;          └─ Dialogbox enthält 9 Dialogelemente
  5922.  
  5923. Bei einer Modul-globalen Deklaration ist der Dialogrecord
  5924. nur innerhalb einer Unit verfügbar. Die Deklaration erfolgt
  5925. innerhalb des Implementationsteils der Unit (Beispiel siehe
  5926. Unit WPalette.pas).
  5927.  
  5928. 2. Record-Variable deklarieren
  5929.  
  5930. var FontDataRec:tFontDataRec;
  5931.  
  5932. 3. Record-Variable mit Anfangswerten belegen (nicht
  5933.    vergessen!)
  5934.  
  5935. Die Initialisierung der Datenrecords erfolgt innerhalb der
  5936. virtuellen Methode SetDialogData. Innerhalb dieser Methode
  5937. werden die Datenrecords aller im Programm vorkommenden Dia-
  5938. logfenster mit Anfangswerten belegt. Bei Modul-internen De-
  5939.  
  5940.  
  5941.  
  5942.  
  5943.  
  5944. Programmierhandbuch                                 WG-Vision - 105 -
  5945.  
  5946.  
  5947.  
  5948.  
  5949.  
  5950.  
  5951.  
  5952. klarationen ist diese Vorgehensweise nicht notwendig. In
  5953. solch einem Fall belegen Sie den Dialogrecord am Besten
  5954. innerhalb des Konstruktors des Dialogfensters.
  5955.  
  5956. procedure TApplication.SetDialogData;
  5957. begin
  5958.   with FontDataRec do Schalter:='TGrrrrRrG';
  5959. end;
  5960.  
  5961. An dieser Stelle ist besondere Sorgfalt angesagt. Ein klei-
  5962. ner Fehler kann schnell zu unvorhergesehenen Programmabläu-
  5963. fen führen. Die Variable Schalter enthält in der Reihenfolge
  5964. der Implementation die Kennbuchstaben der im Dialogfenster
  5965. implementierten Dialogelemente. Die Anzahl der Zeichen in
  5966. diesem String muß genauso groß sein wie die im Datenrecord
  5967. vorgegebene Stringlänge.
  5968. Innerhalb von WG-Vision gelten folgende Kennbuchstaben für
  5969. die einzelnen Dialogelemente:
  5970.  
  5971. T   Pushbutton
  5972. R   gesetztes Radiobutton
  5973. r   nichtgesetztes Radiobutton
  5974. C   gesetztes Checkbutton
  5975. c   nichtgesetztes Checkbutton
  5976. L   Eingabezeile, Zählschalter
  5977. B   Listbox
  5978. G   Gruppenrahmen
  5979. I   Icon
  5980. S   statischer Text
  5981.  
  5982. Hinweis: Dialogfenster, welche nur passive Dialogelemente
  5983.          enthalten, benötigen keinen Datenrecord zum
  5984.          Datenaustausch.
  5985.  
  5986.  
  5987.  
  5988.  
  5989.  
  5990.  
  5991.  
  5992.  
  5993.  
  5994. Programmierhandbuch                                 WG-Vision - 106 -
  5995.  
  5996.  
  5997.  
  5998.  
  5999.  
  6000.  
  6001.  
  6002. 5.2.6. Radio-Buttons (Optionsschaltflächen)
  6003.  
  6004. Radio-Buttons verdanken ihren Namen den Frequenzwahltasten
  6005. an Radios, deren Funktionsweise sie nachahmen. Betätigt man
  6006. z.B. mit der Maus ein Radiobutton, dann wird der bisher ak-
  6007. tive Radiobutton deaktiviert. Daraus wird ersichtlich, daß
  6008. mindestens zwei Radiobuttons eine Gruppe bilden. Ein Radio-
  6009. button für sich allein ergibt keinen Sinn.
  6010. Da Radiobuttons innerhalb eines Programms verschiedene Funk-
  6011. tionseinheiten repräsentieren können, ist eine Gruppenbil-
  6012. dung unerläßlich. Die Gruppenzugehörigkeit eines Radiobut-
  6013. tons wird durch den Parameter PGruppe festgelegt.
  6014. Das Einfügen von Radiobuttons in ein Dialogfenster ist sehr
  6015. einfach, wie folgendes Beispiel zeigt:
  6016.  
  6017. constructor TSetFontWindow.Init(x,y:integer);
  6018. var RR:TRect;
  6019. begin
  6020.   RR.Assign(x,y,x+455,y+265);
  6021.   TDlgWindow.Init(RR,'Zeichensätze', winDouble+winPanel+winMenu);
  6022.   SetPushButton(55,210,80,22,'OK',cmCloseWindow);
  6023.   SetGroupFrame(25,55,150,125,'Zeichensätze',NormWidth);
  6024.   SetRadioButton(45,80, '~T~hin8    8x12',1);                 {Gruppe 1}
  6025.   SetRadioButton(45,95, 'T~h~in14   8x14',1);
  6026.   SetRadioButton(45,110,'Th~i~n16   8x16',1);
  6027.   SetRadioButton(45,125,'~B~rdwy19  8x19',1);
  6028.   SetRadioButton(45,140,'~W~ndw19   8x19',1);
  6029.   SetRadioButton(45,155,'~S~ans19   8x19',1);
  6030.   SetData(FontDataRec);       {Dialogrecord mit Anfangswerten übergeben}
  6031. end;
  6032.  
  6033. Mit SetData werden dem Dialogfenster die Anfangswerte zu-
  6034. gänglich gemacht. Die Variable Schalter in FontDataRec hat
  6035. folgende Belegung:
  6036.  
  6037. Schalter:='TGrrrrRrG';
  6038.  
  6039. Das Radiobutton mit der Bezeichnung Wndw19 ist beim Aufblen-
  6040. den des Dialogfensters aktiv. Das wird durch den Buchstaben-
  6041.  
  6042.  
  6043.  
  6044. Programmierhandbuch                                 WG-Vision - 107 -
  6045.  
  6046.  
  6047.  
  6048.  
  6049.  
  6050.  
  6051.  
  6052. kürzel "R" (im Gegensatz zu "r") erreicht. Wenn ein anderes
  6053. Radiobutton angeklickt wird (z.B. Thin14), dann ändert sich
  6054. Schalter simultan in
  6055.  
  6056. 'TGrRrrrrG'
  6057.  
  6058. Durch die Analyse dieser Zeichenkette kann man nach dem
  6059. Schließen des Dialogfensters (oder simultan innerhalb dessen
  6060. Eventhandlers) die neue Schalterstellung auswerten, z.B. mit
  6061.  
  6062. if Schalter[4]:'R' then ...
  6063.  
  6064. Oft versieht man ein Dialogfenster mit dem Schalter "Abbre-
  6065. chen". Damit nach einem Abbruch der Ursprungszustand des
  6066. Dialogrecords wieder hergestellt werden kann, empfiehlt es
  6067. sich, eine Zwischenvariable für den Dialogrecord als Feld
  6068. innerhalb des Dialogfenster-Objekts einzurichten. Innerhalb
  6069. des Konstruktors wird in diesem Feld der Dialogrecord zwi-
  6070. schengespeichert. Sendet das Dialogfenster das Kommando
  6071. cmCancel, dann läßt sich innerhalb des Eventhandlers der
  6072. Originalzustand leicht wieder herstellen.
  6073.  
  6074. Komplexbeispiel     Quelltext-Lister mit Zeichensatzänderung
  6075.  
  6076. Das folgende Beispiel zeigt die Verwendung von Radiobuttons
  6077. in einem konkreten Anwendungsfall. Außerdem werden einige
  6078. spezielle Programmiermethoden (Abfangen von Mitteilungen,
  6079. Sperren und Freigabe von Menüpunkten, Änderung des Fenster-
  6080. hintergrundes ohne Verwendung des TBackground-Objekts)
  6081. behandelt.
  6082.  
  6083. Aufgabenstellung
  6084. Es soll ein einfacher Quelltextlister (Erweiterung des
  6085. Programms Lister.pas) entwickelt werden, bei dem sich zur
  6086. Laufzeit der Zeichensatz wechseln läßt. Die verfügbaren
  6087. Zeichensätze sollen sich aus einem Dialogfenster unter
  6088. Verwendung von Radiobuttons auswählen lassen.
  6089.  
  6090.  
  6091.  
  6092.  
  6093.  
  6094. Programmierhandbuch                                 WG-Vision - 108 -
  6095.  
  6096.  
  6097.  
  6098.  
  6099.  
  6100.  
  6101.  
  6102. Der Quelltextlister mit Veränderung des Zeichenfonts
  6103. funktioniert nicht in den Super-VGA-Modi.
  6104.  
  6105. program Lister;
  6106.  
  6107. uses WApp,
  6108.      WEvent,
  6109.      WDecl,
  6110.      WViews,
  6111.      WDriver,
  6112.      WDlg,
  6113.      WFileDlg,
  6114.      WUtils,
  6115.      WText,
  6116.      graph;
  6117.  
  6118.  
  6119. const cmOpen    = 101;
  6120.       cmSetFont = 102;
  6121.  
  6122.       msgDraw   = 100;             {Mitteilung, Scrollbereich mit neuem}
  6123.                                                 {Zeichensatz darstellen}
  6124.  
  6125. type TApplication=object(TApp)
  6126.        procedure InitMenuBar; virtual;
  6127.        procedure SetDialogData; virtual;
  6128.        procedure HandleEvent; virtual;
  6129.        procedure LoadFile;
  6130.        procedure ListWindow;
  6131.        procedure SetFont;
  6132.      end;
  6133.  
  6134.      PNewScroller=^TNewScroller;
  6135.  
  6136.  
  6137.  
  6138.  
  6139.  
  6140.  
  6141.  
  6142.  
  6143.  
  6144. Programmierhandbuch                                 WG-Vision - 109 -
  6145.  
  6146.  
  6147.  
  6148.  
  6149.  
  6150.  
  6151.  
  6152.      PScrollWindow=^TScrollWindow;
  6153.      TScrollWindow=object(TWindow)
  6154.        Scroller:PNewScroller;
  6155.        procedure InitWindowScroller; virtual;
  6156.        procedure HandleEvent; virtual;
  6157.        destructor Done; virtual;
  6158.      end;
  6159.  
  6160.      TNewScroller=object(TScroller)
  6161.        procedure CreateData;
  6162.        procedure ScrollDraw; virtual;
  6163.      end;
  6164.  
  6165. {Dialogfenster zur Auswahl der Zeichensätze}
  6166.  
  6167.      PSetFontWindow=^TSetFontWindow;
  6168.      TSetFontWindow=object(TDlgWindow)
  6169.       DFont:GraficFont;
  6170.       constructor Init(x,y:integer);
  6171.       procedure DrawClientArea; virtual;
  6172.       procedure HandleEvent; virtual;
  6173.      end;
  6174.  
  6175. {Dialog-Record}
  6176.  
  6177.      tFontDataRec=record
  6178.                     Schalter:string[8];
  6179.                   end;
  6180.  
  6181.  
  6182. var MyApp:TApplication;
  6183.     FontDataRec:tFontDataRec;
  6184.  
  6185. Der Menüpunkt "Zeichensatz wechseln" ist beim Programmstart gesperrt
  6186. (vorletzter Parameter=true). Da es in diesem konkreten Beispiel wenig
  6187. sinnvoll ist, den Zeichensatz vor dem Aufblenden des Listfensters zu än-
  6188. dern (das List-Objekt stellt bei seiner Initialisierung selbst einen
  6189. Zeichensatz ein), wird dieser Menüpunkt einfach gesperrt. Erst wenn sich
  6190. ein List-Fenster auf dem Bildschirm befindet, wird er freigegeben (siehe
  6191.  
  6192.  
  6193.  
  6194. Programmierhandbuch                                 WG-Vision - 110 -
  6195.  
  6196.  
  6197.  
  6198.  
  6199.  
  6200.  
  6201.  
  6202. TApplication.HandleEvent)
  6203.  
  6204. procedure TApplication.InitMenuBar;
  6205. begin
  6206.   MainMenu('~F~enster',0);
  6207.    SubMenu('~D~atei Laden',cmOpen,0,0,false,false);
  6208.    SubMenu('~Z~eichensatz wechseln',cmSetFont,0,0,true,false);
  6209.    NewLine;
  6210.    SubMenu('E~x~it  Alt-X',cmCloseApplication,0,altX,false,false);
  6211. end;
  6212.  
  6213. Dialogrecord initialisieren. Das Radiobutton Nr.5 ist aktiv
  6214.  
  6215. procedure TApplication.SetDialogData;
  6216. begin
  6217.   FontDataRec.Schalter:='TGrrrrRr';
  6218. end;
  6219.  
  6220. Das Objekt TInputDialog (Unit WFileDlg) ist eine komplette Dateiaus-
  6221. wahlbox. Diese Auswahlbox sendet die Message msgLoadFile, wenn daraus
  6222. ein gültiger Dateiname ausgewählt wurde. Dieser Dateiname wird in
  6223. Event.InfoString mit kompletten Pfad gespeichert und damit letztendlich
  6224. zu seinem Empfänger transportiert (TNewScroller.CreateData). Das pas-
  6225. siert beim Aufruf von ListWindow. Dieses Objekt ist für die Darstellung
  6226. eines Textes in einem Scrollfenster zuständig. Danach darf auf keinem
  6227. Fall vergessen werden, die Message zu löschen. Andernfalls würden weite-
  6228. re Listfenster im Heap (und auf dem Bildschirm) erzeugt bis leztendlich
  6229. der Speicher voll ist.
  6230.  
  6231.  
  6232.  
  6233.  
  6234.  
  6235.  
  6236.  
  6237.  
  6238.  
  6239.  
  6240.  
  6241.  
  6242.  
  6243.  
  6244. Programmierhandbuch                                 WG-Vision - 111 -
  6245.  
  6246.  
  6247.  
  6248.  
  6249.  
  6250.  
  6251.  
  6252. procedure TApplication.HandleEvent;
  6253. begin
  6254.   Heap^.ShowHeapStatus(523,8,White);
  6255.   TProgram.HandleEvent;
  6256.   case Event.Command of
  6257.    cmOpen    : LoadFile;
  6258.    cmSetFont : SetFont;
  6259.   end; {case}
  6260.   if Event.Message=msgLoadFile then
  6261.    begin
  6262.      ListWindow;
  6263.      ClearMessage;
  6264.    end;
  6265.  
  6266. Jeder Untermenüeintrag verfügt als Instanz von TSubMenu Methoden, um
  6267. sich zu sperren (Aktiviere) und sich wieder freizugeben (DeAktiviere).
  6268. Ein gesperrter Untermenüpunkt wird standardmäßig auf dem Bildschirm mit
  6269. hellgrauer Schrift dargestellt. Er kann dann keine Kommandos mehr abset-
  6270. zen. Ein zu sperrendes Untermenü erreicht man über die Pointerkette MMe-
  6271. nu[Nr des Hauptmenü-eintrags]^.SBMenu[Position im Pull-Down-Menü]^.
  6272. NewLine zählt dabei auch als Eintrag. In diesem Beispiel wird das Menü
  6273. immer dann gesperrt, wenn sich kein Listfenster (WinAnz=0) auf dem Bild-
  6274. schirm befindet.
  6275.  
  6276.   if WinAnz=0 then MMenu[1]^.SbMenu[2]^.Aktiviere
  6277.    else MMenu[1]^.sbMenu[2]^.DeAktiviere;
  6278. end;
  6279.  
  6280. Hier sieht man die Vorteile, die ein ordentlich ausgetestetes Fenster-
  6281. objekt, verpackt in einer Unit (hier WFileDlg), den Programmierer bietet
  6282. (oder wie lange würden Sie zur Programmierung eines Eingabedialogs benötigen ?
  6283.  
  6284. procedure TApplication.LoadFile;
  6285. var Window:PInputDialog;
  6286. begin
  6287.   Window:=new(PInputDialog, Init('Dateiauswahl','*.PAS'));
  6288.   InsertDesktop(Window);
  6289. end;
  6290.  
  6291.  
  6292.  
  6293.  
  6294. Programmierhandbuch                                 WG-Vision - 112 -
  6295.  
  6296.  
  6297.  
  6298.  
  6299.  
  6300.  
  6301. procedure TApplication.ListWindow;
  6302. var R:TRect;
  6303.     Window:PScrollWindow;
  6304. begin
  6305.   R.Assign(20,60,616,446);
  6306.   Window:=new(PScrollWindow, Init(R,'ScrollWindow / Quelltext-Lister',
  6307.               winDouble+winPanel+winMenu+winKey));
  6308.   InsertDesktop(Window);
  6309. end;
  6310.  
  6311. procedure TApplication.SetFont;
  6312. var Window:PSetFontWindow;
  6313. begin
  6314.   Window:=new(PSetFontWindow, Init(60,80));
  6315.   InsertDesktop(Window);
  6316. end;
  6317.  
  6318. {Implementation TScrollWindow}
  6319.  
  6320. procedure TScrollWindow.InitWindowScroller;
  6321. var R:TRect;
  6322.     SBH1,SBV1:PScrollBar;
  6323. begin
  6324.   R:=Frame^.Area;
  6325.   SBH1:=new(PScrollBar, Init(R,HorizDir));
  6326.   SBV1:=new(PScrollBar, Init(R,VertDir));
  6327.   Scroller:=new(PNewScroller, Init(R,SBH1,SBV1));
  6328.   Scroller^.CreateData;
  6329.   List^.InsertItem(Scroller);
  6330. end;
  6331.  
  6332. procedure TScrollWindow.HandleEvent;
  6333. begin
  6334.   TWindow.HandleEvent;
  6335.   if Event.Message=msgDraw then           {Scrollbereich neu darstellen}
  6336.    begin
  6337.      Scroller^.ScrollDraw;
  6338.      ClearMessage;
  6339.    end;
  6340. end;
  6341.  
  6342.  
  6343.  
  6344. Programmierhandbuch                                 WG-Vision - 113 -
  6345.  
  6346.  
  6347.  
  6348.  
  6349.  
  6350.  
  6351.  
  6352. destructor TScrollWindow.Done;
  6353. begin
  6354.   TWindow.Done;
  6355.   dispose(Scroller, Done);
  6356. end;
  6357.  
  6358. {Implementation TNewScroller}
  6359.  
  6360. procedure TNewScroller.CreateData;
  6361. var dat:text;
  6362.     LfdPtr:PLine;
  6363. begin
  6364.   SetFont(Wndw19);
  6365.  
  6366. An dieser Stelle wird der InfoString ausgelesen. Rückgesetzt wird die
  6367. Mitteilung aber erst im Eventhandler der Applikation
  6368.  
  6369.   assign(dat,Event.InfoString);
  6370.   reset(dat);
  6371.   while not EOF(dat) do
  6372.    begin
  6373.      LfdPtr:=new(PLine, Init);
  6374.      readln(dat,LfdPtr^.Eintrag);
  6375.      Liste^.InsertItem(LfdPtr);
  6376.    end;
  6377.   SetLimit(25,Liste^.AnzElem-1,8,16);
  6378. end;
  6379.  
  6380. procedure TNewScroller.ScrollDraw;
  6381. var i:integer;
  6382.     LfdPtr:PGroup;
  6383.  
  6384. function clip(p,n:byte;z:string):string;
  6385. begin
  6386.   clip:=copy(z,p,n);
  6387. end;
  6388.  
  6389.  
  6390.  
  6391.  
  6392.  
  6393.  
  6394. Programmierhandbuch                                 WG-Vision - 114 -
  6395.  
  6396.  
  6397.  
  6398.  
  6399.  
  6400.  
  6401.  
  6402. begin
  6403.   SetFontColor(White,Blue);                  {Farbgestaltung des gerade}
  6404.                                                  {aktiven Zeichensatzes}
  6405.   Mouse.HideMouse;
  6406.   with Border do
  6407.    begin
  6408.      SetFillStyle(SolidFill,GetPalColor(1));
  6409.      SetColor(GetPalColor(2));
  6410.      for i:=Delta.y to WDelta.y do
  6411.       begin
  6412.         LfdPtr:=Liste^.GetItems(i);
  6413.         Bar(A.x,A.y+(i-Delta.y)*Py+10,B.x,A.y+(i-Delta.y)*Py+10+Py);
  6414.         WriteText(A.x+20,A.y+(i-Delta.y)*Py+10,clip(Delta.x,
  6415.                   Spalten*8 div 8-5,PLine(LfdPtr)^.Eintrag));
  6416.       end;
  6417.      if VertiScrollBar<>nil then
  6418.       for i:=(WDelta.y-Delta.y)+1 to Zeilen do
  6419.        Bar(A.x,A.y+i*Py+10,B.x,A.y+i*Py+10+Py);
  6420.    end;
  6421.   Mouse.ShowMouse;
  6422. end;
  6423.  
  6424. {Implementation TSetFontWindow}
  6425.  
  6426. constructor TSetFontWindow.Init(x,y:integer);
  6427. var RR:TRect;
  6428.     i:integer;
  6429. begin
  6430.   RR.Assign(x,y,x+455,y+265);
  6431.   TDlgWindow.Init(RR,'Zeichensätze',winDouble+winPanel+winMenu);
  6432.   SetPushButton(55,210,80,22,'OK',cmCloseWindow);
  6433.   SetGroupFrame(25,55,150,125,'Zeichensätze',NormWidth);
  6434.   SetRadioButton(45,80, '~T~hin8   8x12',1);
  6435.   SetRadioButton(45,95, 'T~h~in14  8x14',1);
  6436.   SetRadioButton(45,110,'Th~i~n16  8x16',1);
  6437.   SetRadioButton(45,125,'~B~rdwy19 8x19',1);
  6438.   SetRadioButton(45,140,'~W~ndw19  8x19',1);
  6439.   SetRadioButton(45,155,'~S~ans19  8x19',1);
  6440.  
  6441.  
  6442.  
  6443.  
  6444. Programmierhandbuch                                 WG-Vision - 115 -
  6445.  
  6446.  
  6447.  
  6448.  
  6449.  
  6450.  
  6451.  
  6452. Dialogrecord dem Fensterobjekt bekannt machen
  6453.  
  6454.   SetData(FontDataRec);
  6455.  
  6456. Da nicht vorausgesetzt werden kann, welcher Zeichensatz gerade aktiv
  6457. ist, wird der aktive Zeichensatz aus der Stellung der Radiobuttons be-
  6458. stimmt. Nur beim allerersten Aufblenden der Dialogbox steht der in TAp-
  6459. plication.SetDialogData initialisierte Dialogstring zur Verfügung.
  6460. Später kann er durchaus verändert worden sein.
  6461.  
  6462.   for i:=3 to 8 do
  6463.    if FontDataRec.Schalter[i]='R' then
  6464.     case i of
  6465.       3 : DFont:=Thin8;
  6466.       4 : DFont:=Thin14;
  6467.       5 : DFont:=Thin16;
  6468.       6 : DFont:=Brdwy19;
  6469.       7 : DFont:=Wndw19;
  6470.       8 : DFont:=Sans19;
  6471.     end; {case}
  6472.  
  6473. Font-Typ und Font-Farbe setzen
  6474.  
  6475.   SetFont(DFont);
  6476.   SetFontColor(White,Green);
  6477. end;
  6478.  
  6479. Wie in diesem Handbuch schon mehrfach erläutert wurde, stellt der Fen-
  6480. sterhintergrund ein eigenständiges Objekt dar. Das bringt den Nachteil
  6481. mit sich, daß eine Veränderung des Fensterinhalts ohne Abarbeitung der
  6482. Draw-Methoden aller Fensterelemente nur umständlich zu realisieren ist.
  6483. Aus diesem Grund wurde innerhalb des TWindow-Objekts die leere Methode
  6484. DrawClientArea implementiert. Mit dieser Methode läßt sich der Hinter-
  6485. grund eines Fenster sehr leicht überschreiben. In diesem Programm wird
  6486. die Prozedur zur Anzeige eines Zeichenblocks im Dialogfenster genutzt.
  6487. Sie wird im Eventhandler immer dann abgearbeitet, wenn ein neues Radio-
  6488. button ausgewählt wird. In diesem Beispiel wird für die Positionierung
  6489. der Rahmen und der Zeichenketten der Nullpunkt des Fensters (Origin)
  6490. verwendet.
  6491.  
  6492.  
  6493.  
  6494. Programmierhandbuch                                 WG-Vision - 116 -
  6495.  
  6496.  
  6497.  
  6498.  
  6499.  
  6500.  
  6501.  
  6502. procedure TSetFontWindow.DrawClientArea;
  6503. var z:array[1..6] of string;
  6504.     i:integer;
  6505. begin
  6506.   z[1]:='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  6507.   z[2]:='abcdefghijklmnopqrstuvwxyz';
  6508.   z[3]:='ÄÖÜäöü?=)(/&%$"!^°²ⁿ{[]}\';
  6509.   z[4]:='12345678901234567890123456';
  6510.   z[5]:='{}[]\~ÇüéâäàåçêëèïîìÄÅÉæôö';
  6511.   z[6]:='òûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼─«';
  6512.   with Origin do
  6513.    begin
  6514.      SetColor(Black);
  6515.      Mouse.HideMouse;
  6516.      FBar(x+205,y+60,x+425,y+188,White);
  6517.      SetLineStyle(SolidLn,0,ThickWidth);
  6518.      RectAngle(x+200,y+55,x+427,y+190);
  6519.      SetLineStyle(SolidLn,0,NormWidth);
  6520.      for i:=1 to 6 do WriteText(x+215,y+45+i*20,z[i]);
  6521.      Mouse.ShowMouse;
  6522.    end;
  6523. end;
  6524.  
  6525. Setzen eines neuen Zeichensatzes. Der Zeichensatz wird je nach Schal-
  6526. terstellung innerhalb einer case-Auswahl bestimmt. Hat sich gegenüber
  6527. dem letzten Aufruf der Font verändert, dann wird der neue Zeichensatz
  6528. aktiviert und der Zeichenblock mittels der Methode DrawClientArea neu
  6529. dargestellt. Außerdem wird die Message msgDraw ausgesendet, die vom
  6530. Eventhandler des Scrollers abgefangen wird und ein Neu-Zeichnen des
  6531. Scrollbereichs bewirkt. Da der Scroller solange deaktiv ist wie das Dia-
  6532. logfenster aufgeblendet ist (ein Dialog ist immer modal), kann er erst
  6533. auf diese Message reagieren, wenn das Font-Auswahlfenster mit cmClose-
  6534. Window geschlossen wird (deshalb wird TDlgWindow.HandleEvent erst am
  6535. Ende der Prozedur aufgerufen).
  6536.  
  6537.  
  6538.  
  6539.  
  6540.  
  6541.  
  6542.  
  6543.  
  6544. Programmierhandbuch                                 WG-Vision - 117 -
  6545.  
  6546.  
  6547.  
  6548.  
  6549.  
  6550.  
  6551.  
  6552. procedure TSetFontWindow.HandleEvent;
  6553. var i:byte;
  6554. begin
  6555.   with FontDataRec do
  6556.    for i:=3 to 8 do
  6557.     if Schalter[i]='R' then
  6558.      begin
  6559.        case i of
  6560.         3 : DFont:=Thin8;
  6561.         4 : DFont:=Thin14;
  6562.         5 : DFont:=Thin16;
  6563.         6 : DFont:=Brdwy19;
  6564.         7 : DFont:=Wndw19;
  6565.         8 : DFont:=Sans19;
  6566.        end; {case}
  6567.      end;
  6568.   if DFont<>Font then                                {Font gewechselt ?}
  6569.    begin
  6570.      SetFont(DFont);                             {neuen Font aktivieren}
  6571.      DrawClientArea;                                {Testblock zeichnen}
  6572.      Event.Message:=msgDraw;                       {Message an Scroller}
  6573.    end;
  6574.   TDlgWindow.HandleEvent;
  6575. end;
  6576.  
  6577. {Hauptprogramm}
  6578.  
  6579. begin
  6580.   MyApp.Init('Beispiel :  LISTER mit Fontwechsel');
  6581.   MyApp.Run;
  6582.   MyApp.Done;
  6583. end.
  6584.  
  6585.  
  6586.  
  6587.  
  6588.  
  6589.  
  6590.  
  6591.  
  6592.  
  6593.  
  6594. Programmierhandbuch                                 WG-Vision - 118 -
  6595.  
  6596.  
  6597.  
  6598.  
  6599.  
  6600.  
  6601.  
  6602. 5.2.7. Checkbuttons (Kontrollfelder)
  6603.  
  6604. Eine Checkbutton repräsentiert jeweils eine Option, die ein-
  6605. oder ausgeschalten sein kann. Durch Anklicken des Buttons
  6606. wird entweder ein Kreuz in das Auswahlquadrat gezeichnet
  6607. oder gelöscht. Im Gegensatz zu den Radiobuttons gibt es in-
  6608. nerhalb einer Gruppe von Chekbuttons keine Verbindung zwi-
  6609. schen den einzelnen Elementen. Deshalb können Sie ein
  6610. einzelnes Checkbutton unabhängig von den anderen Checkbut-
  6611. tons der Gruppe ein- und ausschalten.
  6612. Die Programmierung von Checkbuttons erfolgt in der gleichen
  6613. Art und Weise wie die Programmierung der Radiobuttons. Mit
  6614. dem Befehl
  6615.  
  6616. SetCheckButton(x,y:integer; Bez:str25);
  6617.  
  6618. erzeugen Sie ein Checkbutton. Die Angabe einer Gruppennummer
  6619. ist natürlich nicht notwendig, da alle Checkbuttons völlig
  6620. unabhängig voneinander sind.
  6621.  
  6622. Beispiel
  6623. Einfacher Druckerdialog mit Radio- und Checkbuttons
  6624.  
  6625. ...
  6626. type PDruckerDlg=^TDruckerDlg;
  6627.      TDruckerDlg=object(TDlgWindow)
  6628.       constructor Init(x,y:integer);
  6629.       ...
  6630.      end;
  6631.  
  6632. ...
  6633.  
  6634. procedure TApplication.SetDialogData;
  6635. begin
  6636.   PrintDialogData.Schalter:='TTGRrrrrGrRrCGcccS';
  6637. end;
  6638. ...
  6639.  
  6640.  
  6641.  
  6642.  
  6643.  
  6644. Programmierhandbuch                                 WG-Vision - 119 -
  6645.  
  6646.  
  6647.  
  6648.  
  6649.  
  6650.  
  6651.  
  6652. procedure TApplication.DruckerDialog;
  6653. var Window:PDruckerDlg;
  6654. begin
  6655.   Window:=new(PDruckerDlg, Init(60,80));
  6656.   InsertDesktop(Window);
  6657. end;
  6658.  
  6659. {Implementation TDruckerDlg}
  6660.  
  6661. constructor TDruckerDlg.Init(x,y:integer);
  6662. var RR:TRect;
  6663. begin
  6664.   RR.Assign(x,y,x+380,y+310);
  6665.   TDlgWindow.Init(RR,'Drucker-Dialog',winDouble+winPanel));
  6666.   SetPushButton(190,270,80,22,'OK',cmCloseWindow);
  6667.   SetPushButton(285,270,80,22,'Abbrechen'),cmCancel);
  6668.   SetGroupFrame(20,40,180,140,'Druckertyp',NormWidth);
  6669.    SetRadioButton(40,70,'~M~atrixdrucker',1);              {1.Gruppe}
  6670.    SetRadioButton(40,90,'~L~aserdrucker',1);
  6671.    SetRadioButton(40,110,'~T~ypenraddrucker',1);
  6672.    SetRadioButton(40,130,'~B~ubble-Jet',1);
  6673.    SetRadioButton(40,150,'T~h~ermodrucker',1);
  6674.   SetGroupFrame(220,40,135,90,'Auflösung',NormWidth);
  6675.    SetRadioButton(240,70,'~3~00 dpi',2);                   {2.Gruppe}
  6676.    SetRadioButton(240,90,'~1~60 dpi',2);
  6677.    SetRadioButton(240,110,' ~7~5 dpi',2);
  6678.    SetCheckButton(225,165,'~E~inzelblatt');
  6679.   SetGroupFrame(20,200,155,88,'',ThickWidth);
  6680.    SetCheckButton(40,225,'~F~ett');
  6681.    SetCheckButton(40,245,'~K~ursiv');
  6682.    SetCheckButton(40,265,'~U~nterstrichen');
  6683.   SetStaticText(195,210,'Drucker-Dialog',LeftText);
  6684.    SetTextParameters(TSCRFont,HorizDir,1);
  6685.    ChangePalColor(10,Red);
  6686.   SetData(PrintDialogData);
  6687. end;
  6688.  
  6689.  
  6690.  
  6691.  
  6692.  
  6693.  
  6694. Programmierhandbuch                                 WG-Vision - 120 -
  6695.  
  6696.  
  6697.  
  6698.  
  6699.  
  6700.  
  6701.  
  6702. Die Abfrage, ob ein Checkbutton gesetzt ist oder nicht,
  6703. erfolgt genauso wie bei den Radiobuttons:
  6704.  
  6705. if Schalter[13]='C' then
  6706.  
  6707. 5.2.7.1. Farbgestaltung von Radio- und Checkbuttons
  6708.  
  6709. Für die Farben der Radio- und Checkbuttons ist die Standard-
  6710. palette Palette5 zuständig. Es gilt folgendes Palettenlay-
  6711. out:
  6712.  
  6713. Eintrag    Bedeutung                      Standard
  6714.  
  6715.    1       Markierungskreis/-kästchen     #0   Schwarz
  6716.    2       Hintergrund                    #15  Weiß
  6717.    3       Kreisscheibe / Kreuz           #8   Dunkelgrau
  6718.    4       Text, aktiv                    #0   Schwarz
  6719.    5       Text, inaktiv                  #7   Grau
  6720.    6       Aktiv-Rahmen                   #8   Dunkelgrau
  6721.  
  6722. Der Aktivrahmen wird punktiert um den Bezeichner eines fo-
  6723. kussierten Dialogelements (außer Pushbuttons) gezeichnet.
  6724. Zur Änderung eines Paletteneintrags kann auch hier die Me-
  6725. thode ChangePalColor verwendet werden.
  6726.  
  6727. 5.2.8. Textfelder (Edit-Controls)
  6728.  
  6729. Die Eingabe von Zeichenketten (Wörter, Zahlen) in
  6730. Maskenfelder wird sehr oft benötigt. WG-Vision stellt mit
  6731. SetInputLine eine Methode zur Verfügung, mit der sehr leicht
  6732. Eingabemasken aufgebaut werden können. Mit diesem Befehl
  6733. erzeugen Sie ein Rechteck, das Ihre Eingaben aufnehmen kann.
  6734. Innerhalb der Maske stehen Ihnen die wichtigsten
  6735. Editierfunktionen zur Verfügung:
  6736.  
  6737.  
  6738.  
  6739.  
  6740.  
  6741.  
  6742.  
  6743.  
  6744. Programmierhandbuch                                 WG-Vision - 121 -
  6745.  
  6746.  
  6747.  
  6748.  
  6749.  
  6750.  
  6751.  
  6752. ^H, Backspace   Zeichen links vom Kursor löschen
  6753. ^Y              gesamte Eingabezeile löschen
  6754. ^T              ab Kursorposition bis Zeilenende löschen
  6755. ^G, Del         Zeichen an der Kursorposition löschen
  6756.  
  6757. End, Ende       Kursor hinter den letzten Buchstaben der
  6758.                 Eingabezeile setzen
  6759. Home, Pos1      Kursor an den Anfang der Eingabezeile setzen
  6760.  
  6761.  
  6762. Syntax
  6763.  
  6764. SetInputLine(x,y,xl:integer;Bez:str25;MaxLen:byte;Zeich:ZMenge);
  6765.  
  6766. x,y      Position der linken oberen Ecke der Eingabemaske
  6767. xl       Länge der Eingabemaske in Zeichen
  6768. MaxLen   Maximallänge der einzugebenden Zeichenkette. Dieser
  6769.          Wert muß mit der im Dialogrecord definierten
  6770.          Stringlänge übereinstimmen (s.u.).
  6771. Zeich    Erlaubte Zeichen (nur diese können eingegeben
  6772.          werden)
  6773.  
  6774.          Ziffern   = ['0'..'9','.','-']
  6775.          ASCII     = [' '..'■']
  6776.         Character  = ['A'..'Z',á'..'z','Ä','Ö',
  6777.                       'Ü','ä','ö','ü','ß']
  6778.  
  6779. Wenn MaxLen>xl ist, erfolgt innerhalb der Maske ein Rollen.
  6780.  
  6781.  
  6782.  
  6783.  
  6784.  
  6785.  
  6786.  
  6787.  
  6788.  
  6789.  
  6790.  
  6791.  
  6792.  
  6793.  
  6794. Programmierhandbuch                                 WG-Vision - 122 -
  6795.  
  6796.  
  6797.  
  6798.  
  6799.  
  6800.  
  6801.  
  6802. 5.2.8.1. Datenübergabe von und in Eingabefelder
  6803.  
  6804. Eingabefelder benutzen zum Datenaustausch mit ihrer Umgebung
  6805. den Dialogrecord. Dieser Record muß um die Definitionen der
  6806. Übergabefelder ergänzt werden. Für einen einfachen Adressen-
  6807. erfassungs-Dialog könnte er beispielsweise folgendermaßen
  6808. aussehen:
  6809.  
  6810. ...
  6811.  
  6812. type tAdressData=record
  6813.                    Schalter : string[7];
  6814.                    Firma    : string[40];
  6815.                    PLZ      : string[5];
  6816.                    Ort      : string[25];
  6817.                    Strasse  : string[30];
  6818.                    Telefon  : string[20];
  6819.                  end;
  6820.  
  6821. var Adresse:tAdressData;
  6822. ...
  6823.  
  6824. Wichtig für die Funktionalität ist, daß die Stringlängen,
  6825. wie sie im Dialogrecord definiert sind, mit dem Parameter
  6826. MaxLen von SetInputLine übereinstimmen.
  6827. Die Initialisierung der Adress-Variablen erfolgt bei Objekt-
  6828. übergreifender Nutzung innerhalb von TApplication.SetDialog-
  6829. Data:
  6830.  
  6831.  
  6832.  
  6833.  
  6834.  
  6835.  
  6836.  
  6837.  
  6838.  
  6839.  
  6840.  
  6841.  
  6842.  
  6843.  
  6844. Programmierhandbuch                                 WG-Vision - 123 -
  6845.  
  6846.  
  6847.  
  6848.  
  6849.  
  6850.  
  6851.  
  6852. procedure TApplication.SetDialogData;
  6853. begin
  6854.   with Adresse do
  6855.    begin
  6856.      Schalter:='TTLLLLLS';
  6857.      FillChar(Firma,SizeOf(Firma),' ');
  6858.      FillChar(PLZ,SizeOf(PLZ),' ');
  6859.      FillChar(Ort,SizeOf(Ort),' ');
  6860.      FillChar(Strasse,SizeOf(Strasse),' ');
  6861.      FillChar(Telefon,SizeOf(Telefon),' ');
  6862.    end;
  6863. end;
  6864.  
  6865. Bei der Initialisierung eines Dialogrecords sind folgende
  6866. Punkte zu beachten:
  6867.  
  6868. - "Schalter" muß immer als Erstes Element implementiert
  6869.    werden !
  6870.  
  6871. - Zeichenketten müssen vollständig aufgefüllt sein:
  6872.   Def. z:string5;   z:='ab'; (falsch)  z:='   ab'; (richtig)
  6873.  
  6874. - lange Zeichenketten zuerst mit Leerzeichen füllen, dann
  6875.   erst Zuweisung eines Anfangswertes
  6876.   z.B. FillChar(Ort,SizeOf(Ort),' '); Ort:='Zittau';
  6877.  
  6878. Ein Dialogrecord wird von der Leseroutinen eines aktiven
  6879. Dialogelements direkt aus dem Speicher gelesen: Das Objekt
  6880. TInputLine benutzt dafür folgende Routine (Unit WDlg):
  6881.  
  6882. procedure TInputLine.SetData(var Rec);
  6883. var i:integer;
  6884. begin
  6885.   Data:='';
  6886.   for i:=1 to DataLen do Data:=Data+char(mem[SSeg:ofs(Rec)+i] );
  6887.   for i:=DataLen downto 1 do
  6888.    if Data[i]=' ' then delete(Data,i,1) else Exit;
  6889. end;
  6890.  
  6891.  
  6892.  
  6893.  
  6894. Programmierhandbuch                                 WG-Vision - 124 -
  6895.  
  6896.  
  6897.  
  6898.  
  6899.  
  6900.  
  6901.  
  6902. Data ist das Feld in TInputLine, in dem die editierbare Zei-
  6903. chenkette aufgebaut wird. Der untypisierte Record wird zur
  6904. Laufzeit von TDlgWindow.SetData zur Verfügung gestellt. In-
  6905. nerhalb dieser Routine wird aus dem Dialogrecord gemäß der
  6906. Typdefinition des Records und der Reihenfolge der Implemen-
  6907. tierung der Dialogelemente ein Teilrecord erzeugt, der TIn-
  6908. putLine.SetData übergeben wird. Daraus extrahiert die
  6909. Routine den Anfangswert für die Eingabezeile, die letztend-
  6910. lich in Data gespeichert wird. Da das Längenbyte eines
  6911. Strings in diesem Zusammenhang nicht zu gebrauchen ist, wer-
  6912. den die Leerzeichen am Ende der Zeichenkette zur Identifika-
  6913. tion nicht benötigter Zeichen verwendet. Die Verwendung
  6914. nullterminierter Strings hätte die Datenübergabe vom Dialog-
  6915. record in ein Dialogfenster stark vereinfacht. Aus Kompati-
  6916. bilitätsgründen zu Turbo-Pascal 6.0 konnte diese Art von
  6917. Strings (sie werden erst ab BP7 unterstützt) jedoch nicht
  6918. verwendet werden.
  6919. Das Auslesen der Datenfelder aus den Dialogelementen zurück
  6920. in den Dialogrecord wird von der Methode GetDataRec
  6921. (TDlgWindow) gewährleistet.
  6922.  
  6923. Lesen des Dialogrecords
  6924.  
  6925. procedure TDlgWindow.SetData(var Rec);
  6926. var LfdPtr:PGroup;
  6927.     i,j,k:integer;
  6928.     Wert:string;
  6929.     ch:char;
  6930. begin
  6931.   RecAdr:=ofs(Rec);                     {Offsett-Adresse von Rec merken}
  6932.   k:=0; Wert:=0;
  6933.   with DlgList^ do           {gesamte Liste der Dialogelemente abackern}
  6934.    begin
  6935.      for i:=1 to AnzElem       (= Anzahl implementierter Dialogelemente}
  6936.       begin
  6937.         ch:=char(mem[DSeg:ofs(Rec)+i]);            {"Schalter" auslesen}
  6938.         Wert:=Wert+ch;      {Zeichenkette "DlgElemente" zusammenbasteln}
  6939.  
  6940.  
  6941.  
  6942.  
  6943.  
  6944. Programmierhandbuch                                 WG-Vision - 125 -
  6945.  
  6946.  
  6947.  
  6948.  
  6949.  
  6950.  
  6951.  
  6952. {Radio- oder Checkbutton ?}
  6953.  
  6954.         if (UpCase(ch)='R') or (UpCase(ch)='C') then
  6955.          begin
  6956.            LfdPtr:=GetItems(i);          {Radio- oder Checkbutton holen}
  6957.            LfdPtr^.SetData(ch);                       {Daten überhelfen}
  6958.          end;
  6959.         DlgElemente:=Wert;                {ist identisch mit "Schalter"}
  6960.  
  6961. {Offsett-Index für das Erste Zeichen des nächsten Dialogrecord-Eintrags}
  6962.  
  6963.         k:=AnzElem+1;
  6964.         for i:=1 to DlgList^.AnzElem do
  6965.  
  6966. {Eingabezeile, Zählschalter (L) oder Listbox (B) ?}
  6967.  
  6968.         case DlgElemente[i] of
  6969.          'L' : begin
  6970.                  Wert:='';
  6971.                  LfdPtr:=GetItems(i);       {Pointer auf Dialog-Element}
  6972.                  Anz:=PInputLine(LfdPtr)^.DataLen;    {wieviele Zeichen}
  6973.                                                                {lesen ?}
  6974.  
  6975. {Übergaberecord zusammenbasteln}
  6976.  
  6977.                  for j:=1 to Anz do
  6978.                   Wert:=Wert+char(mem[DSeg:ofs(Rec)+k+j]);
  6979.                  k:=Anz+k+1;                       {neuer Offsett-Index}
  6980.                  LfdPtr^.SetData(Wert);                {Daten übergeben}
  6981.                end;
  6982.          'B' : begin
  6983.                  Wert:='';
  6984.                  LfdPtr:=GetItems(i);       {Pointer auf Dialog-Element}
  6985.                  Anz:=PListBox(LfdPtr)^.DataLen;      {wieviele Zeichen}
  6986.                                                                {lesen ?}
  6987.  
  6988.  
  6989.  
  6990.  
  6991.  
  6992.  
  6993.  
  6994. Programmierhandbuch                                 WG-Vision - 126 -
  6995.  
  6996.  
  6997.  
  6998.  
  6999.  
  7000.  
  7001.  
  7002. {Übergaberecord zusammenbasteln}
  7003.  
  7004.                  for j:=1 to Anz do
  7005.                   Wert:=Wert+char(mem[DSeg:ofs(Rec)+k+j]);
  7006.                  k:=Anz+k+1;                       {neuer Offsett-Index}
  7007.                  LfdPtr^.SetData(Wert);                {Daten übergeben}
  7008.                end;
  7009.         end; {case}
  7010.       end;
  7011.    end;
  7012. end;
  7013.  
  7014. Schreiben des Dialogrecords
  7015.  
  7016. procedure TDlgWindow.GetDataRec;
  7017. var LfdPtr:PGroup;
  7018.     i,j,k,l:integer;
  7019.     ch:char;
  7020.     Wert:string;
  7021.     Anz:word;
  7022. begin
  7023.   if not DlgInput then Exit;                {nur passive Dialogelemente}
  7024.   with DlgList^ do
  7025.    for i:=1 to AnzElem do
  7026.     begin
  7027.       LfdPtr:=GetItems(i);
  7028.       ch:=DlgElemente[i];
  7029.  
  7030. {Status der Radio- und Checkbuttons auslesen}
  7031.  
  7032.       if (UpCase(ch)='R') or (UpCase(ch)='C') then
  7033.        begin
  7034.          if TypeOf(LfdPtr^)=TypeOf(TRadioButton) then
  7035.           if PRadioButton(LfdPtr)^.Gesetzt then DlgElemente[i]:='R'
  7036.            else DlgElemente[i]:='r';
  7037.          if TypeOf(LfdPtr^)=TypeOf(TCheckButton) then
  7038.           if PCheckButton(LfdPtr)^.Gesetzt then DlgElemente[i]:='C'
  7039.            else DlgElemente[i]:='c';
  7040.        end;
  7041.  
  7042.  
  7043.  
  7044. Programmierhandbuch                                 WG-Vision - 127 -
  7045.  
  7046.  
  7047.  
  7048.  
  7049.  
  7050.  
  7051.  
  7052.       mem[DSeg:RecAdr+1]:=byte(DlgElemente[i]);          {zurück in den}
  7053.                                                           {Dialogrecord}
  7054.     end;
  7055.  
  7056. {Eingabewerte der Eingabezeilen, Zählschalter und Listboxen
  7057. zurückschreiben}
  7058.  
  7059.   k:=DlgList^.AnzElem+1;
  7060.   for i:=1 to DlgList^.AnzElem do
  7061.    case DlgElemente[i] of
  7062.     'L' : begin
  7063.             LfdPtr:=DlgList^.GetItems(i);
  7064.             Wert:=PInputLine(LfdPtr)^.Data;
  7065.             l:=length(Wert);
  7066.             Anz:=PInputLine(LfdPtr)^.DataLen;
  7067.             for j:=l+1 to Anz do Wert:=Wert+' ';
  7068.             for j:=1 to Anz do mem[DSeg:RecAdr+k+j]:=byte(Wert[j]);
  7069.             k:=Anz+k+l;
  7070.           end;
  7071.     'B' : begin
  7072.             LfdPtr:=DlgList^.GetItems(i);
  7073.             Wert:=PListBox(LfdPtr)^.Data;
  7074.             l:=length(Wert);
  7075.             Anz:=PListBox(LfdPtr)^.DataLen;
  7076.             for j:=l+1 to Anz do Wert:=Wert+' ';
  7077.             for j:=1 to Anz do mem[DSeg:RecAdr+k+j]:=byte(Wert[j]);
  7078.             k:=Anz+k+l;
  7079.           end;
  7080.    end; {case}
  7081. end;
  7082.  
  7083. Bei der Erweiterung der Toolbox um neue aktive Dialogelemen-
  7084. te müssen diese beiden Methoden u.U. angepaßt werden.
  7085.  
  7086.  
  7087.  
  7088.  
  7089.  
  7090.  
  7091.  
  7092.  
  7093.  
  7094. Programmierhandbuch                                 WG-Vision - 128 -
  7095.  
  7096.  
  7097.  
  7098.  
  7099.  
  7100.  
  7101.  
  7102. 5.2.8.2. Farbgestaltung von TInputLine-Objekten
  7103.  
  7104. Für die Farben der Eingabezeilen ist die Standardpalette
  7105. Palette5 zuständig. Es gilt folgendes Palettenlayout:
  7106.  
  7107. Eintrag    Bedeutung                      Standard
  7108.  
  7109.    1       Rechteck um das Eingabefeld    #0   Schwarz
  7110.    2       Hintergrund                    #15  Weiß
  7111.    3       wird nicht verwendet
  7112.    4       Text, aktiv    (Bezeichner)    #0   Schwarz
  7113.    5       Text, inaktiv  (Bezeichner)    #7   Grau
  7114.    6       Aktiv-Rahmen um Bezeichner     #8   Dunkelgrau
  7115.    7       Text im Eingabefeld            #0   Schwarz
  7116.  
  7117. Zur Änderung eines Paletteneintrags kann auch hier die
  7118. Methode ChangePalColor verwendet werden.
  7119.  
  7120. Komplexbeispiel    Mini-Adreßdatenbank
  7121.  
  7122. Das Programm MiniDB zeigt am Beispiel einer einfachen Adreß-
  7123. Datenbank die Programmierung von Eingabemasken aus TInputLi-
  7124. ne-Objekten. Besondere Aufmerksamkeit wird dem Austausch von
  7125. Messages zwischen einzelnen Programmteilen (z.B. Datenerfas-
  7126. sungsfenster und Browse-Fenster) gelegt. Außerdem zeigt das
  7127. Programm exemplarisch, wie mit Dateien in WG-Vision-Program-
  7128. men umgegangen werden muß.
  7129.  
  7130. Aufgabenstellung
  7131. Das Programm MiniDB soll in der Lage sein, Adreßdaten zu er-
  7132. fassen und sie in einem Browse-Fenster darstellen. Die Daten
  7133. werden in einer Datei mit wahlfreien Zugriff verwaltet. Be-
  7134. reits erstellte Adreßdateien sollen geladen und neue Adreß-
  7135. dateien erzeugt werden. Die Eingabe ist über einen Eingabe-
  7136. Dialog zu realisieren.
  7137. Weiterhin sind alle Menüpunkte und Dialogelemente zu sper-
  7138. ren, wenn ihre Funktion nicht sinnvoll ist.
  7139.  
  7140.  
  7141.  
  7142.  
  7143.  
  7144. Programmierhandbuch                                 WG-Vision - 129 -
  7145.  
  7146.  
  7147.  
  7148.  
  7149.  
  7150.  
  7151.  
  7152. {Mini-Adressdatenbank zur Demonstration der Arbeit mit TInputLine-
  7153. Objekten}
  7154.  
  7155. program Mini_Adressdatenbank;
  7156.  
  7157. uses WApp,
  7158.      WEvent,
  7159.      WDecl,
  7160.      WViews,
  7161.      WDriver,
  7162.      WDlg,
  7163.      WFileDlg,
  7164.      WUtils,
  7165.      WText,
  7166.      dos,
  7167.      graph;
  7168.  
  7169.  
  7170. const cmOpen      = 101;
  7171.       cmSave      = 102;
  7172.       cmErfassen  = 201;
  7173.       cmBlaettern = 202;
  7174.       cmBrowse    = 203;
  7175.  
  7176. {Diese Konstanten werden nur innerhalb des Objekts TErfassen benötigt}
  7177.  
  7178.       cmLeft      = 90;   {zum Blättern innerhalb des Anzeige-Fenster}
  7179.       cmRight     = 91;
  7180.  
  7181.       msgDraw     = 100;
  7182.  
  7183.  
  7184.  
  7185.  
  7186.  
  7187.  
  7188.  
  7189.  
  7190.  
  7191.  
  7192.  
  7193.  
  7194. Programmierhandbuch                                 WG-Vision - 130 -
  7195.  
  7196.  
  7197.  
  7198.  
  7199.  
  7200.  
  7201.  
  7202. type TApplication=object(TApp)
  7203.        FName : PathStr;
  7204.        procedure InitMenuBar; virtual;
  7205.        procedure SetDialogData; virtual;
  7206.        procedure HandleEvent; virtual;
  7207.        procedure LoadFile;                          {Adreßdatei laden}
  7208.        procedure NewFile;                  {Neue Adreßdatei erstellen}
  7209.        procedure BrowseWindow;           {Scrollfenster zum "browsen"}
  7210.        procedure Erfassen(Mode:boolean);                {Eingabemaske}
  7211.      end;
  7212.  
  7213. {Browse-Fenster}
  7214.  
  7215.      PNewScroller=^TNewScroller;
  7216.  
  7217.      PScrollWindow=^TScrollWindow;
  7218.      TScrollWindow=object(TWindow)
  7219.        Scroller:PNewScroller;
  7220.        procedure InitWindowScroller; virtual;
  7221.        procedure HandleEvent; virtual;
  7222.        destructor Done; virtual;
  7223.      end;
  7224.  
  7225.      TNewScroller=object(TScroller)
  7226.        procedure CreateData;
  7227.        procedure ScrollDraw; virtual;
  7228.      end;
  7229.  
  7230. {Eingabemaske für die Adreßdaten und Anzeige für den Menüpunkt Blättern}
  7231.  
  7232.      PErfassen=^TErfassen;
  7233.      TErfassen=object(TDlgWindow)
  7234.       PosIndex:word;
  7235.       constructor Init(DInput:boolean);
  7236.       destructor Done; virtual;
  7237.       procedure DeleteDataRecord;
  7238.       procedure HandleEvent; virtual;
  7239.      end;
  7240.  
  7241.  
  7242.  
  7243.  
  7244. Programmierhandbuch                                 WG-Vision - 131 -
  7245.  
  7246.  
  7247.  
  7248.  
  7249.  
  7250.  
  7251. {Datenrecord für Datei}
  7252.  
  7253.      tAdressData   =record
  7254.                       Firma    : string[40];
  7255.                       PLZ      : string[5];
  7256.                       Ort      : string[25];
  7257.                       Strasse  : string[30];
  7258.                       Telefon  : string[15]
  7259.                     end;
  7260.  
  7261. {Dialog-Record}
  7262.  
  7263.      tAdressDataRec=record
  7264.                       Schalter : string[9];
  7265.                       Adr      : tAdressData;   {hilft wirtschaften ...}
  7266.                     end;
  7267.  
  7268. var MyApp:TApplication;
  7269.     AdressData:tAdressDataRec;   {Dialogrecord}
  7270.     Adresse:tAdressData;         {Adressen-Record}
  7271.     dat:file of tAdressData;     {Datenbank-Datei}
  7272.  
  7273. procedure TApplication.InitMenuBar;
  7274. begin
  7275.   MainMenu('~D~atei',0);
  7276.    SubMenu('~A~dressen laden',cmOpen,0,0,false,false);
  7277.    SubMenu('~N~eue Adreßdatei',cmSave,0,0,false,false);
  7278.    NewLine;
  7279.    SubMenu('E~x~it  Alt-X',cmCloseApplication,0,altX,false,false);
  7280.  
  7281. Alle Menüpunkte unter "Bearbeiten" sind beim Programmstart gesperrt
  7282. (Parameter true). Das ist sinnvoll, weil dem Programm zu diesem Zeit-
  7283. punkt noch nicht bekannt ist, welche Datei konkret bearbeitet werden
  7284. soll
  7285.  
  7286.   MainMenu('~B~earbeiten',0);
  7287.    SubMenu('~A~dressen Erfassen',cmErfassen,0,0,true,false);
  7288.    SubMenu('~B~lättern',cmBlaettern,0,0,true,false);
  7289.    SubMenu('B~r~owse',cmBrowse,0,0,true,false);
  7290. end;
  7291.  
  7292.  
  7293.  
  7294. Programmierhandbuch                                 WG-Vision - 132 -
  7295.  
  7296.  
  7297.  
  7298.  
  7299.  
  7300.  
  7301.  
  7302. {Initialisierung der Werte für die Eingabemaske}
  7303.  
  7304. procedure TApplication.SetDialogData;
  7305. begin
  7306.   with AdressData do
  7307.    begin
  7308.      Schalter:='TTTLLLLLS';
  7309.      FillChar(Adr.Firma,SizeOf(Adr.Firma),' ');
  7310.      FillChar(Adr.PLZ,SizeOf(Adr.PLZ),' ');
  7311.      FillChar(Adr.Ort,SizeOf(Adr.Ort),' ');
  7312.      FillChar(Adr.Strasse,SizeOf(Adr.Strasse),' ');
  7313.      FillChar(Adr.Telefon,SizeOf(Adr.Telefon),' ');
  7314.    end;
  7315. end;
  7316.  
  7317. procedure TApplication.HandleEvent;
  7318. var i:integer;
  7319. begin
  7320.   Heap^.ShowHeapStatus(523,8,White);
  7321.   TProgram.HandleEvent;
  7322.   case Event.Command of
  7323.    cmOpen      : LoadFile;
  7324.    cmSave      : NewFile;
  7325.    cmErfassen  : Erfassen(true);
  7326.    cmBlaettern : Erfassen(false);
  7327.    cmBrowse    : BrowseWindow;
  7328.   end; {case}
  7329.  
  7330. Die Fenster LoadFile und NewFile senden die Messages msgLoadFile und
  7331. msgSaveFile sowie in Event.InfoString den jeweils ausgewählten bzw. ein-
  7332. gegebenen Dateinamen inklusive vollständiger Pfadangabe. Diese Messages
  7333. werden hier abgefangen um den Applikationsobjekt den Dateinamen zu über-
  7334. geben.
  7335.  
  7336.   if Event.Message=msgLoadFile then
  7337.    begin
  7338.      FName:=Event.InfoString;
  7339.  
  7340.  
  7341.  
  7342.  
  7343.  
  7344. Programmierhandbuch                                 WG-Vision - 133 -
  7345.  
  7346.  
  7347.  
  7348.  
  7349.  
  7350.  
  7351.  
  7352. Sobald ein gültiger Dateiname verfügbar ist, kann die Sperrung des Menüs
  7353. "Bearbeiten" aufgehoben werden
  7354.  
  7355.      for i:=1 to 3 do MMenu[2]^.SbMenu[i]^.DeAktiviere;
  7356.      ClearMessage;
  7357.    end;
  7358.   if Event.Message=msgSaveFile then
  7359.    begin
  7360.  
  7361. Wurde bei der Eingabe des Dateinamens keine Extension angegeben, dann
  7362. wird sie hier angehängt. Die Adreßdateien bekommen die Extension .DBS
  7363.  
  7364.      if Pos('.',Event.Infostring)=0 then FName:=Event.InfoString+'.DBS'
  7365.       else FName:=Event.InfoString;
  7366.      MMenu[2]^.SbMenu[1]^.DeAktiviere;
  7367.      ClearMessage;
  7368.    end;
  7369. end;
  7370.  
  7371. Die Objekte TInputDialog und TOutputDialog werden aus der Unit WFileDlg
  7372. importiert. Diese Unit ist Bestandteil von WG-Vision
  7373.  
  7374. procedure TApplication.LoadFile;
  7375. var Window:PInputDialog;
  7376. begin
  7377.   Window:=new(PInputDialog, Init('Dateiauswahl','*.DBS'));
  7378.   InsertDesktop(Window);
  7379. end;
  7380.  
  7381. procedure TApplication.NewFile;
  7382. var Window:POutputDialog;
  7383. begin
  7384.   Window:=new(POutputDialog, Init('Neue Adreß-Datei'));
  7385.   InsertDesktop(Window);
  7386. end;
  7387.  
  7388.  
  7389.  
  7390.  
  7391.  
  7392.  
  7393.  
  7394. Programmierhandbuch                                 WG-Vision - 134 -
  7395.  
  7396.  
  7397.  
  7398.  
  7399.  
  7400.  
  7401.  
  7402. procedure TApplication.BrowseWindow;
  7403. var R:TRect;
  7404.     Window:PScrollWindow;
  7405. begin
  7406.   R.Assign(20,60,616,446);
  7407.   Window:=new(PScrollWindow, Init(R,'BROWSE-Fenster',
  7408.               winDouble+winPanel+winMenu+winKey));
  7409.   InsertDesktop(Window);
  7410. end;
  7411.  
  7412. In diesem Programm wird das Fenster Erfassen für zwei verschiedene
  7413. Zwecke benutzt. Einmal dient es zur Verwaltung der Eingabemaske für die
  7414. Adreßdaten und zum anderen wird es zum "Blättern" innerhalb der Adreß-
  7415. datenbank verwendet. Die Unterscheidung zwischen diesen beiden Funktio-
  7416. nen geschieht über die logische Variable Mode. Sie wird an das Objekt
  7417. TErfassen weitergeleitet (im Konstruktor)
  7418.  
  7419. procedure TApplication.Erfassen(Mode:boolean);
  7420. var Window:PErfassen;
  7421.     i:integer;
  7422. begin
  7423.   Window:=new(PErfassen, Init(Mode));
  7424.   InsertDesktop(Window);
  7425.  
  7426. Sobald eine Datei eröffnet ist, können dem Nutzer auch die Menüpunkte
  7427. "Blättern" und "Browse" zugänglich gemacht werden
  7428.  
  7429.   for i:=2 to 3 do MMenu[2]^.SbMenu[i]^.DeAktiviere;
  7430. end;
  7431.  
  7432. {Implementation TScrollWindow}
  7433.  
  7434. procedure TScrollWindow.InitWindowScroller;
  7435. var R:TRect;
  7436.     SBH1,SBV1:PScrollBar;
  7437. begin
  7438.   R:=Frame^.Area;
  7439.   SBH1:=new(PScrollBar, Init(R,HorizDir));
  7440.   SBV1:=new(PScrollBar, Init(R,VertDir));
  7441.  
  7442.  
  7443.  
  7444. Programmierhandbuch                                 WG-Vision - 135 -
  7445.  
  7446.  
  7447.  
  7448.  
  7449.  
  7450.  
  7451.  
  7452.   Scroller:=new(PNewScroller, Init(R,SBH1,SBV1));
  7453.   Scroller^.CreateData;
  7454.   List^.InsertItem(Scroller);
  7455. end;
  7456.  
  7457. procedure TScrollWindow.HandleEvent;
  7458. begin
  7459.   TWindow.HandleEvent;
  7460.  
  7461. Da das Browse-Fenster nichtmodal ist, kann während es aufgeblendet ist
  7462. auch die Eingabemaske aktiv sein, d.h. es sind weitere Adreßeingaben
  7463. möglich. Sobald die Erfassung abgeschlossen ist, muß das Browse-Fenster
  7464. aktualisiert werden. Um das zu erreichen, wird zuerst die Datenliste im
  7465. Heap gelöscht und danach wieder neu aufgebaut (in CreateData). Anschlie-
  7466. ßend wird der Scroller mit den aktualisierten Daten neu aufgeblendet
  7467. (Draw). Ausgelöst wird dieser Vorgang durch die Message msgDraw, welche
  7468. das Erfassungsfenster sendet, wenn es geschlossen wird
  7469.  
  7470.   if Event.Message=msgDraw then
  7471.    begin
  7472.      with Scroller^ do
  7473.       begin
  7474.         Createdata;
  7475.         Draw;
  7476.       end;
  7477.      ClearMessage;     {wichtig !}
  7478.    end;
  7479. end;
  7480.  
  7481. destructor TScrollWindow.Done;
  7482. begin
  7483.   TWindow.Done;
  7484.   dispose(Scroller, Done);
  7485. end;
  7486.  
  7487.  
  7488.  
  7489.  
  7490.  
  7491.  
  7492.  
  7493.  
  7494. Programmierhandbuch                                 WG-Vision - 136 -
  7495.  
  7496.  
  7497.  
  7498.  
  7499.  
  7500.  
  7501.  
  7502. {Implementation TNewScroller}
  7503.  
  7504. procedure TNewScroller.CreateData;
  7505. var LfdPtr:PLine;
  7506. begin
  7507.   SetFont(Wndw19);
  7508.  
  7509. Erst einmal nachschauen, ob eine Datenliste bereits vorhanden ist (wegen
  7510. Aktualisierung !) und wenn ja, dann Inhalt löschen
  7511.  
  7512.   if Liste<>nil then Liste^.DeleteItems;
  7513.  
  7514. Datei zum Lesen öffnen
  7515.  
  7516.   assign(dat,MyApp.FName);
  7517.   reset(dat);
  7518.  
  7519. Adreßdaten in die Liste einlesen. Da die Liste nur Strings aufnehmen
  7520. kann und deren Länge bekanntlich begrenzt ist (256 Zeichen), paßt die
  7521. Telefonnummer nicht mehr hinein.
  7522.  
  7523.   while not EOF(dat) do
  7524.    begin
  7525.      LfdPtr:=new(PLine, Init);
  7526.      read(dat,Adresse);
  7527.      with Adresse do
  7528.       LfdPtr^.Eintrag:=Firma+' │ '+PLZ+' │ '+Ort+' │ '+Strasse;
  7529.      Liste^.InsertItem(LfdPtr);
  7530.    end;
  7531.   SetLimit(25,Liste^.AnzElem,8,16);
  7532.   close(dat);
  7533. end;
  7534.  
  7535. procedure TNewScroller.ScrollDraw;
  7536. var i:integer;
  7537.     LfdPtr:PGroup;
  7538.  
  7539.  
  7540.  
  7541.  
  7542.  
  7543.  
  7544. Programmierhandbuch                                 WG-Vision - 137 -
  7545.  
  7546.  
  7547.  
  7548.  
  7549.  
  7550.  
  7551.  
  7552. function clip(p,n:byte;z:string):string;
  7553. begin
  7554.   clip:=copy(z,p,n);
  7555. end;
  7556.  
  7557. begin
  7558.   SetFontColor(White,Blue);
  7559.   Mouse.HideMouse;
  7560.   with Border do
  7561.    begin
  7562.      SetFillStyle(SolidFill,GetPalColor(1));
  7563.      SetColor(GetPalColor(2));
  7564.      for i:=Delta.y to WDelta.y do
  7565.       begin
  7566.         LfdPtr:=Liste^.GetItems(i);
  7567.         Bar(A.x,A.y+(i-Delta.y)*Py+10,B.x,A.y+(i-Delta.y)*Py+10+Py);
  7568.         WriteText(A.x+20,A.y+(i-Delta.y)*Py+10,clip(Delta.x,
  7569.                   Spalten*8 div 8-5,PLine(LfdPtr)^.Eintrag));
  7570.       end;
  7571.      if VertiScrollBar<>nil then
  7572.       for i:=(WDelta.y-Delta.y)+1 to Zeilen do
  7573.        Bar(A.x,A.y+i*Py+10,B.x,A.y+i*Py+10+Py);
  7574.    end;
  7575.   Mouse.ShowMouse;
  7576. end;
  7577.  
  7578. {Implementation Erfassen}
  7579.  
  7580. constructor TErfassen.Init(DInput:boolean);
  7581. var RR:TRect;
  7582. begin
  7583.   PosIndex:=0;                   {Position des Satzzeigers in der Datei}
  7584.   RR.Assign(60,80,440,350);            {Position und Größe des Fensters}
  7585.  
  7586. An dieser Stelle muß die Datei geöffnet werden. Der Konstruktor wird
  7587. immer nur einmal, nämlich in dem Augenblick, wo das Fenster geöffnet
  7588. wird, durchlaufen. Das Schließen der Datei erfolgt dann logischerweise
  7589. im Destructor Done des Fensters. Aus diesem Grund muß der Destructor
  7590. auch überschrieben werden, da diese Arbeit aus begreiflichen Gründen der
  7591.  
  7592.  
  7593.  
  7594. Programmierhandbuch                                 WG-Vision - 138 -
  7595.  
  7596.  
  7597.  
  7598.  
  7599.  
  7600.  
  7601.  
  7602. Destruktor des TDlgWindow-Objektes nicht übernehmen kann. Beim Öffnen
  7603. der Datei muß weiterhin untersucht werden, ob die Adressendatei bereits
  7604. existiert (Öffnen zum Anhängen von neuen Datensätzen) oder ob eine neue
  7605. Datei erst erzeugt werden muß. Diese Frage läßt sich in diesem Beispiel-
  7606. programm eindeutig durch Überprüfung von IOResult beantworten.
  7607.  
  7608.   assign(dat,MyApp.FName);
  7609.   {$I-}
  7610.   reset(dat);
  7611.   {$I+}
  7612.   if IOResult=0 then            {Existiert Datei ?}
  7613.    begin
  7614.      if not DInput then         {Blättern}
  7615.       begin
  7616.  
  7617. Ersten Datensatz lesen, und AdressData damit initialisieren, damit
  7618. sofort der erste Datensatz aufgeblendet wird.
  7619.  
  7620.         read(dat,Adresse);                          {1. Datensatz lesen}
  7621.         AdressData.Adr:=Adresse;           {Dialogrecord initialisieren}
  7622.         SetData(AdressData);                       {Dialogrecord setzen}
  7623.       end
  7624.       else
  7625.       begin
  7626.  
  7627. Datensatzzeiger an das Ende der Datei positionieren und leere Eingabe-
  7628. maske vorbereiten.
  7629.  
  7630.         DeleteDataRecord;
  7631.         seek(dat,FileSize(dat));
  7632.       end;
  7633.    end
  7634.    else rewrite(dat);                               {neue Datei anlegen}
  7635.  
  7636. Fensterobjekt initialisieren und gestalten
  7637.  
  7638.   TDlgWindow.Init(RR,'Erfassen von Adressen',winDouble+winPanel);
  7639.   SetPushButton(134,225,100,22,'OK',cmCloseWindow);
  7640.  
  7641.  
  7642.  
  7643.  
  7644. Programmierhandbuch                                 WG-Vision - 139 -
  7645.  
  7646.  
  7647.  
  7648.  
  7649.  
  7650.  
  7651.  
  7652. Die Methode SetDisabled schaltet ein Dialogelement gewissermaßen ab. Das
  7653. bedeutet, daß solch ein Dialogelement aus dem Eventhandler des Fensters
  7654. ausgeschlossen ist und damit nicht mehr auf Ereignisse reagieren kann.
  7655. Es ist gewissermaßen totgelegt. Auf dem Bildschirm wird es durch seine
  7656. farbliche Gestaltung besonders hervorgehoben.
  7657.  
  7658.   SetPushButton(260,225,40,22,'<<',cmLeft);
  7659.    if DInput then SetDisabled;
  7660.   SetPushButton(310,225,40,22,'>>',cmRight);
  7661.    if DInput then SetDisabled;
  7662.   SetInputLine(140,90,25,'~F~irma    :',40,ASCII);
  7663.    if not DInput then SetDisabled;
  7664.   SetInputLine(140,115,5,'~P~LZ      :',5,ZIFFERN);
  7665.    if not DInput then SetDisabled;
  7666.   SetInputLine(140,140,20,'~O~rt      :',25,ASCII);
  7667.    if not DInput then SetDisabled;
  7668.   SetInputLine(140,165,20,'~S~traße   :',30,ASCII);
  7669.    if not DInput then SetDisabled;
  7670.   SetInputLine(140,190,15,'~T~elefon  :',15,ZIFFERN);
  7671.    if not DInput then SetDisabled;
  7672.  
  7673. Statischer Text in Rot unter Verwendung des Triplex-Fonts.
  7674.  
  7675.    if DInput then SetStaticText(40,35,'Adressenerfassung',LeftText)
  7676.     else SetStaticText(40,35,'Blättern in der Datei',LeftText);
  7677.    SetTextParameters(TriplexFont,HorizDir,2);
  7678.    ChangePalColor(10,Red);
  7679.  
  7680. Anfangswerte des Diaslogrecords an das Fenster übergeben.
  7681.  
  7682.   SetData(AdressData);
  7683. end;
  7684.  
  7685. destructor TErfassen.Done;
  7686. begin
  7687.   close(dat);                                  {Adressendatei schließen}
  7688.   TDlgWindow.Done;
  7689. end;
  7690.  
  7691.  
  7692.  
  7693.  
  7694. Programmierhandbuch                                 WG-Vision - 140 -
  7695.  
  7696.  
  7697.  
  7698.  
  7699.  
  7700.  
  7701.  
  7702. Dialogrecord mit Leerzeichen belegen. Da die Eingabezeilen direkt auf
  7703. die Werte im Dialogrecord zugreifen, ist es zum Aufblenden einer leere
  7704. Maske unumgänglich, den Dialogrecord zu "löschen".
  7705.  
  7706. procedure TErfassen.DeleteDataRecord;
  7707. begin
  7708.   with AdressData do
  7709.    begin
  7710.      FillChar(Adr.Firma,SizeOf(Adr.Firma),' ');
  7711.      FillChar(Adr.PLZ,SizeOf(Adr.PLZ),' ');
  7712.      FillChar(Adr.Ort,SizeOf(Adr.Ort),' ');
  7713.      FillChar(Adr.Strasse,SizeOf(Adr.Strasse),' ');
  7714.      FillChar(Adr.Telefon,SizeOf(Adr.Telefon),' ');
  7715.    end;
  7716.   SetData(AdressData);                               {nicht vergessen !}
  7717. end;
  7718.  
  7719. Und hier eine der wichtigsten Routinen. Innerhalb des Eventhandlers des
  7720. Erfassungsfensters erfolgt die eigentliche Datenübernahme in die Datei.
  7721.  
  7722. procedure TErfassen.HandleEvent;
  7723.  
  7724. Hilfsroutine zum Lesen eines Datensatzes aus der Adressendatei. Diese
  7725. Routine wird zum Blättern benötigt.
  7726.  
  7727. procedure ReadDataRecord;
  7728. begin
  7729.   seek(dat,PosIndex);                         {Satzzeiger positionieren}
  7730.   read(dat,Adresse);                                  {Adresse auslesen}
  7731.   AdressData.Adr:=Adresse;             {Dialogrecord mit Adresse füllen}
  7732.   SetData(AdressData);         {Dialogrecord dem Fenster bekannt machen}
  7733.   DrawMask;                                         {Maske neu zeichnen}
  7734.   Event.Command:=cmNothing;                           {Kommando löschen}
  7735. end;
  7736.  
  7737.  
  7738.  
  7739.  
  7740.  
  7741.  
  7742.  
  7743.  
  7744. Programmierhandbuch                                 WG-Vision - 141 -
  7745.  
  7746.  
  7747.  
  7748.  
  7749.  
  7750.  
  7751.  
  7752. begin
  7753.   TDlgWindow.HandleEvent;
  7754.  
  7755. Die Message msgNewMask wird direkt von WG-Vision gesendet. Immer wenn
  7756. eine Eingabemaske nach unten mit <Cursor><Down> verlassen wird, wird
  7757. diese Message auf die Reise geschickt. Dadurch kann der Programmierer
  7758. auf den Fakt reagieren, daß die Maske ausgefüllt ist und die Daten über-
  7759. nommen werden können. In unserem Beispiel wird nach Speicherung des
  7760. Adress-Records in der Datei sofort eine leere Maske aufgeblendet und die
  7761. Eingabe der nächsten Adresse kann erfolgen.
  7762.  
  7763.   if Event.Message=msgNewMask then
  7764.    begin
  7765.      Adresse:=AdressData.Adr;  {Adresse aus dem Dialogrecord übernehmen}
  7766.      write(dat,Adresse);                {Adresse in die Datei schreiben}
  7767.      DeleteDataRecord;             {Dialogrecord mit Leerzeichen füllen}
  7768.      DrawMask;                            {neue Eingabemaske aufblenden}
  7769.  
  7770. An dieser Stelle sendet das Fenster eine Mitteilung an das Browse-Fen-
  7771. ster. Da dieses Fenster durchaus auf dem Bildschirm präsent sein kann
  7772. (es ist jedoch deaktiviert, da ein Dialogfenster immer modal ist), muß
  7773. es sich nach dem Schließen des Erfassungsfenster an die neuen Daten an-
  7774. passen, d.h. es muß jetzt auch ohne Zutun des Nutzers die neu eingegebe-
  7775. nen Datensätze richtig anzeigen. Da sein Eventhandler erst nach dem
  7776. Schließen des Erfassungsfenster auf Messages reagieren kann, erfolgt na-
  7777. türlich auch erst dann die Neuanpassung des Scrollbereiches.
  7778.  
  7779.      Event.Message:=msgDraw;          {Mitteilung an das Browse-Fenster}
  7780.    end;
  7781.  
  7782. Diese Kommandos können nur im Blätter-Modus abgesetzt werden.
  7783.  
  7784.   if Event.Command=cmRight then
  7785.    if FilePos(dat)<FileSize(dat) then
  7786.     begin
  7787.       inc(PosIndex);                              {nach Rechts blättern}
  7788.       ReadDataRecord;
  7789.     end;
  7790.   if Event.Command=cmLeft then
  7791.  
  7792.  
  7793.  
  7794. Programmierhandbuch                                 WG-Vision - 142 -
  7795.  
  7796.  
  7797.  
  7798.  
  7799.  
  7800.  
  7801.  
  7802.    if PosIndex>0 then
  7803.     begin
  7804.       dec(PosIndex);                               {nach links blättern}
  7805.       ReadDataRecord;
  7806.     end;
  7807. end;
  7808.  
  7809. {Hauptprogramm}
  7810.  
  7811. begin
  7812.   MyApp.Init('Adressen-Datenbank');
  7813.   MyApp.Run;
  7814.   MyApp.Done;
  7815. end.
  7816.  
  7817. Das Program MiniDB ist natürlich vollausbaufähig. Wenn Sie
  7818. eine kleine Adressenverwaltung benötigen, dann sollten Sie
  7819. diesem Programm weitere Funktionen hinzufügen. Es dürfte
  7820. beispielsweise nicht schwierig sein, eine Editier- und
  7821. Druckfunktion einzubauen.
  7822.  
  7823. Hinweis:
  7824. Beobachten Sie bitte bei der Abarbeitung dieses Programms
  7825. einmal den Heapwächter. Sie werden feststellen, das 8888
  7826. Bytes nicht wieder freigegeben werden. Der Grund liegt in
  7827. diesem Fall nicht in einer fehlerhaften Programmierung son-
  7828. dern in dem Umstand, daß WG-Vision den Vektorzeichensatz
  7829. TriplexFont in den Heap geladen hat. Dieser Font kann in der
  7830. jetzigen Version von WG-Vision nicht mehr aus dem Speicher
  7831. entfernt werden. Das ist zwar traurig, aber wahr.
  7832.  
  7833.  
  7834.  
  7835.  
  7836.  
  7837.  
  7838.  
  7839.  
  7840.  
  7841.  
  7842.  
  7843.  
  7844. Programmierhandbuch                                 WG-Vision - 143 -
  7845.  
  7846.  
  7847.  
  7848.  
  7849.  
  7850.  
  7851.  
  7852. 5.2.8.3. Aufbau von Eingabemasken
  7853.  
  7854. Eingabemasken haben insbesonders bei Datenbankanwendungen
  7855. eine zentrale Bedeutung. Um die Programmierung von Eingabe-
  7856. masken zu vereinfachen, besitzt WG-Vision intern bereits ei-
  7857. nige Routinen, die die Verwaltung von Eingabemasken
  7858. unterstützen. Ob sie genutzt werden, hängt von der jeweili-
  7859. gen Aufgabenstellung ab.
  7860. Eine Eingabemaske unter WG-Vision besitzt folgende Eigen-
  7861. schaften:
  7862.  
  7863. - Jedes Eingabefeld ist voll editierbar. Das wird dadurch
  7864.   gewährleistet, daß ein Eingabefeld in WG-Vision ein
  7865.   TInputLine-Objekt ist
  7866.  
  7867. - Die Eingabefelder einer Eingabemaske sind unabhängig von
  7868.   anderen Dialogelementen (Druckschalter, Radio- und
  7869.   Checkbuttons) fokussierbar. In WG-Vision erfolgt die
  7870.   Fokussierung eines Dialogelementes mittels der Tabulator-
  7871.   Taste (bzw. <Shift><Tab>). Zusätzlich dazu lassen sich
  7872.   Maskenfelder mittels der Tasten <Cursor><Up> und
  7873.   <Cursor><Down> zyklisch (also von den anderen Dialog-
  7874.   elementen entkoppelt) fokussieren.
  7875.  
  7876. - Eine Eingabemaske muß unabhängig vom Fenster neu
  7877.   darstellbar sein (Methode DrawMask).
  7878.  
  7879. - Wenn eine Eingabemaske nach unten verlassen wird, sendet
  7880.   WG-Vision die Message msgNewMask aus (unabhängig davon, ob
  7881.   in die Maske Daten eingegeben wurden oder nicht). Diese
  7882.   Mitteilung kann genutzt werden, um die Maskendaten
  7883.   abzuspeichern und eine neue leere Maske aufzublenden
  7884.   (siehe Komplexbeispiel MINIDB).
  7885.  
  7886. - In einem Dialogfenster werden alle TInputLine-Objekte zu
  7887.   einer Maske vereinigt. Mehrere individuelle Masken in
  7888.   einem Dialogfenster sind nicht möglich.
  7889.  
  7890.  
  7891.  
  7892.  
  7893.  
  7894. Programmierhandbuch                                 WG-Vision - 144 -
  7895.  
  7896.  
  7897.  
  7898.  
  7899.  
  7900.  
  7901.  
  7902. 5.2.9. Zählschalter
  7903.  
  7904. Ein direkter Nachkomme von TInputLine ist der sogenannte
  7905. Zählschalter (TNumButton). Mit dem Zählschalter können Zah-
  7906. len in festzulegenden Grenzen und Schrittweiten herauf- und
  7907. herabgezählt werden. Außerdem lassen sich Zahlen auch direkt
  7908. eingeben und genauso wie Zeichenketten editieren.
  7909. Ein Zählschalter unterscheidet sich von einer Eingabezeile
  7910. durch zwei Schalter, die entweder übereinander oder rechts
  7911. oder links vom Eingabefeld angeordnet sein können. Indem Sie
  7912. diese Schalter betätigen, können Sie einen Wert im Eingabe-
  7913. feld herauf- oder herunterzählen. Die Schalter werden dazu
  7914. entweder mit der Maus angeklickt oder mit den Tasten <Cur-
  7915. sor><Up> und <Cursor><Down> bedient (natürlich nur, wenn der
  7916. Zählschalter fokussiert ist). Die Fokussierung erfolgt ent-
  7917. weder mittels der Tabulator-Taste, dem Shortkey (in Verbin-
  7918. dung mit <alt>) oder durch Anklicken des Eingabebereichs mit
  7919. der Maus.
  7920.  
  7921. Syntax
  7922.  
  7923. SetNumButton(x,y,xl:integer;Bez:str25;MaxLen,TTyp:byte;
  7924.              Min,Max,Step,Format:real);
  7925.  
  7926. x,y      Position der linken oberen Ecke der Eingabemaske
  7927. xl       Länge der Eingabemaske in Zeichen
  7928. Bez      Bezeichner
  7929. MaxLen   Maximallänge der einzugebenden Zeichenkette. Dieser
  7930.          Wert muß mit der im Dialogrecord definierten
  7931.          Stringlänge übereinstimmen
  7932.  
  7933. TTyp     Anordnung der Tasten:   1 übereinander
  7934.                                  2 nebeneinander
  7935.  
  7936. Min      Minimalwert, bis auf den heruntergezählt wird
  7937. Max      Maximalwert, bis auf den heraufgezählt wird
  7938. Step     Schrittweite
  7939. Format   legt die Anzahl der Vor- und Nachkommastellen fest
  7940.  
  7941.  
  7942.  
  7943.  
  7944. Programmierhandbuch                                 WG-Vision - 145 -
  7945.  
  7946.  
  7947.  
  7948.  
  7949.  
  7950.  
  7951.  
  7952. Der Anfangswert für den Zählschalter wird im Dialogrecord
  7953. festgelegt. Im String "Schalter" wird ein TNumButton-Objekt
  7954. genauso wie die Eingabezeile mit L codiert.
  7955. Das folgende kleine Programmfragment könnte einem Drucker-
  7956. dialog entnommen sein. Durch die Eingaben über drei
  7957. Zählschalter soll angegeben werden von und bis zu welcher
  7958. Seite ein Dokument ausgedruckt werden soll und in wieviel
  7959. Exemplaren:
  7960.  
  7961. Dialogrecord deklarieren
  7962.  
  7963. ...
  7964.  
  7965. type tPrintPages=record
  7966.                    Schalter:string[4];
  7967.                    VonSeite:string[3];
  7968.                    BisSeite:string[3];
  7969.                    Exemplare:string[2];
  7970.                  end;
  7971.  
  7972. var PPages:tPrintPages;
  7973.  
  7974. Dialogrecord mit Anfangswerten belegen
  7975.  
  7976. procedure TApplication.SetDialogData;
  7977. begin
  7978.   with PPages do
  7979.    begin
  7980.      Schalter:='SLLL';
  7981.      VonSeite:='  1';              {unbedingt Leerzeichen mit angeben !}
  7982.      BisSeite:='  1';
  7983.      Exemplare:=' 1';
  7984.    end;
  7985. end;
  7986. ...
  7987.  
  7988. Neues Dialogfenster in die Windowliste einfügen
  7989.  
  7990.  
  7991.  
  7992.  
  7993.  
  7994. Programmierhandbuch                                 WG-Vision - 146 -
  7995.  
  7996.  
  7997.  
  7998.  
  7999.  
  8000.  
  8001.  
  8002. procedure TApplication.NewWindow;
  8003. var Window:PNewWindow;
  8004. begin
  8005.   Window:=new(PNewWindow, Init);
  8006.   InsertDesktop(Window);
  8007. end;
  8008. ...
  8009.  
  8010. Dialogfenster mit einem statischen Text und drei Zählschal-
  8011. tern
  8012.  
  8013. constructor TNewWindow.Init;
  8014. var RR:TRect;
  8015. begin
  8016.   RR.Assign(60,80,300,280);
  8017.   TDlgWindow.Init(RR,'Fenster mit Zählschalter',
  8018.                   winDouble+winPanel+winMenu+winKey);
  8019.   SetStaticText(20,40,'Dokument drucken',LeftText);
  8020.    ChangePalColor(10,Red);
  8021.   SetNumButton(20,100,3,'~V~on',3,1,1,999,1,3.0);
  8022.   SetNumButton(135,100,3,'~B~is',3,1,1,999,1,3.0);
  8023.   SetNumButton(40,155,2,'~E~xemplare',2,2,1,99,1,2.0);
  8024.   SetData(PPages);                    │ │ │ │  │  └─ 2 Vorkommastellen
  8025. end;                                  │ │ │ │  └─ Schrittweite
  8026. ...                                   │ │ │ └─ Maximalwert
  8027.                                       │ │ └─ Minimalwert
  8028.                                       │ └─ Schaltertyp
  8029.                                       └─ Maximallänge
  8030.  
  8031. Bei den ersten beiden Zählschaltern werden die Tasten über-
  8032. einander rechts neben das Eingabefeld gezeichnet (TTyp 1).
  8033. Beim Dritten Zählschalter befindet sich jeweils rechts und
  8034. links neben dem Eingabefeld ein Schalter. Der Text wird auch
  8035. hier rechts daneben geschrieben. Sie können übrigens die Po-
  8036. sition des Bezeichners relativ zum Fenster beliebig mit dem
  8037. Befehl
  8038.  
  8039. SetTextPosition(x,y:integer)
  8040.  
  8041.  
  8042.  
  8043.  
  8044. Programmierhandbuch                                 WG-Vision - 147 -
  8045.  
  8046.  
  8047.  
  8048.  
  8049.  
  8050.  
  8051.  
  8052. verändern. Bedingung ist, daß Sie diesen Befehl gleich un-
  8053. terhalb von SetNumButton anordnen bzw. vor dem nächsten neu-
  8054. en Dialogelement (analog ChangePalColor im obigen Beispiel).
  8055.  
  8056. Für die Farbgestaltung sind die Paletten 4 (Drucktasten) und
  8057. 5 (eigentlicher Zählschalter) zuständig.
  8058. Ein Beispiel für die Anwendung von Zählschaltern ist das
  8059. Objekt TPalWorkShop in der Unit WPalette.
  8060.  
  8061.  
  8062.  
  8063.  
  8064.  
  8065.  
  8066.  
  8067.  
  8068.  
  8069.  
  8070.  
  8071.  
  8072.  
  8073.  
  8074.  
  8075.  
  8076.  
  8077.  
  8078.  
  8079.  
  8080.  
  8081.  
  8082.  
  8083.  
  8084.  
  8085.  
  8086.  
  8087.  
  8088.  
  8089.  
  8090.  
  8091.  
  8092.  
  8093.  
  8094. Programmierhandbuch                                 WG-Vision - 148 -
  8095.  
  8096.  
  8097.  
  8098.  
  8099.  
  8100.  
  8101.  
  8102. 5.2.10. Listboxen
  8103.  
  8104. Listboxen sind rechteckige Bereiche innerhalb eines Dialog-
  8105. fensters, die mit einem oder zwei Rollbalken ausgestattet
  8106. sind. Sie enthalten zeilenweise Zeichenketten (z.B. Dateina-
  8107. men), die sich mit einem Auswahlbalken auswählen lassen.
  8108. Zur Implementation in ein Dialogfenster reicht es nicht aus,
  8109. mit dem Befehl SetListBox(...) einen Zeiger auf die Stan-
  8110. dard-Listbox in die Dialogelementeliste DlgList des Dialog-
  8111. fensters einzufügen. Die Methode SetListbox ist als virtual
  8112. deklariert und muß in einem konkreten Anwendungsfall über-
  8113. schrieben werden. Das ist deshalb notwendig, um der Listbox
  8114. zu sagen, was sie eigentlich auflisten soll. Bevor wir in
  8115. einem kleinen Beispiel die Vorgehensweise näher beleuchten,
  8116. hier erst einmal die Syntax des Befehls:
  8117.  
  8118. Syntax
  8119.  
  8120. SetListBox(x,y,xl,yl:integer;Bez:str25;LScroller:word);
  8121.  
  8122. x,y        Koordinaten der linken oberen Ecke der Listbox
  8123. xl,yl      Breite und Länge der Listbox
  8124. Bez        Bezeichner (wird standardmäßig linksbündig über
  8125.            die Listbox geschrieben. Position läßt sich aber
  8126.            mit SetTextPosition relativ zum Dialogfenster
  8127.            verändern
  8128.  
  8129. LScroller  Rollbalken:  VScrBar  nur vertikaler Rollbalken
  8130.                         HScrBar  nur horizontaler Rollbalken
  8131.                         DScrBar  beide Rollbalken
  8132.  
  8133.  
  8134.  
  8135.  
  8136.  
  8137.  
  8138.  
  8139.  
  8140.  
  8141.  
  8142.  
  8143.  
  8144. Programmierhandbuch                                 WG-Vision - 149 -
  8145.  
  8146.  
  8147.  
  8148.  
  8149.  
  8150.  
  8151.  
  8152. Beispiel: Fenster mit einer Listbox, in der alle Dateien des
  8153.           Hauptverzeichnisses aufgelistet werden
  8154.  
  8155. Da wir die Listbox mit Daten (hier Dateinamen) füllen
  8156. wollen, müssen wir von TListBox ein neues Objekt ableiten:
  8157.  
  8158. type PDateiListBox=^TDateiListBox;
  8159.      TDateiListBox=object(TListBox)
  8160.       procedure CreateDataList;
  8161.      end;
  8162. ...
  8163.  
  8164. Außerdem muß die Methode SetListBox überschrieben werden:
  8165.  
  8166. type PNewWindow=^TNewWindow;
  8167.      TNewWindow=object(TDlgWindow)
  8168.       constructor Init;
  8169.       procedure SetListBox(x,y,xl,yl:integer;Bez:str25;
  8170.                            LScroller:word); virtual;
  8171.      end;
  8172. ...
  8173.  
  8174. Zum Schluß müssen wir für das Fenster TNewWindow noch einen
  8175. Dialogrecord zur Verfügung stellen:
  8176.  
  8177. type tLBoxData=record
  8178.                  Schalter:string[2];
  8179.                  DName:string[12];
  8180.                end;
  8181.  
  8182. var LBoxData:tLBoxData;
  8183.  
  8184. Die Variable DName enthält nach dem Schließen des Dialogfen-
  8185. sters den Dateinamen in der Listbox, auf welchem der Aus-
  8186. wahlbalken zuletzt gestanden hat.
  8187.  
  8188.  
  8189.  
  8190.  
  8191.  
  8192.  
  8193.  
  8194. Programmierhandbuch                                 WG-Vision - 150 -
  8195.  
  8196.  
  8197.  
  8198.  
  8199.  
  8200.  
  8201.  
  8202. Dialogdaten setzen:
  8203.  
  8204. procedure TApplication.SetDialogData;
  8205. begin
  8206.   with LBoxData do
  8207.    begin
  8208.      Schalter:='TB';
  8209.      FillChar(DName,SizeOf(DName),' ');
  8210.    end;
  8211. end;
  8212.  
  8213. Eine Listbox wird in der Stringvariablen Schalter mit dem
  8214. Buchstaben `B' codiert.
  8215.  
  8216. SetListBox überschreiben:
  8217.  
  8218. procedure TNewWindow.SetListBox(x,y,xl,yl:integer;
  8219.                                 Bez:str25;LScroller:word);
  8220. var LBox:PDateiListBox;                          {neues TListBox-Objekt}
  8221. begin
  8222.   TDlgWindow.SetListBox(x,y,xl,yl,Bez,LScroller);
  8223.   LBox:=new(PDateiListBox, Init(R,Bez,SBH,SBV));
  8224.   with LBox^ do
  8225.    begin
  8226.      CreateDataList;
  8227.  
  8228. Koordinaten in P merken, damit bei Verschiebungen des Fensters die
  8229. Listbox wieder an die richtige relative Position gezeichnet werden kann.
  8230.  
  8231.      P.x:=x; P.y:=y;
  8232.    end;
  8233.   DlgList^.InsertItem(LBox);
  8234. end;
  8235.  
  8236. In der Methode CreateDataList werden der Listbox die Daten
  8237. übergeben, die sie konkret auflisten soll. Zu diesem Zweck
  8238. mußte ein neues Objekt von TListBox abgeleitet werden, deren
  8239.  
  8240.  
  8241.  
  8242.  
  8243.  
  8244. Programmierhandbuch                                 WG-Vision - 151 -
  8245.  
  8246.  
  8247.  
  8248.  
  8249.  
  8250.  
  8251.  
  8252. Methode CreateDataList dann die Daten bereitstellt. Wir ver-
  8253. wenden wieder eine Liste im Heap, um die Dateinamen abzu-
  8254. speichern:
  8255.  
  8256. procedure TDateiListBox.CreateDataList;
  8257. var SRec:SearchRec;
  8258.     LfdPtr:PLine;
  8259. begin
  8260.   FindFirst('\*.*',Archive,SRec);
  8261.   if SRec.Name<>'' then
  8262.    repeat
  8263.      LfdPtr:=new(PLine, Init);
  8264.      LfdPtr^.Eintrag:=SRec.Name;
  8265.      Liste^.InsertItem(LfdPtr);
  8266.      FindNext(SRec);
  8267.    until DOSError=18;
  8268.  
  8269.   DataLen:=12;   {Sehr wichtig ! Dieser Wert wird in TDlgWindow.SetData}
  8270.                  {benötigt. Er ist identisch mit der Stringlänge in der}
  8271.                                  {Deklaration von DName im Dialogrecord}
  8272.  
  8273.   SetLimit(12,Liste^.AnzElem,8,11);
  8274. end;
  8275.  
  8276.  
  8277.  
  8278.  
  8279.  
  8280.  
  8281.  
  8282.  
  8283.  
  8284.  
  8285.  
  8286.  
  8287.  
  8288.  
  8289.  
  8290.  
  8291.  
  8292.  
  8293.  
  8294. Programmierhandbuch                                 WG-Vision - 152 -
  8295.  
  8296.  
  8297.  
  8298.  
  8299.  
  8300.  
  8301.  
  8302. 5.2.10.1. Farbpalette
  8303.  
  8304. Die Listbox verwendet die Standardpalette Palette5. Folgende
  8305. Einträge sind von Bedeutung:
  8306.  
  8307. Eintrag    Bedeutung                      Standard
  8308.  
  8309.    1       Rahmen der Listbox             #0   Schwarz
  8310.    2       Hintergrund                    #15  Weiß
  8311.    3       wird nicht verwendet
  8312.    4       Text in der Listbox (normal)   #0   Schwarz
  8313.            Bezeichner, aktiv
  8314.    5       Bezeichner, inaktiv            #7   Grau
  8315.    6       Aktiv-Rahmen um Bezeichner     #8   Dunkelgrau
  8316.    7       wird nicht verwendet           #0   Schwarz
  8317.    8       Farbe des Auswahlbalkens       #8   Dunkelgrau
  8318.    9       Text im AuswahlbalkenS         #15  Weiß
  8319.  
  8320.  
  8321. Zur Darstellung der Rollbalken wird die Standardpalette
  8322. Palette3 verwendet.
  8323. Wie bei jedem Dialogelement läßt sich ein Paletteneintrag
  8324. mit ChangePalColor verändern.
  8325.  
  8326. 5.2.11. Zusammenfassung Dialogelemente
  8327.  
  8328. Folgende Methoden von TDlgWindow stehen zur Programmierung
  8329. eines Dialogs zur Verfügung:
  8330.  
  8331. SetPushButton       Druckschalter            passiv
  8332. SetRadioButton      Optionsschaltfläche      aktiv
  8333. SetCheckButton      Kontrollfeld             aktiv
  8334. SetInputLine        Eingabezeile             aktiv
  8335. SetNumButton        Zählschalter             aktiv
  8336. SetListBox          Listbox                  aktiv
  8337. SetGroupFrame       Gruppenrahmen            passiv
  8338. SetStaticText       Statischer Text          passiv
  8339. SetIcon             Icon                     passiv
  8340.  
  8341.  
  8342.  
  8343.  
  8344. Programmierhandbuch                                 WG-Vision - 153 -
  8345.  
  8346.  
  8347.  
  8348.  
  8349.  
  8350.  
  8351.  
  8352. Alle Fenster mit aktiven Dialogelementen benötigen einen
  8353. Dialogrecord, der entweder global (innerhalb des gesamten
  8354. Programms, initialisiert in SetDialogData) oder Objekt-lokal
  8355. (implementiert im Konstruktor des Fensterobjekts) implemen-
  8356. tiert sein muß.
  8357. Folgende Methoden beeinflussen einige Eigenschaften der Dia-
  8358. logelemente:
  8359.  
  8360. ChangePalColor     ändert einen Paletteneintrag
  8361. SetDisabled        deaktiviert ein Dialogelement
  8362. SetTextParameters  ändert die Font-Eigenschaften eines
  8363.                    statischen Textes
  8364. SetTextPosition    verändert die Position eines Bezeichners.
  8365.                    Druckschalter: relativ zur Tastenmitte
  8366.                    übrige Elemente: relativ zum Fenster
  8367.  
  8368.  
  8369. Diese Befehle müssen unterhalb der Implementationsbefehle
  8370. angeordnet werden:
  8371.  
  8372. Beispiel
  8373. ...
  8374.  
  8375. SetInputLine(20,40,80,22,'OK',cmCloseWindow);
  8376.  ChangePalColor(3,Yellow);
  8377.  SetTextPosition(-10,-20);
  8378.  SetDisabled;
  8379. SetStaticText(20,80,'Statischer Text in Rot',LeftText);
  8380.  ChangeColor(10,Red);
  8381. ...
  8382.  
  8383.  
  8384.  
  8385.  
  8386.  
  8387.  
  8388.  
  8389.  
  8390.  
  8391.  
  8392.  
  8393.  
  8394. Programmierhandbuch                                 WG-Vision - 154 -
  8395.  
  8396.  
  8397.  
  8398.  
  8399.  
  8400.  
  8401.  
  8402. Spezialmethoden
  8403.  
  8404. DrawMask           zeichnet eine Eingabemaske neu
  8405. SetData            übergibt einen Dialogrecord an das
  8406.                    Fenster
  8407.  
  8408. InsertChildWindow  Einfügen eines Child-Fensters
  8409. GetFocElem         übergibt den Index des gerade
  8410.                    fokussierten Dialogelements
  8411.  
  8412.  
  8413.  
  8414.  
  8415.  
  8416.  
  8417.  
  8418.  
  8419.  
  8420.  
  8421.  
  8422.  
  8423.  
  8424.  
  8425.  
  8426.  
  8427.  
  8428.  
  8429.  
  8430.  
  8431.  
  8432.  
  8433.  
  8434.  
  8435.  
  8436.  
  8437.  
  8438.  
  8439.  
  8440.  
  8441.  
  8442.  
  8443.  
  8444. Programmierhandbuch                                 WG-Vision - 155 -
  8445.  
  8446.  
  8447.  
  8448.  
  8449.  
  8450.  
  8451.  
  8452. 5.3. Child-Fenster
  8453.  
  8454. In ein Dialogfenster können weitere Fenster, sogenannte
  8455. Childfenster, eingehangen werden. Childfenster werden beim
  8456. Aufbau von Dialogen oft benötigt. Wenn Sie z.B. aus einem
  8457. Drucker-Setup-Dialog einen Drucker aus einer Listbox ausge-
  8458. wählt haben, möchten Sie ihn vielleicht konfigurieren. Zu
  8459. diesem Zweck programmieren Sie ein weiteres Dialogfenster,
  8460. das Sie z.B. über ein Pushbutton aufblenden. Dieses Fenster
  8461. ist dann aber kein Bestandteil der Windowliste des Desktops
  8462. (wie das "Parent"-Fenster), sondern ein dem aufrufenden Fen-
  8463. ster untergeordnetes Window, welches als "Child" nur inner-
  8464. halb des "Parent"-Fensters definiert ist.
  8465. Zum "Einhängen" des Childwindows wird die Methode Insert-
  8466. ChildWindow verwendet.
  8467. In ein Parent-Fenster können beliebig viele Child's einge-
  8468. hangen werden. Ein Child-Fenster selbst darf jedoch keine
  8469. Child-Fenster enthalten. Sonst kommt der Eventhandler von
  8470. WG-Vision gehörig durcheinander, da er nicht für rekursive
  8471. Aufrufe ausgelegt ist.
  8472. Für die Implementierung eines Childfensters gelten die glei-
  8473. chen Regeln wie für jedes normale Dialogfenster. Es lassen
  8474. sich natürlich auch Objekte vom Ausgangstyp TWindow als
  8475. Child's verwenden.
  8476.  
  8477. Prinzipielle Vorgehensweise
  8478.  
  8479. Deklaration des Parent-Fensters
  8480.  
  8481. type PParentWindow=^TParentWindow;
  8482.      TParentWindow=object(TDlgWindow)
  8483.       ...
  8484.       procedure SetChildWindow;         {in dieser Methode erfolgt das}
  8485.                                           {Einhängen des Childfensters}
  8486.      end;
  8487.  
  8488. Deklaration des Child-Fensters
  8489.  
  8490.  
  8491.  
  8492.  
  8493.  
  8494. Programmierhandbuch                                 WG-Vision - 156 -
  8495.  
  8496.  
  8497.  
  8498.  
  8499.  
  8500.  
  8501.  
  8502. type PChildWindow=^TChildWindow;
  8503.      TChildWindow=object(TDlgWindow);
  8504.       constructor Init;
  8505.       ...                               {Eventhandler, Hintergrund etc.}
  8506.      end;
  8507.  
  8508. Implementation von SetChildWindow
  8509.  
  8510. procedure TParentWindow.SetChildWindow;
  8511. var CWindow:PChildWindow;
  8512. begin
  8513.  
  8514. Zunächst benötigen wir einen Zeiger auf unser Childwindow
  8515.  
  8516.   CWindow:=new(PChildWindow, Init);
  8517.  
  8518. Bevor das Childwindow aufgeblendet werden kann, muß das Parentwindow
  8519. deaktiviert werden. Das passiert automatisch (das Childwindow als Nach-
  8520. fahre von TDlgWindow ist ja von Haus aus modal). Lediglich der Rahmen
  8521. muß in Verantwortung des Programmierers neu gezeichnet werden, damit das
  8522. Fenster auch optisch "deaktiviert" ist. Zu diesem Zweck wird die Varia-
  8523. ble FrameDeaktivated auf true gesetzt und das Parentfenster veranlaßt,
  8524. sich selbst neu zu zeichnen.
  8525.  
  8526.   FrameDeaktivated:=true;
  8527.   DrawNewFrame;
  8528.  
  8529. Und jetzt muß sich nur noch das Childfenster aufblenden.
  8530.  
  8531.   CWindow^.Draw;
  8532.  
  8533. Damit auch alle Ereignisse, die dieses Fenster betreffen, vom
  8534. Eventhandler auch richtig ausgewertet werden können, muß das
  8535. Childfenster in die entsprechende Liste des Parentfensters eingebaut
  8536. werden.
  8537.  
  8538.   InsertChildWindow(CWindow);
  8539. end;
  8540.  
  8541.  
  8542.  
  8543.  
  8544. Programmierhandbuch                                 WG-Vision - 157 -
  8545.  
  8546.  
  8547.  
  8548.  
  8549.  
  8550.  
  8551.  
  8552. Das Childfenster muß innerhalb des Eventhandlers des Parent-
  8553. fensters als Reaktion auf ein Kommando (z.B. von einem
  8554. Pushbutton) aufgerufen werden:
  8555.  
  8556. ...
  8557.  
  8558. if Event.Command=cmHelp then SetChildWindow;
  8559. ...
  8560.  
  8561. Zur Laufzeit kann über die logische Variable ChildPresent
  8562. abgetestet werden, ob ein Childfenster gerade aufgeblendet
  8563. ist oder nicht.
  8564.  
  8565.  
  8566. Komplexbeispiel Dialog zur Änderung des Systemdatums und der
  8567.                 Systemzeit
  8568.  
  8569. Aufgabenstellung:
  8570. Ein Dialogfenster, in dem das Systemdatum und die Systemzeit
  8571. editiert werden können, soll mit einer Hilfe-Funktion ausge-
  8572. stattet werden. Dazu ist ein Pushbutton mit der Aufschrift
  8573. "Hilfe" anzulegen und die Ereignisbehandlung so zu gestal-
  8574. ten, daß eine Aktivierung dieses Schalters ein Childwindow
  8575. mit der Hilfe-Information aufblendet.
  8576.  
  8577.  
  8578.  
  8579.  
  8580.  
  8581.  
  8582.  
  8583.  
  8584.  
  8585.  
  8586.  
  8587.  
  8588.  
  8589.  
  8590.  
  8591.  
  8592.  
  8593.  
  8594. Programmierhandbuch                                 WG-Vision - 158 -
  8595.  
  8596.  
  8597.  
  8598.  
  8599.  
  8600.  
  8601.  
  8602. program Datum_und_Zeiteingabe;
  8603.  
  8604. uses WDecl,
  8605.      WApp,
  8606.      WEvent,
  8607.      WDlg,
  8608.      graph,
  8609.      dos;
  8610.  
  8611. const cmDate=101;
  8612.  
  8613. type TApplication=object(TApp)
  8614.       procedure InitMenuBar; virtual;
  8615.       procedure HandleEvent; virtual;
  8616.       procedure SetDate;
  8617.      end;
  8618.  
  8619. Die Methode SetDialogData wird nicht benötigt, da die Initialisierung
  8620. des Dialogrecords erst im Augenblick des Aufblendens des TDateiWindow's
  8621. innerhalb des Konstruktors erledigt wird. Alles andere hätte auch keinen
  8622. Sinn, da ja nicht die Uhrzeit bei Programmstart, sondern die aktuelle
  8623. Uhrzeit editiert werden soll.
  8624.  
  8625.      PDateWindow=^TDateWindow;                           {Parent-Window}
  8626.      TDateWindow=object(TDlgWindow)
  8627.       constructor Init;
  8628.       procedure HandleEvent; virtual;
  8629.       procedure SetHelp;
  8630.      end;
  8631.  
  8632.      PHilfe=^THilfe;                                      {Child-Window}
  8633.      THilfe=object(TDlgWindow)
  8634.       constructor Init;
  8635.      end;
  8636.  
  8637.  
  8638.  
  8639.  
  8640.  
  8641.  
  8642.  
  8643.  
  8644. Programmierhandbuch                                 WG-Vision - 159 -
  8645.  
  8646.  
  8647.  
  8648.  
  8649.  
  8650.  
  8651.  
  8652.      tSetDateTime=record
  8653.                     Schalter:string[5];
  8654.                     Datum:string[10];
  8655.                     Zeit:string[8]
  8656.                   end;
  8657.  
  8658. var MyApp:TApplication;
  8659.     DT:tSetDateTime;
  8660.  
  8661. procedure TApplication.InitMenuBar;
  8662. begin
  8663.   MainMenu('~F~enster',0);
  8664.    SubMenu('~E~instellungen',cmDate,0,0,false,false);
  8665.    SubMenu('E~x~it  Alt-X',cmCloseApplication,0,altX,false,false);
  8666. end;
  8667.  
  8668. procedure TApplication.HandleEvent;
  8669. begin
  8670.   TProgram.HandleEvent;
  8671.   case Event.Command of
  8672.    cmDate : SetDate;
  8673.   end; {case}
  8674. end;
  8675.  
  8676. procedure TApplication.SetDate;
  8677. var Window:PDateWindow;
  8678. begin
  8679.   Window:=new(PDateWindow, Init);
  8680.   InsertDesktop(Window);
  8681. end;
  8682.  
  8683.  
  8684.  
  8685.  
  8686.  
  8687.  
  8688.  
  8689.  
  8690.  
  8691.  
  8692.  
  8693.  
  8694. Programmierhandbuch                                 WG-Vision - 160 -
  8695.  
  8696.  
  8697.  
  8698.  
  8699.  
  8700.  
  8701.  
  8702. {Implementation TDateWindow}
  8703.  
  8704. constructor TDateWindow.Init;
  8705. var RR:TRect; z:string;
  8706.     Jahr,Monat,Tag,Wochentag:word;
  8707.     Stunde,Minute,Sekunde,Sek100:word;
  8708. begin
  8709.   RR.Assign((GetMaxX div 2)-150,140,(GetMaxX div 2)+150,300);
  8710.   TDlgWindow.Init(RR,'Datum & Uhrzeit',winDouble+winPanel+winMenu);
  8711.  
  8712. Das Editieren des Datums und der Uhrzeit erfolgt innerhalb einer Einga-
  8713. bezeile. Zugelassene Zeichen sind nur Ziffern, wobei die Ziffernmenge
  8714. modifiziert wird (bei der Uhrzeit werden als Begrenzer Doppelpunkte ver-
  8715. wendet, beim Datum einfache Punkte).
  8716.  
  8717.   SetInputLine(95,70,10,'~D~atum  ',10,Ziffern-['-']);
  8718.   SetInputLine(95,105,8,'~U~hrzeit',8,Ziffern+[':']-['.','-']);
  8719.   SetPushButton(200,40,80,22,'OK',cmOK);
  8720.   SetPushButton(200,70,80,22,'~A~bbrechen',cmCloseWindow);
  8721.   SetPushButton(200,115,80,22,'~H~ilfe',90);
  8722.  
  8723. An dieser Stelle wird der Dialogrecord zusammengebastelt. Datum und
  8724. Uhrzeit bekommen jeweils die aktuellen Werte und werden als Vorgabe in
  8725. den Eingabezeilen aufgeblendet.
  8726.  
  8727.   with DT do
  8728.    begin
  8729.      Schalter:='LLTTT';
  8730.      Datum:=''; Zeit:='';
  8731.      GetDate(Jahr,Monat,Tag,Wochentag);
  8732.      str(Tag:2,z);
  8733.      Datum:=Datum+z+'.';
  8734.      str(Monat:2,z);
  8735.      Datum:=Datum+z+'.';
  8736.      str(Jahr:4,z);
  8737.      Datum:=Datum+z;
  8738.      GetTime(Stunde,Minute,Sekunde,Sek100);
  8739.      str(Stunde:2,z);
  8740.      Zeit:=Zeit+z+':';
  8741.  
  8742.  
  8743.  
  8744. Programmierhandbuch                                 WG-Vision - 161 -
  8745.  
  8746.  
  8747.  
  8748.  
  8749.  
  8750.  
  8751.  
  8752.      str(Minute:2,z);
  8753.      Zeit:=Zeit+z+':';
  8754.      str(Sekunde:2,z);
  8755.      Zeit:=Zeit+z;
  8756.    end;
  8757.   SetData(DT);
  8758. end;
  8759.  
  8760. procedure TDateWindow.HandleEvent;
  8761. begin
  8762.   TDlgWindow.HandleEvent;
  8763.  
  8764. Wenn die Hilfe-Taste gedrückt wird, muß das Childfenster aufgeblendet
  8765. werden.
  8766.  
  8767.   if Event.Command=90 then SetHelp;
  8768.   if Event.Command=cmOK then
  8769.    begin
  8770.      with DT do
  8771.       begin
  8772.  
  8773.         {und hier kommen die Routinen zum Setzen des neuen
  8774.         Datums und der neuen Uhrzeit hinein. Dazu müssen Sie
  8775.         die Strings Datum und Uhrzeit zerpflücken und die
  8776.         in das word-Format umgewandelten Teilstrings den
  8777.         Routinen SetDate und SetTime übergeben. Vielleicht
  8778.         programmieren Sie diesen Teil einmal selbst ?}
  8779.  
  8780.       end;
  8781.      Event.Command:=cmCloseWindow;
  8782.    end;
  8783. end;
  8784.  
  8785. procedure TDateWindow.SetHelp;
  8786. var HelpWindow:PHilfe;
  8787. begin
  8788.   HelpWindow:=new(PHilfe, Init);
  8789.  
  8790.  
  8791.  
  8792.  
  8793.  
  8794. Programmierhandbuch                                 WG-Vision - 162 -
  8795.  
  8796.  
  8797.  
  8798.  
  8799.  
  8800.  
  8801.  
  8802. Parent-Fenster deaktivierten
  8803.  
  8804.   FrameDeaktivated:=true;
  8805.   DrawNewFrame;
  8806.  
  8807. Childwindow zeichnen und in die entsprechende Liste des Parent-Windows
  8808. einfügen
  8809.  
  8810.   HelpWindow^.Draw;
  8811.   InsertChildWindow(HelpWindow);
  8812. end;
  8813.  
  8814. {Implementation THilfe}
  8815.  
  8816. constructor THilfe.Init;                       {Childwindow}
  8817. var RR:TRect;
  8818. begin
  8819.   RR.Assign((GetMaxX div 2)-100,180,(GetMaxX div 2)+200,340);
  8820.   TDlgWindow.Init(RR,'Hilfe',winDouble+winPanel);
  8821.   SetStaticText(150,45,'Einstellen von',CenterText);
  8822.   SetStaticText(150,75,'Datum und Uhrzeit',CenterText);
  8823.   SetPushButton(110,130,80,22,'OK',cmCloseWindow);
  8824. end;
  8825.  
  8826. {Hauptprogramm}
  8827.  
  8828. begin
  8829.   MyApp.Init('Demonstration Childfenster');
  8830.   MyApp.Run;
  8831.   MyApp.Done;
  8832. end.
  8833.  
  8834.  
  8835.  
  8836.  
  8837.  
  8838.  
  8839.  
  8840.  
  8841.  
  8842.  
  8843.  
  8844. Programmierhandbuch                                 WG-Vision - 163 -
  8845.  
  8846.  
  8847.  
  8848.  
  8849.  
  8850.  
  8851.  
  8852. 5.4. Programmierung einer Iconleiste
  8853.  
  8854. Iconleisten oder Toolbars sind bei Windows-Programmierern
  8855. sehr beliebt. Sie erlauben die schnelle Auswahl von Komman-
  8856. dos ohne erst das Pull-Down-Menü bemühen zu müssen. Außerdem
  8857. sehen sie gut aus und, das soll nicht verschwiegen werden,
  8858. sie geben einem Programm ein professionelles Flair. In die-
  8859. sem Abschnitt möchte ich zeigen, wie man unter Ausnutzung
  8860. eines einfachen passiven Dialogfensters mit wenig Aufwand
  8861. eine Iconleiste programmieren kann.
  8862. Diese Iconleiste soll genau unterhalb der Menüzeile positio-
  8863. niert werden. Natürlich ist auch jede andere Position im
  8864. Clientbereich des Desktops denkbar, so z.B. senkrecht am
  8865. linken Rand. Wo die Iconleiste konkret angeordnet wird,
  8866.  bleibt aber letztendlich dem Programmierer überlassen.
  8867. Eine Iconleiste wird erst einmal genauso programmiert wie
  8868. ein normales Dialogfenster. Natürlich wählt man kein ver-
  8869. schiebbares Fenster (also eins mit Panel), sondern einfach
  8870. einen schwarz umrandeten grauen Balken mit den gleichen Ab-
  8871. messungen wie die Hauptmenüzeile:
  8872.  
  8873. ...
  8874.  
  8875. type PIconBar=^TIconBar;
  8876.      TIconBar=object(TDlgWindow)
  8877.       constructor Init;
  8878.       procedure InitBackground; virtual;    {neuer Hintergrund}
  8879.      end;
  8880.  
  8881.      PIconBarBgrd=^TIconBarBgrd;           {grauer Hintergrund}
  8882.      TIconBarBgrd=object(TBackground)
  8883.       procedure Draw; virtual;
  8884.      end;
  8885.  ...
  8886.  
  8887.  constructor TIconBar.Init;
  8888.  var RR:TRect;
  8889.  begin
  8890.  
  8891.  
  8892.  
  8893.  
  8894. Programmierhandbuch                                 WG-Vision - 164 -
  8895.  
  8896.  
  8897.  
  8898.  
  8899.  
  8900.  
  8901.  
  8902. Mit diesem Pointer-Schwanz bestimmen wir die Lage des Innenrahmens vom
  8903. Desktop, in das wir die Iconleiste einpassen wollen. Damit die senkrech-
  8904. ten Linien der Iconleiste mit den senkrechten Linien des Desktop-Innen-
  8905. rahmens zusammenfallen, muß von A.x Eins abgezogen und zu B.x Eins
  8906. dazuaddiert werden.
  8907.  
  8908.    with MyApp.Desktop^.Frame^.Area do RR(Assign(A.x-1,A.y+21,B.x+1,A.y+48);
  8909.  
  8910. Implementation von Druckschaltern mit 16x16 Pixel-Icons. Die Kommandos,
  8911. welche die Pushbuttons absetzen, werden im Eventhandler der Applikation
  8912. abgefangen und ausgewertet.
  8913.  
  8914.    SetPushButton(3,3,0,0,'#ICON.I16/1',80);
  8915.     ChangePalColor(8,LightGray);
  8916.    SetPushButton(28,3,0,0,'#ICON.I16/2',81);
  8917.     ChangePalColor(8,LightGray);
  8918.            ...
  8919.  
  8920.    SetPushButton(400,3,0,0,'#ICON.I16/14',941);
  8921.     ChangePalColor(8,LightGray);
  8922.    WinModal:=true;          {wir wollen das Menü ja auch noch bedienen}
  8923.    IconBarPresent:=true;     {damit sagen wir WG-Vision, daß das erste}
  8924.                                            {Fenster eine Iconleiste ist}
  8925. end;
  8926.  
  8927. Jetzt benötigen wir nur noch ein Applikationsfenster, wel-
  8928. ches die Iconleiste aufnimmt:
  8929.  
  8930. procedure TApplication.IconBar;
  8931. var IBar:PIconBar;
  8932. begin
  8933.   IBar:=new(PIconBar, Init);
  8934.   InsertDesktop(IBar);
  8935. end;
  8936.  
  8937.  
  8938.  
  8939.  
  8940.  
  8941.  
  8942.  
  8943.  
  8944. Programmierhandbuch                                 WG-Vision - 165 -
  8945.  
  8946.  
  8947.  
  8948.  
  8949.  
  8950.  
  8951.  
  8952. Die Icons für die Druckschalter müssen natürlich zuvor mit
  8953. dem Iconeditor erstellt und in der Datei ICON.I16 abgespei-
  8954. chert sein. Das diese Datei zur Laufzeit verfügbar sein muß,
  8955. ist selbstverständlich. Sonst haben Sie nur graue Tasten oh-
  8956. ne Bildchen, also Grau auf Grau.
  8957. Bleibt noch die Frage zu klären, an welcher Stelle des Pro-
  8958. gramms die Iconleiste eingefügt werden soll. Sie darf ja nur
  8959. einmal beim Programmstart geladen werden und muß dann wäh-
  8960. rend des gesamten Programmlaufs aktiv bleiben. Am einfach-
  8961. sten ist es, den Konstruktor der Applikation zu über-
  8962. schreiben und darin die Methode IconBar aufzurufen:
  8963.  
  8964. constructor TApplication.Init(Titel:string);
  8965. begin
  8966.   TApp.Init(Titel);
  8967.   WorkArea.A.y:=WorkArea.A.y+26;
  8968.   IconBar;
  8969. end;
  8970.  
  8971. Außerdem wurde auch gleich das Workarea den neuen Gegeben-
  8972. heiten angepaßt, damit die Fenster nicht über die Iconleiste
  8973. geschoben werden können.
  8974.  
  8975. Hinweis:
  8976. Das wir die Iconleiste direkt von einem Dialogfenster abge-
  8977. leitet haben, hat einige Konsequenzen. Immer dann, wenn ein
  8978. nichtmodales Fenster (z.B. ein TWindow-Objekt) aufgeblendet
  8979. wird, kann die Iconleiste nicht mehr bedient werden. Sie
  8980. wird damit quasi tot gelegt. Das Pull-Down-Menü funktioniert
  8981. natürlich weiter. Deshalb folgender Ratschlag: Rufen Sie
  8982. über die Iconleiste nur modale Fenster, also in erster Linie
  8983. Dialogfenster, auf.
  8984.  
  8985.  
  8986.  
  8987.  
  8988.  
  8989.  
  8990.  
  8991.  
  8992.  
  8993.  
  8994. Programmierhandbuch                                 WG-Vision - 166 -
  8995.  
  8996.  
  8997.  
  8998.  
  8999.  
  9000.  
  9001.  
  9002. Beispiel:
  9003.  
  9004. program MenuTest;
  9005.  
  9006. uses WApp,
  9007.      WDecl,
  9008.      WViews,
  9009.      WDlg,
  9010.      WDriver,
  9011.      WUtils,
  9012.      WFileDlg,
  9013.      WEvent,
  9014.      crt;
  9015.  
  9016. const cmNewWindow   = 101;
  9017.       cmOpen        = 102;
  9018.  
  9019. type TApplication=object(TApp)
  9020.       constructor Init(Titel:string);
  9021.       procedure InitMenuBar; virtual;
  9022.       procedure HandleEvent; virtual;
  9023.       procedure IconBar;
  9024.       procedure NewWindow;
  9025.       procedure Eingabe;
  9026.      end;
  9027.  
  9028.      PIconBar=^TIconBar;
  9029.      TIconBar=object(TDlgWindow)
  9030.       constructor Init;
  9031.       procedure InitBackground; virtual;
  9032.      end;
  9033.  
  9034.      PIconBarBgrd=^TIconBarBgrd;
  9035.      TIconBarBgrd=object(TBackground)
  9036.       procedure Draw; virtual;
  9037.      end;
  9038.  
  9039.  
  9040. var MyApp:TApplication;
  9041.  
  9042.  
  9043.  
  9044. Programmierhandbuch                                 WG-Vision - 167 -
  9045.  
  9046.  
  9047.  
  9048.  
  9049.  
  9050.  
  9051.  
  9052. {Implementation TApplication}
  9053.  
  9054. constructor TApplication.Init(Titel:string);
  9055. begin
  9056.   TApp.Init(Titel);
  9057.   WorkArea.A.y:=WorkArea.A.y+26;
  9058.   IconBar;                                         {Iconleiste einfügen}
  9059. end;
  9060.  
  9061. procedure TApplication.InitMenuBar;
  9062. begin
  9063.   MainMenu('~D~atei',0);
  9064.    SubMenu('~N~eues Fenster',cmNewWindow,0,0,false,false);
  9065.    SubMenu('~D~atei laden',cmOpen,0,0,false,false);
  9066.    NewLine;
  9067.    SubMenu('E~x~it  Alt-X',cmCloseApplication,0,altX,false,false);
  9068.   MainMenu('~B~earbeiten',0);
  9069.    SubMenu('~A~dressen Erfassen',cmNothing,0,0,true,false); {nur Dummys}
  9070.    SubMenu('~B~lättern',cmNothing,0,0,true,false);
  9071.    SubMenu('B~r~owse',cmNothing,0,0,true,false);
  9072. end;
  9073.  
  9074. procedure TApplication.HandleEvent;
  9075. var i:integer;
  9076.     z:string;
  9077.     LfdPtr:PGroup;
  9078. begin
  9079.   TProgram.HandleEvent;
  9080.   case Event.Command of
  9081.    cmNewWindow   : NewWindow;
  9082.    cmOpen        : Eingabe;
  9083.    80..91        : begin                     {unsere erste Messagebox !}
  9084.                      str(Event.Command-79:2,z);
  9085.                      MessageBox(1,'Iconleiste betätigt','Schalter-
  9086.                                   Nummer '+z);
  9087.                    end;
  9088.   end; {case}
  9089. end;
  9090.  
  9091.  
  9092.  
  9093.  
  9094. Programmierhandbuch                                 WG-Vision - 168 -
  9095.  
  9096.  
  9097.  
  9098.  
  9099.  
  9100.  
  9101.  
  9102. procedure TApplication.IconBar;
  9103. var Window:PIconBar;
  9104. begin
  9105.   Window:=new(PIconBar, Init);
  9106.   InsertDesktop(Window);
  9107. end;
  9108.  
  9109. procedure TApplication.NewWindow;
  9110. var R:TRect;
  9111.     Window:PWindow;
  9112. begin
  9113.   R.Assign(60,80,440,280);
  9114.   Window:=new(PWindow,Init(R,'Beispiel',winDouble+winPanel+winMenu+winKey));
  9115.   InsertDesktop(Window);
  9116. end;
  9117.  
  9118. procedure TApplication.Eingabe;
  9119. var Window:PInputDialog;
  9120. begin
  9121.   Window:=new(PInputDialog, Init('Eingabe','*.*'));
  9122.   InsertDesktop(Window);
  9123. end;
  9124.  
  9125. {Implementation TIconBar}
  9126.  
  9127. constructor TIconBar.Init;
  9128. var RR:TRect;
  9129. begin
  9130.   with MyApp.Desktop^.Frame^.Area do
  9131.     RR.Assign(A.x-1,A.y+21,B.x+1,A.y+48);
  9132.   TDlgWindow.Init(RR,'',winSingle);
  9133.   SetPushButton(3,3,0,0,'#ICON.I16/1',cmOpen);
  9134.    ChangePalColor(8,LightGray);
  9135.   SetPushButton(28,3,0,0,'#ICON.I16/2',cmNewWindow);
  9136.    ChangePalColor(8,LightGray);
  9137.   SetPushButton(65,3,0,0,'#ICON.I16/3',80);
  9138.    ChangePalColor(8,LightGray);
  9139.  
  9140.  
  9141.  
  9142.  
  9143.  
  9144. Programmierhandbuch                                 WG-Vision - 169 -
  9145.  
  9146.  
  9147.  
  9148.  
  9149.  
  9150.  
  9151.  
  9152.   SetPushButton(90,3,0,0,'#ICON.I16/4',81);
  9153.    ChangePalColor(8,LightGray);
  9154.   SetPushButton(115,3,0,0,'#ICON.I16/5',82);
  9155.    ChangePalColor(8,LightGray);
  9156.   SetPushButton(150,3,0,0,'#ICON.I16/6',83);
  9157.    ChangePalColor(8,LightGray);
  9158.   SetPushButton(175,3,0,0,'#ICON.I16/7',84);
  9159.    ChangePalColor(8,LightGray);
  9160.   SetPushButton(200,3,0,0,'#ICON.I16/8',85);
  9161.    ChangePalColor(8,LightGray);
  9162.   SetPushButton(225,3,0,0,'#ICON.I16/9',86);
  9163.    ChangePalColor(8,LightGray);
  9164.   SetPushButton(250,3,0,0,'#ICON.I16/10',87);
  9165.    ChangePalColor(8,LightGray);
  9166.   SetPushButton(325,3,0,0,'#ICON.I16/11',88);
  9167.    ChangePalColor(8,LightGray);
  9168.   SetPushButton(350,3,0,0,'#ICON.I16/12',89);
  9169.    ChangePalColor(8,LightGray);
  9170.   SetPushButton(375,3,0,0,'#ICON.I16/13',90);
  9171.    ChangePalColor(8,LightGray);
  9172.   SetPushButton(400,3,0,0,'#ICON.I16/14',91);
  9173.    ChangePalColor(8,LightGray);
  9174.   WinModal:=true; IconBarPresent:=true;
  9175. end;
  9176.  
  9177. procedure TIconBar.InitBackground;
  9178. var RR:TRect;
  9179. begin
  9180.   RR:=Frame^.Area;
  9181.   Bgrd:=new(PIconBarBgrd, Init(RR));
  9182.   List^.InsertItem(Bgrd);
  9183. end;
  9184.  
  9185. {Implementation TIconBarBgrd}
  9186.  
  9187. procedure TIconBarBgrd.Draw;
  9188. begin
  9189.   with Border do FBar(A.x,A.y,B.x,B.y,LightGray);
  9190. end;
  9191.  
  9192.  
  9193.  
  9194. Programmierhandbuch                                 WG-Vision - 170 -
  9195.  
  9196.  
  9197.  
  9198.  
  9199.  
  9200.  
  9201.  
  9202. {Hauptprogramm}
  9203.  
  9204. begin
  9205.   MyApp.Init('Menü-Test');
  9206.   MyApp.Run;
  9207.   MyApp.Done;
  9208. end.
  9209.  
  9210.  
  9211. Komplexbeispiel  Dateiauswahldialog
  9212.  
  9213. Das Laden von Dateien gehört mit zu den Funktionen, auf die
  9214. fast kein Programm verzichten kann. Deshalb wurde in die
  9215. Unit WFileDlg von WG-Vision ein komplettes Dialogfenster im-
  9216. plementiert, mit dessen Hilfe eine sehr komfortable Auswahl
  9217. von Dateien möglich ist. Außerdem lassen sich Verzeichnisse
  9218. und Laufwerke mit nur wenigen Mausklicks wechseln. Da das
  9219. Objekt TInputDialog sehr gut zeigt, wie man komplexe Algo-
  9220. rithmen in ein abgeschlossenes Objekt einpacken kann, soll
  9221. es an dieser Stelle, sozusagen als Abschluß zum Thema Dia-
  9222. logfenster, etwas ausführlicher behandelt und dokumentiert
  9223. werden. Wer sich ernsthaft mit der Programmierung auf der
  9224. Grundlage von WG-Vision auseinandersetzen möchte, sollte auf
  9225. jeden Fall versuchen, die Funktionsweise dieses speziellen
  9226. Dialogs zu verstehen. Die Anmerkungen zum Quelltext sollen
  9227. Ihnen dabei helfen.
  9228. Das Objekt TInputDialog zeigt auch am Beispiel Listbox und
  9229. Eingabezeile, wie man objektintern Daten austauschen oder
  9230. gemeinsam auf Daten zugreifen kann. Außerdem finden Sie in
  9231. diesem Objekt eine mustergültige Fehlerbehandlung.
  9232.  
  9233. Aufgabenstellung
  9234. Aus einer Dialogbox sollen genau spezifizierte Dateinamen
  9235. ausgewählt und mit vollständigem Pfad via Event.InfoString
  9236. dem Hauptprogramm zur Verfügung gestellt werden. Es ist die
  9237. Möglichkeit des Verzeichnis- und Laufwerkswechsel vorzuse-
  9238. hen. Der Dateiname soll wahlweise auch über eine Eingabezei-
  9239. le eingegeben werden können.
  9240.  
  9241.  
  9242.  
  9243.  
  9244. Programmierhandbuch                                 WG-Vision - 171 -
  9245.  
  9246.  
  9247.  
  9248.  
  9249.  
  9250.  
  9251.  
  9252. Aus der hier wiedergegebenen Unit WFileDlg wurde das Objekt
  9253. TOutPutDialog entfernt.
  9254.  
  9255. UNIT WFileDlg;
  9256.  
  9257. interface
  9258.  
  9259. uses WDecl,
  9260.      WDlg,
  9261.      WViews,
  9262.      WEvent,
  9263.      WDriver,
  9264.      WUtils,
  9265.      dos,
  9266.      graph;
  9267.  
  9268. const msgLoadFile = 10;            {Message, das ein gültiger Dateiname}
  9269.                                                    {zur Verfügung steht}
  9270.  
  9271. type PInputDialog=^TInputDialog;
  9272.      TInputDialog=object(TDlgWindow)
  9273.       Pfad     : PathStr;                                 {Originalpfad}
  9274.       Klick    : boolean;
  9275.       constructor Init(ATitle:str80;FMask:str12);
  9276.       destructor Done; virtual;
  9277.       procedure SetFileMask; virtual;         {Dateiauswahlmaske setzen}
  9278.       procedure InitBackground; virtual;
  9279.       procedure SetPalette; virtual;
  9280.       procedure SetDateiListBox(X,Y,xl,yl:integer;Bez:str25;
  9281.                                 LScroller:word);
  9282.       procedure HandleEvent; virtual;
  9283.      end;
  9284.  
  9285.      PDateiListBox=^TDateiListBox;
  9286.      TDateiListBox=object(TListBox)
  9287.       procedure CreateDataList;  {Datei- und Verzeichnisnamen auflisten}
  9288.      end;
  9289.  
  9290.  
  9291.  
  9292.  
  9293.  
  9294. Programmierhandbuch                                 WG-Vision - 172 -
  9295.  
  9296.  
  9297.  
  9298.  
  9299.  
  9300.  
  9301.  
  9302.      PIDlgBgrd=^TIDlgBgrd;
  9303.      TIDlgBgrd=object(TBackground)
  9304.       procedure Draw; virtual;
  9305.      end;
  9306.  
  9307. var FileMask : str12;
  9308.  
  9309. implementation
  9310.  
  9311. type tDialogData=record{Dialogrecord}
  9312.                     Schalter    : string[12];
  9313.                     DateiName   : string[32];         {für Eingabezeile}
  9314.                     Datei       : string[12];                  {Listbox}
  9315.                  end;
  9316.  
  9317. var DlgData:tDialogData;
  9318.  
  9319. {Implementation TInputDialog}
  9320.  
  9321. constructor TInputDialog.Init(ATitle:str80;FMask:str12);
  9322. var RR:TRect;
  9323.     z:array[1..4] of string[20];
  9324.     Drives:str10;
  9325.  
  9326. Mit dieser Funktion können Sie erfahren, welche logischen Laufwerke
  9327. verfügbar sind. Aus praktischen Gründen wird angenommen, daß maximal 6
  9328. logische Laufwerke (A bis F) vorhanden sein können. Als Ergebnis wird
  9329. ein String übergeben, der alle gültigen Laufwerksbuchstaben enthält.
  9330.  
  9331.  
  9332.  
  9333.  
  9334.  
  9335.  
  9336.  
  9337.  
  9338.  
  9339.  
  9340.  
  9341.  
  9342.  
  9343.  
  9344. Programmierhandbuch                                 WG-Vision - 173 -
  9345.  
  9346.  
  9347.  
  9348.  
  9349.  
  9350.  
  9351.  
  9352. function DriveMap:str10;
  9353. var LW,LWerk:str10;
  9354.     i:integer;
  9355.     reg:Registers;
  9356. begin
  9357.   LW:='ABCDEF';
  9358.   LWerk:='';
  9359.   for i:=1 to 6 do
  9360.    begin
  9361.      reg.ah:=$44;
  9362.      reg.al:=$0E;
  9363.      reg.bl:=i;
  9364.      MSDos(reg);
  9365.      if (reg.flags and FCarry)=0 then LWerk:=LWerk+LW[i];
  9366.    end;
  9367.   DriveMap:=LWerk;
  9368. end;
  9369.  
  9370. begin
  9371.  
  9372. WG-Vision ist konsquent zweisprachig programmiert. Das muß natürlich
  9373. auch bei der Programmierung von Spezialdialogen beachtet werden, wenn
  9374. man einfach durch Setzen von Sprache=Englisch eine englischsprachige
  9375. Version kompilieren möchte.
  9376.  
  9377.  
  9378.  
  9379.  
  9380.  
  9381.  
  9382.  
  9383.  
  9384.  
  9385.  
  9386.  
  9387.  
  9388.  
  9389.  
  9390.  
  9391.  
  9392.  
  9393.  
  9394. Programmierhandbuch                                 WG-Vision - 174 -
  9395.  
  9396.  
  9397.  
  9398.  
  9399.  
  9400.  
  9401.  
  9402.   if Sprache=Englisch then
  9403.    begin
  9404.      z[1]:='File~n~ame    :';
  9405.      z[2]:='~F~ile';
  9406.      z[3]:='Cancel';
  9407.      z[4]:='Directory';
  9408.    end
  9409.    else
  9410.    begin
  9411.      z[1]:='Datei~n~ame   :';
  9412.      z[2]:='~D~ateien';
  9413.      z[3]:='Abbrechen';
  9414.      z[4]:='Verzeichnis';
  9415.    end;
  9416.   Drives:=DriveMap;
  9417.  
  9418. Hier folgen die üblichen Fensterinitialisierungen
  9419.  
  9420.   RR.Assign(120,80,382,400);
  9421.   TDlgWindow.Init(RR,ATitle,winDouble+winPanel+winMenu);
  9422.  
  9423. Vorbereitung des Dialogrecords, hier einmal etwas anders !
  9424.  
  9425.   FillChar(DlgData.DateiName,SizeOf(DlgData.DateiName),' ');
  9426.   FileMask:=FMask; Klick:=false;
  9427.   DlgData.DateiName:=FileMask;                               {erst das,}
  9428.   DlgData.DateiName[0]:=#32;      {Längenbyte}              {dann das !}
  9429.  
  9430. aktuellen Pfad merken
  9431.  
  9432.   GetDir(0,Pfad);
  9433.  
  9434. Dialogelemente implementieren
  9435.  
  9436.   SetInputLine(145,55,12,z[1],32,ASCII);
  9437.    ChangePalColor(2,LightGray);
  9438.   SetDateiListBox(15,150,127,144,z[2],VScrBar);
  9439.    ChangePalColor(2,LightGray);
  9440.  
  9441.  
  9442.  
  9443.  
  9444. Programmierhandbuch                                 WG-Vision - 175 -
  9445.  
  9446.  
  9447.  
  9448.  
  9449.  
  9450.  
  9451.  
  9452.   SetPushButton(156,155,90,22,'OK',cmOK);
  9453.    ChangePalColor(7,DarkGray);
  9454.    ChangePalColor(8,LightGray);
  9455.   SetPushButton(156,185,90,22,z[3],cmCancel);
  9456.    ChangePalColor(7,DarkGray);
  9457.    ChangePalColor(8,LightGray);
  9458.   SetStaticText(20,85,z[4],LeftText);
  9459.   SetStaticText(20,105,Pfad,LeftText);
  9460.    ChangePalColor(10,Red);
  9461.  
  9462. "Laufwerkstasten", Es werden zwar alle 6 Laufwerkstasten implementiert,
  9463. aber nur die aktiviert, die wirklich vorhanden sind.
  9464.  
  9465.   SetPushButton(162,230,22,22,'A',ord('A'));
  9466.    if Pos('A',Drives)=0 then SetDisabled;
  9467.    ChangePalColor(7,DarkGray);
  9468.    ChangePalColor(8,LightGray);
  9469.   SetPushButton(191,230,22,22,'B',ord('B'));
  9470.    if Pos('B',Drives)=0 then SetDisabled;
  9471.    ChangePalColor(7,DarkGray);
  9472.    ChangePalColor(8,LightGray);
  9473.   SetPushButton(220,230,22,22,'C',ord('C'));
  9474.    if Pos('C',Drives)=0 then SetDisabled;
  9475.    ChangePalColor(7,DarkGray);
  9476.    ChangePalColor(8,LightGray);
  9477.   SetPushButton(162,260,22,22,'D',ord('D'));
  9478.    if Pos('D',Drives)=0 then SetDisabled;
  9479.    ChangePalColor(7,DarkGray);
  9480.    ChangePalColor(8,LightGray);
  9481.   SetPushButton(191,260,22,22,'E',ord('E'));
  9482.    if Pos('E',Drives)=0 then SetDisabled;
  9483.    ChangePalColor(7,DarkGray);
  9484.    ChangePalColor(8,LightGray);
  9485.   SetPushButton(220,260,22,22,'F',ord('F'));
  9486.    if Pos('F',Drives)=0 then SetDisabled;
  9487.    ChangePalColor(7,DarkGray);
  9488.    ChangePalColor(8,LightGray);
  9489.  
  9490.  
  9491.  
  9492.  
  9493.  
  9494. Programmierhandbuch                                 WG-Vision - 176 -
  9495.  
  9496.  
  9497.  
  9498.  
  9499.  
  9500.  
  9501.  
  9502. Dialogrecord Objekt-intern übergeben
  9503.  
  9504.   with DlgData do     {Input-Dialog}
  9505.    begin
  9506.      Schalter:='LBTTSSTTTTTT';
  9507.      FillChar(DateiName,SizeOf(DateiName),' ');
  9508.      DateiName[0]:=#32;
  9509.      FillChar(Datei,SizeOf(Datei),' ');
  9510.      Datei[0]:=#12;
  9511.    end;
  9512.   SetData(DlgData);
  9513. end;
  9514.  
  9515. destructor TInputDialog.Done;
  9516. begin
  9517.   ChDir(Pfad);                          {Ausgangspfad wieder einstellen}
  9518.   TDlgWindow.Done;
  9519. end;
  9520.  
  9521. procedure TInputDialog.SetFileMask;
  9522. begin
  9523.   FileMask:='*.*';      {Standard-Dateimaske, kann überschrieben werden}
  9524. end;
  9525.  
  9526. procedure TInputDialog.InitBackground;
  9527. var RR:TRect;
  9528. begin
  9529.   RR:=Frame^.Area;
  9530.   Bgrd:=new(PIDlgBgrd, Init(RR));
  9531.   List^.InsertItem(Bgrd);
  9532. end;
  9533.  
  9534. procedure TInputDialog.SetPalette;
  9535. begin
  9536.   Palette:=Palette1;
  9537.   Palette[2]:=#1;
  9538.   Palette[3]:=#15;
  9539. end;
  9540.  
  9541.  
  9542.  
  9543.  
  9544. Programmierhandbuch                                 WG-Vision - 177 -
  9545.  
  9546.  
  9547.  
  9548.  
  9549.  
  9550.  
  9551.  
  9552. procedure TInputDialog.SetDateiListBox(X,Y,xl,yl:INTEGER;Bez:str25;
  9553.                                         LScroller:WORD);
  9554. VAR LBox:PDateiListBox;
  9555. begin
  9556.   TDlgWindow.SetListBox(X,Y,xl,yl,Bez,LScroller);
  9557.   LBox:=New(PDateiListBox, Init(R,Bez,SBH,SBV));
  9558.   LBox^.CreateDataList;
  9559.   LBox^.P.X:=X; LBox^.P.Y:=Y;
  9560.   DlgList^.InsertItem(LBox);
  9561. end;
  9562.  
  9563. Und hier kommt der eigentlich interessante Teil !
  9564.  
  9565. procedure TInputDialog.HandleEvent;
  9566. var LfdPtr:PGroup;
  9567.     I:byte;
  9568.     ActPfad:PathStr;
  9569.     zz:string;
  9570.  
  9571. begin
  9572.   TDlgWindow.HandleEvent;                                   {wie gehabt}
  9573.   with Event do
  9574.    begin
  9575.      GetDir(0,ActPfad);
  9576.      if Event.Command in [65..70] then {Laufwerksauswahltasten gedrückt}
  9577.       begin
  9578.  
  9579. Event.Command enthält raffinierterweise den ASCII-Code des
  9580. Laufwerksbezeichners
  9581.  
  9582.         {$I-}
  9583.         ChDir(chr(Event.Command)+':\');
  9584.         {$I+}
  9585.  
  9586. Fehlermessage provozieren, wenn DOSError<>0
  9587.  
  9588.  
  9589.  
  9590.  
  9591.  
  9592.  
  9593.  
  9594. Programmierhandbuch                                 WG-Vision - 178 -
  9595.  
  9596.  
  9597.  
  9598.  
  9599.  
  9600.  
  9601.  
  9602.         DOSError:=IOResult;
  9603.         ClearEvent;
  9604.         if DOSError<>0 then
  9605.          begin
  9606.            ChDir(ActPfad);
  9607.            case DOSError of
  9608.             1..18    : Fehler.FTyp:=ds;
  9609.             100..106 : Fehler.FTyp:=io;
  9610.             150..162 : Fehler.FTyp:=mst;
  9611.            end; {case}
  9612.            Fehler.FNummer:=DOSError;
  9613.            Event.Message:=msgError;
  9614.            EXIT;
  9615.          end;
  9616.  
  9617. Datei-Listbox mit Dateinamen etc. füllen
  9618.  
  9619.         LfdPtr:=DlgList^.GetItems(2);
  9620.         with PDateiListBox(LfdPtr)^ do
  9621.          begin
  9622.            CreateDataList;
  9623.            Draw;
  9624.          end;
  9625.  
  9626. Aktuellen Pfad als statischen Text in das Dialogfenster eintragen. Bitte
  9627. beachten Sie die Vorgehensweise! Hier können Sie lernen, wie man zur
  9628. Laufzeit einen statischen Text ändern kann.
  9629.  
  9630.         LfdPtr:=DlgList^.GetItems(6);      {statischer Text, 6.Eintrag}
  9631.                                                            {in DlgList}
  9632.         with PStaticText(LfdPtr)^ do                         {Typecast}
  9633.          begin
  9634.            GetDir(0,ActPfad);
  9635.            if length(ActPfad)>26 then              {wenn zu lang, dann}
  9636.             begin                                      {zusammenkürzen}
  9637.               while length(ActPfad)>22 do
  9638.                repeat
  9639.                  delete(ActPfad,3,1);
  9640.                until ActPfad[3]='\';
  9641.  
  9642.  
  9643.  
  9644. Programmierhandbuch                                 WG-Vision - 179 -
  9645.  
  9646.  
  9647.  
  9648.  
  9649.  
  9650.  
  9651.  
  9652.               insert('\...',ActPfad,3);
  9653.             end;
  9654.            Bezeichner.Zeile:=ActPfad;
  9655.            FBar(Origin.x,Origin.y,Origin.x+223,Origin.y+8,LightGray);
  9656.            Draw;
  9657.          end;
  9658.       end;
  9659.  
  9660. OK-Taste gedrückt. Wenn die ausgewählte Datei wirklich auf dem
  9661. Datenträger existiert, dann Dateinamen mit Pfad ergänzen, in
  9662. Event.InfoString verpacken und mit der Mitteilung msgLoadFile auf die
  9663. Reise schicken ...
  9664.  
  9665.      if Event.Command=cmOK then
  9666.       begin
  9667.         zz:=Trim(FExpand(DlgData.DateiName));            {Trim entfernt}
  9668.                                                {nachfolgend Leerzeichen}
  9669.         if Exists(zz) then                {nachschauen, ob es die Datei}
  9670.                                                         {überhaupt gibt}
  9671.          begin
  9672.            Message:=msgLoadFile;                    {Message abschicken}
  9673.            LfdPtr:=DlgList^.GetItems(1);    {Dateiname mit Pfad aus der}
  9674.                                                     {Eingabezeile lesen}
  9675.            with PInputLine(LfdPtr)^ do
  9676.             InfoString:=Trim(FExpand(DlgData.DateiName));
  9677.            Command:=cmCloseWindow;
  9678.          end
  9679.          else Message:=msgError;
  9680.       end;
  9681.  
  9682. Abbrechen gedrückt. Fenster schließen und sonst nichts
  9683.  
  9684.      if Command=cmCancel then
  9685.       with DlgData do
  9686.        begin
  9687.          DateiName:='';
  9688.          Datei:='';
  9689.          Command:=cmCloseWindow;
  9690.        end;
  9691.  
  9692.  
  9693.  
  9694. Programmierhandbuch                                 WG-Vision - 180 -
  9695.  
  9696.  
  9697.  
  9698.  
  9699.  
  9700.  
  9701.  
  9702. Wenn Sie in die Eingabezeile eine neue Dateiauswahlmaske geschrieben und
  9703. mit <ENTER> quittiert haben, dann muß der Inhalt der Listbox neu
  9704. erstellt werden.
  9705.  
  9706.     if (What=evKeyboard) AND (Keyb.KeyCode=kbEnter) then
  9707.      if Pos('*',DlgData.DateiName)<>0 then
  9708.       begin
  9709.         if Pos('\',DlgData.DateiName)<>0 then
  9710.          begin
  9711.            FileMask:=Trim(copy(DlgData.DateiName,Pos('\',
  9712.                       DlgData.DateiName)+1,length(DlgData.DateiName)-
  9713.                       Pos('\',DlgData.DateiName)));
  9714.          end
  9715.          else FileMask:=Trim(DlgData.DateiName);
  9716.         LfdPtr:=DlgList^.GetItems(2);
  9717.         with PDateiListBox(LfdPtr)^ do
  9718.          begin
  9719.            CreateDataList;
  9720.            Draw;
  9721.          end;
  9722.       end;
  9723.  
  9724. Anklick-Bereich für den Doppelklick festlegen. Das ist notwendig, wenn
  9725. ein Doppelklick auf den Rollbalken nicht die Übernahme der gerade
  9726. gekennzeichneten Datei veranlassen soll.
  9727.  
  9728.      LfdPtr:=DlgList^.GetItems(2);      {Klick-Bereich für Doppelklick}
  9729.      with PDateiListBox(LfdPtr)^ do
  9730.       begin
  9731.         if Border.Contains(Mouse.Position) then
  9732.          if Mouse.Double then Klick:=true;
  9733.       end;
  9734.  
  9735. Dateiauswahl aus der Listbox
  9736.  
  9737.      if (Keyb.KeyCode=kbSpace) or Klick then
  9738.       begin
  9739.         Mouse.DoubleKlick:=FALSE;
  9740.         Klick:=false;
  9741.  
  9742.  
  9743.  
  9744. Programmierhandbuch                                 WG-Vision - 181 -
  9745.  
  9746.  
  9747.  
  9748.  
  9749.  
  9750.  
  9751.  
  9752.         if PDateiListBox(LfdPtr)^.Focus then
  9753.          begin
  9754.            LfdPtr:=DlgList^.GetItems(1);
  9755.            with PInputLine(LfdPtr)^ do
  9756.             begin
  9757.               Data:=DlgData.Datei;
  9758.               if (Trim(Data)='.') or (Trim(Data)='..') or
  9759.                  (Pos('<D>',Data)<>0) then
  9760.                begin
  9761.                  if Pos('<D>',Data)<>0 then
  9762.                    delete(Data,Pos('<D>',Data),3);
  9763.                  if Trim(Data)='.' then Data:='\';
  9764.                  ChDir(Data);
  9765.                  if Trim(Data)<>'\' then Data:=Trim(Data)+'\'+FileMask;
  9766.                  LfdPtr:=DlgList^.GetItems(2);
  9767.                  with PDateiListBox(LfdPtr)^ do
  9768.                   begin
  9769.                     CreateDataList;
  9770.                     Draw;
  9771.                   end;
  9772.  
  9773. Statischen Text den neuen Gegebenheiten anpassen
  9774.  
  9775.  
  9776.  
  9777.  
  9778.  
  9779.  
  9780.  
  9781.  
  9782.  
  9783.  
  9784.  
  9785.  
  9786.  
  9787.  
  9788.  
  9789.  
  9790.  
  9791.  
  9792.  
  9793.  
  9794. Programmierhandbuch                                 WG-Vision - 182 -
  9795.  
  9796.  
  9797.  
  9798.  
  9799.  
  9800.  
  9801.  
  9802.                  LfdPtr:=DlgList^.GetItems(6);        {statischer Text}
  9803.                  with PStaticText(LfdPtr)^ do
  9804.                  begin
  9805.                     GetDir(0,ActPfad);
  9806.                     if length(ActPfad)>26 then      {wenn zu lang, dann}
  9807.                      begin                              {zusammenkürzen}
  9808.                        while length(ActPfad)>22 do
  9809.                         repeat
  9810.                           delete(ActPfad,3,1);
  9811.                         until ActPfad[3]='\';
  9812.                        insert('\...',ActPfad,3);
  9813.                      end;
  9814.                    Bezeichner.Zeile:=ActPfad;
  9815.                    FBar(Origin.x,Origin.y,Origin.x+223,Origin.y+8,
  9816.                         LightGray);
  9817.                    Draw;
  9818.                  end;
  9819.                end;
  9820.               Draw;
  9821.             end;
  9822.          end;
  9823.       end;
  9824.    end;
  9825. end;
  9826.  
  9827. Datei- und Verzeichnisnamen in den Heap lesen zur Verwendung innerhalb
  9828. der Listbox.
  9829.  
  9830. {Implementation TDateiListBox}
  9831.  
  9832. procedure TDateiListBox.CreateDataList;
  9833. var SRec:SearchRec;
  9834.     LfdPtr:PLine;
  9835. begin
  9836.   Liste^.DeleteItems;
  9837.   ChangeItem:=1; AktivItem:=1;
  9838.   Delta.X:=1; Delta.Y:=1;
  9839.   VertiScrollBar^.Value:=1;
  9840.   FindFirst('*.*',AnyFile,SRec);
  9841.  
  9842.  
  9843.  
  9844. Programmierhandbuch                                 WG-Vision - 183 -
  9845.  
  9846.  
  9847.  
  9848.  
  9849.  
  9850.  
  9851.  
  9852.   while DosError=0 do
  9853.    begin
  9854.      if SRec.Attr=$10 then
  9855.       begin
  9856.         LfdPtr:=New(PLine, Init);
  9857.         if (SRec.Name='.') or (SRec.Name='..') then
  9858.          LfdPtr^.Eintrag:=SRec.Name
  9859.          else
  9860.          begin
  9861.            while length(SRec.Name)<8 do SRec.Name:=SRec.Name+' ';
  9862.            LfdPtr^.Eintrag:=SRec.Name+' <D>';         {Unterverzeichnis}
  9863.          end;
  9864.         Liste^.InsertItem(LfdPtr);
  9865.       end;
  9866.      FindNext(SRec);
  9867.    end;
  9868.   FindFirst(FileMask,AnyFile,SRec);
  9869.   while DosError=0 do
  9870.    begin
  9871.      if SRec.Attr=$20 then
  9872.       begin
  9873.         LfdPtr:=New(PLine, Init);
  9874.         LfdPtr^.Eintrag:=SRec.Name;
  9875.         Liste^.InsertItem(LfdPtr);
  9876.       end;
  9877.      FindNext(SRec);
  9878.    end;
  9879.   DataLen:=12;
  9880.   SetLimit(12,Liste^.AnzElem,8,11);
  9881. end;
  9882.  
  9883.  
  9884.  
  9885.  
  9886.  
  9887.  
  9888.  
  9889.  
  9890.  
  9891.  
  9892.  
  9893.  
  9894. Programmierhandbuch                                 WG-Vision - 184 -
  9895.  
  9896.  
  9897.  
  9898.  
  9899.  
  9900.  
  9901.  
  9902. procedure TIDlgBgrd.Draw;
  9903. begin
  9904.   with Border do
  9905.    begin
  9906.      FBar(A.x,A.y,B.x,B.y,LightGray);
  9907.      FBar(A.x+7,A.y+18,B.x-7,A.y+46,LightGray);
  9908.      D3Frame(A.x+7,A.y+18,B.x-7,A.y+46,Black,White);
  9909.      D3Frame(A.x+148,A.y+126,A.x+246,A.y+188,Black,White);
  9910.    end;
  9911. end;
  9912.  
  9913. END.
  9914.  
  9915.  
  9916.  
  9917.  
  9918.  
  9919.  
  9920.  
  9921.  
  9922.  
  9923.  
  9924.  
  9925.  
  9926.  
  9927.  
  9928.  
  9929.  
  9930.  
  9931.  
  9932.  
  9933.  
  9934.  
  9935.  
  9936.  
  9937.  
  9938.  
  9939.  
  9940.  
  9941.  
  9942.  
  9943.  
  9944. Programmierhandbuch                                 WG-Vision - 185 -
  9945.  
  9946.  
  9947.  
  9948.  
  9949.  
  9950.  
  9951.  
  9952. 5.5. Mitteilungsboxen
  9953.  
  9954. Mitteilungsboxen sind spezielle Dialogfenster, die man zum
  9955. Aufblenden von Informationen (Hinweise, Fragen etc.) ver-
  9956. wenden kann.
  9957. Das Objekt TProgram stellt eine solche Messagebox zur Verfü-
  9958. gung. Sie kann z.B. sofort über die case-Auswahl des Event-
  9959. handlers der Applikation aufgerufen werden. Eine
  9960. Mitteilungsbox wird unabhängig vom eingestellten Grafikmodus
  9961. immer zentriert auf dem Bildschirm dargestellt. Ihre Größe
  9962. beträgt einheitlich 260x150 Pixel und sie wird in der roten
  9963. Farbpalette angezeigt.
  9964.  
  9965. Syntax
  9966.  
  9967. MessageBox(Caption:word;PanelText,InfoText:string);
  9968.  
  9969. Caption   bestimmt das Schalterlayout der Box
  9970.  
  9971.            0  keine Schalter
  9972.            1  Schalter 'OK'
  9973.            2  Schalter 'Abbrechen'  (Cancel)
  9974.            3  Schalter 'Ja' und 'Nein'  (No und Yes)
  9975.  
  9976. Paneltext Text im Panel der Messagebox
  9977. InfoText  Text im Clientbereich der Messagebox. InfoText
  9978.           kann maximal 2 Zeilen umfassen. Die Stelle, wo der
  9979.           Text umgebrochen werden soll, ist mit einem
  9980.           Doppelkreuz zu kennzeichnen
  9981.  
  9982. Die Tasten einer Messagebox senden bei Betätigung folgende
  9983. Kommandos:
  9984.  
  9985. 'OK'            cmCloseWindow
  9986. 'Abbrechen'     cmCancel
  9987. 'Ja'            cmYes
  9988. 'Nein'          cmNo
  9989.  
  9990.  
  9991.  
  9992.  
  9993.  
  9994. Programmierhandbuch                                 WG-Vision - 186 -
  9995.  
  9996.  
  9997.  
  9998.  
  9999.  
  10000.  
  10001.  
  10002. Beispiel
  10003. Ein Programmteil sendet im Event-Record folgende Mitteilung,
  10004. die von einer Messagebox abgefangen und angezeigt werden
  10005. soll:
  10006.  
  10007. Event.Message:=msgInfo;
  10008. Event.InfoString:='Ungültige Eingabe#Abbruch';
  10009.  
  10010. Im Eventhandler der Applikation:
  10011.  
  10012. ...
  10013. if Event.Message=msgInfo then MessageBox(1,'Hinweis',Event.InfoString);
  10014. ...
  10015.  
  10016. 5.6. Anzeigen von Fehlermeldungen
  10017.  
  10018. Zu einer sauberen Programmierung gehört, daß Fehler im Pro-
  10019. gramm nicht zu einem unvorhersehbaren Verhalten oder sogar
  10020. zu einem Systemabsturz führen. Auf jeden Fall sollte der
  10021. Nutzer beim Auftreten eines Fehlers darüber informiert wer-
  10022. den. Innerhalb einer grafischen Nutzeroberfläche gehört es
  10023. sich, daß Fehlermeldungen innerhalb einer Messagebox anzu-
  10024. zeigen sind.
  10025. WG-Vision verwendet dazu folgendes Konzept:
  10026.  
  10027. 1. Alle Fehlerarten werden in verschiedene Kategorien
  10028.    aufgeteilt, die in etwa die Fehlerquelle beschreiben:
  10029.  
  10030.     gr     Grafik-Fehler
  10031.     ems    EMS-Fehler
  10032.     joy    Joystick-Fehler
  10033.     ds     DOS-Fehler
  10034.     io     Ein-/Ausgabefehler
  10035.     mst    schwerwiegender Fehler
  10036.     pr     Druckerfehler
  10037.  
  10038.  
  10039.  
  10040.  
  10041.  
  10042.  
  10043.  
  10044. Programmierhandbuch                                 WG-Vision - 187 -
  10045.  
  10046.  
  10047.  
  10048.  
  10049.  
  10050.  
  10051.  
  10052. 2. Wird ein Fehler dedektiert (z.B. IOResult<>0), dann wird
  10053.    das Message-Feld des Event-Records auf msgError gesetzt.
  10054.    Außerdem wird in die Record-Variable Fehler der Fehlertyp
  10055.    (FTyp) und die Nummer des Fehlers (FNummer) eingetragen.
  10056.  
  10057. 3. Der Eventhandler der Applikation veranlaßt als Reaktion
  10058.    auf die Message msgError, daß ein Mitteilungsfenster
  10059.    aufgeblendet wird, welches im Panel den Fehlertyp und im
  10060.    Fenster die Fehlermeldung entsprechend der Informationen,
  10061.    die im Record Fehler stehen) enthält. Die Texte zu den
  10062.    Fehlernummern stehen in der Unit WError.
  10063.  
  10064. Exemplarisch soll als Beispiel eine Funktion vorgestellt
  10065. werden, welche überprüft, ob der angeschlossene Drucker be-
  10066. reit ist oder nicht und gegebenenfalls eine entsprechende
  10067. Fehlermitteilung erzwingt. Sie wurde der Unit WPrint entnom-
  10068. men.
  10069.  
  10070. function TLinePrint.PrinterOK:boolean;
  10071. var PrinterAdress:word;
  10072.     Status:byte;
  10073. begin
  10074.   PrinterOK:=false;
  10075.   delay(10);
  10076.   PrinterAdress:=memw[$40:$08)];                 {Basisadresse von LPT1}
  10077.   if PrinterAdress<>0 then
  10078.    begin
  10079.      Status:=port[PrinterAdress+1];                {Statusport einlesen}
  10080.      if (Status and $DF)=$DF then PrinterOK:=true
  10081.       else
  10082.       begin
  10083.         Fehler.FTyp:=pr;
  10084.         if (Status and $40)=$40 then                     {nicht On-Line}
  10085.          if (Status and $20)<>$20 then
  10086.           begin
  10087.             Fehler.FNummer:=303;
  10088.             Event.Message:=msgError;
  10089.             Exit;
  10090.           end
  10091.  
  10092.  
  10093.  
  10094. Programmierhandbuch                                 WG-Vision - 188 -
  10095.  
  10096.  
  10097.  
  10098.  
  10099.  
  10100.  
  10101.  
  10102.           else
  10103.           begin                                            {kein Papier}
  10104.             Fehler.FNummer:=302;
  10105.             Event.Message:=msgError;
  10106.             Exit;
  10107.           end;
  10108.          if (Status and $87)=$87 then             {Drucker nicht bereit}
  10109.           begin
  10110.             Fehler.FNummer:=301;
  10111.             Event.Message:=msgError;
  10112.             Exit;
  10113.           end;
  10114.       end;
  10115.    end
  10116.    else
  10117.    begin
  10118.      Fehler.FTyp:=pr;
  10119.      Fehler.FNummer:=304;
  10120.      Event.Message:=msgError;
  10121.    end;
  10122. end;
  10123.  
  10124. Wenn Sie in der Unit WError Fehlermeldungen vermissen oder
  10125. eigene Fehlermeldungen verwenden möchten, können Sie die
  10126. Unit entsprechend erweitern.
  10127. Für das Abfangen eines Fehlers ist jedoch weiterhin der Pro-
  10128. grammierer verantwortlich.
  10129.  
  10130.  
  10131.  
  10132.  
  10133.  
  10134.  
  10135.  
  10136.  
  10137.  
  10138.  
  10139.  
  10140.  
  10141.  
  10142.  
  10143.  
  10144. Programmierhandbuch                                 WG-Vision - 189 -
  10145.  
  10146.  
  10147.  
  10148.  
  10149.  
  10150.  
  10151.  
  10152. 5.7. Kontextsensitive Hilfe
  10153.  
  10154. Der Aufbau einer kontextsensitiven Hilfe ist innerhalb von
  10155. WG-Vision sehr einfach zu realisieren. Sie brauchen ledig-
  10156. lich die Zeile
  10157.  
  10158. SetOnLineHelp('hilf.dat')
  10159.  
  10160. in den Quelltext ihres Programms einzufügen. Der beste Ort
  10161. dafür ist die erste Zeile in InitMenubar bzw., vorausgesetzt
  10162. Sie überschreiben ihn, der Konstruktor der Applikation. Der
  10163. Parameter in SetOnlineHelp ist der Name der Hilfe-Datei. Sie
  10164. muß sich im gleichen Verzeichnis wie das Programm befinden.
  10165. Fehlt sie, kann das Hilfesystem nicht aktiviert werden (Ach-
  10166. tung ! Es werden keine diesbezüglichen Hinweise ausgegeben).
  10167. Die Hilfsdatei können Sie mit jedem ASCII-Editor erstellen.
  10168. Sie hat folgenden Aufbau:
  10169.  
  10170. Überschrift (ohne Bedeutung)
  10171.  
  10172. ##1
  10173.  
  10174. Hilfe-Text für Helpindex 1
  10175.  
  10176.  
  10177. END
  10178. ##2
  10179.  
  10180. Hilfe-Text für HelpIndex 2
  10181.  
  10182. END
  10183.  
  10184. ...
  10185.  
  10186. HELPEND
  10187.  
  10188. Zwei Doppelkreuze gefolgt von einer Zahl definieren jeweils
  10189. den Beginn des Hilfe-Textes. Beendet wird er durch das
  10190. Kürzel END. Die Zahl hinter dem Doppelkreuz ist identisch
  10191.  
  10192.  
  10193.  
  10194. Programmierhandbuch                                 WG-Vision - 190 -
  10195.  
  10196.  
  10197.  
  10198.  
  10199.  
  10200.  
  10201.  
  10202. mit den Hilfsindex, den Sie bei der Menüdefinition den
  10203. einzelnen Me-nüpunkten zugeordnet haben. Ist der Hilfsindex
  10204. 0, dann gibt WG-Vision eine Messagebox mit dem Hinweis aus,
  10205. daß keine Hilfe verfügbar ist.
  10206. Aktiviert wird das Hilfesystem mit der <F1>-Taste. Bedingung
  10207. ist, daß sich der Auswahlbalken auf dem entsprechenden Menü-
  10208. punkt befindet.
  10209. Der dazugehörige Hilfstext wird in einem Rollfenster zur An-
  10210. zeige gebracht.
  10211.  
  10212. Beispiel für eine Hilfe-Datei:
  10213.  
  10214. Helpfile für ....
  10215.  
  10216.  
  10217. ##1
  10218.  
  10219. BEISPIEL  WG-Vision
  10220.  
  10221.  
  10222. Menü :  Datei
  10223.  
  10224.  
  10225. Unter dem Menüpunkt "Datei" sind folgende Funktionen
  10226. zusammengefaßt:
  10227.  
  10228. Neues Bild  F3        Der Bildschirm wird gelöscht und
  10229.                       Sie können mit einem neuen Bild
  10230.                       beginnen
  10231.  
  10232. Bild Laden  F2        Ein Dialogfenster wird aufgeblendet,
  10233.                       aus dem Sie ein bereits vorhandenes
  10234.                       Bild zur Weiterverarbeitung auswählen
  10235.                       können
  10236.  
  10237. Bild Speichern        Das in Arbeit befindliche Bild wird
  10238.                       gesichert. Wenn die Bilddatei noch
  10239.                       keinen Namen hat, wird die Eingabe
  10240.                       eines Dateinamens verlangt
  10241.  
  10242.  
  10243.  
  10244. Programmierhandbuch                                 WG-Vision - 191 -
  10245.  
  10246.  
  10247.  
  10248.  
  10249.  
  10250.  
  10251.  
  10252. Drucken               Druckt das Bild auf dem angeschlossenen
  10253.                       Drucker aus
  10254.  
  10255. Löschen               Das gesamte Bild auf dem Bildschirm wird
  10256.                       gelöscht
  10257.  
  10258. Beenden  Alt-X        Malprogramm abbrechen und zurück zum
  10259.                       Betriebssystem
  10260. END
  10261. ##2
  10262.  
  10263. BEISPIEL  WG-Vision
  10264.  
  10265.  
  10266. Menü :  Bearbeiten
  10267.  
  10268.  
  10269. Unter dem Menüpunkt "Bearbeiten" sind folgende Funktionen
  10270. zusammengefaßt:
  10271.  
  10272. Rückgängig            Die letzte Zeichenoperation wird rückgängig
  10273.                       gemacht
  10274.  
  10275. Schnitt               Bildausschnitt festlegen
  10276.  
  10277. Die folgenden Funktionen sind nur aktiv, wenn ein Bildausschnitt
  10278. festgelegt worden ist
  10279.  
  10280. Kopieren              Bildausschnitt an eine andere Stelle des
  10281.                       Bildschirms kopieren
  10282.  
  10283. Verschieben           Bildausschnitt verschieben
  10284.  
  10285. Drehen                Bildausschnitt Drehen
  10286. END
  10287. ##3
  10288.  
  10289. BEISPIEL  WG-Vision
  10290.  
  10291.  
  10292.  
  10293.  
  10294. Programmierhandbuch                                 WG-Vision - 192 -
  10295.  
  10296.  
  10297.  
  10298.  
  10299.  
  10300.  
  10301.  
  10302. Menü :  Werkzeuge
  10303.  
  10304.  
  10305. Unter dem Menüpunkt "Werkzeuge" sind folgende Funktionen
  10306. zusammengefaßt:
  10307. END
  10308. ##4
  10309.  
  10310.  
  10311. BEISPIEL  WG-Vision
  10312.  
  10313. Menü :  Schrift
  10314.  
  10315.  
  10316. Unter dem Menüpunkt "Schrift" sind folgende Funktionen
  10317. zusammengefaßt:
  10318. END
  10319.  
  10320.  
  10321. HELPEND;
  10322.  
  10323. Verwenden Sie für Ihr Programm den VGA-Standardmodus
  10324. M640x480 mit 16 Farben, dann können Sie mit SetFont einen
  10325. der Zusatzzeichensätze für die Anzeige der Hilfstexte akti-
  10326. vieren.
  10327.  
  10328.  
  10329.  
  10330.  
  10331.  
  10332.  
  10333.  
  10334.  
  10335.  
  10336.  
  10337.  
  10338.  
  10339.  
  10340.  
  10341.  
  10342.  
  10343.  
  10344. Programmierhandbuch                                 WG-Vision - 193 -
  10345.  
  10346.  
  10347.  
  10348.  
  10349.  
  10350.  
  10351.  
  10352. 5.8. Statuszeile
  10353.  
  10354. Zur Programmierung einer Statuszeile stellt das Applikati-
  10355. onsobjekt die virtuelle Methode StatusBar zur Verfügung. Mit
  10356. ihrer Hilfe können Sie das Desktop mit einer Statuszeile
  10357. ausstatten, in der Sie z.B. Ihr CopyRight oder andere Infor-
  10358. mationen (z.B. Programminformationen) schreiben können.
  10359. Statusbar besitzt selbst keinen Eventhandler. Deshalb muß
  10360. sie vom Eventhandler der Applikation (bzw. der aufge-
  10361. blendeten Fenster) mit bedient werden (Beispiel siehe
  10362. Abschnitt "Objekte im Detail", "Tastatur").
  10363.  
  10364. Beispiel
  10365.  
  10366. procedure TApplication.StatusBar;
  10367. var i:integer;
  10368. begin
  10369.   FBar(4,GetMaxY-26,GetMaxX-4,GetMaxY-4,LightGray);
  10370.   D3Frame(6,GetMaxY-24,GetMaxX-6,GetMaxY-6,Black,White);
  10371.   OutTextXY(15,GetMaxY-19,'Copyright 1992/93 by Dipl.Phys.
  10372.                            Mathias Scholz');
  10373.   SetColor(Black);
  10374.   OutTextXY(16,GetMaxY-18,'Copyright 1992/93 by Dipl.Phys.
  10375.                            Mathias Scholz');
  10376. end;
  10377.  
  10378. In den meisten Fällen wird vom Programm direkt in die Sta-
  10379. tuszeile geschrieben. Statusbar ist also gewissermaßen nur
  10380. ein Rahmen, welches bei Bedarf Informationen aufnimmt. Die
  10381. Methode Statusbar wird in der Regel nur einmal beim Aufblen-
  10382. den des Desktops abgearbeitet.
  10383.  
  10384.  
  10385.  
  10386.  
  10387.  
  10388.  
  10389.  
  10390.  
  10391.  
  10392.  
  10393.  
  10394. Programmierhandbuch                                 WG-Vision - 194 -
  10395.  
  10396.  
  10397.  
  10398.  
  10399.  
  10400.  
  10401.  
  10402. 5.9. Zweisprachige Programmierung
  10403.  
  10404. Programme, die mit WG-Vision erstellt worden sind, können
  10405. sofort in zwei Sprachvarianten (Deutsch und Englisch) er-
  10406. stellt werden. Wird beim Programmstart die Variable Sprache
  10407. mit "Englisch" initialisiert, dann erfolgen alle Ausschrif-
  10408. ten auf den Bildschirm in Englisch (Sie müssen Ihr Programm
  10409. natürlich auch zweisprachig gestalten. Schauen Sie sich dazu
  10410. bitte noch einmal das Komplexbeispiel Dateiauswahldialog
  10411. an). Außerdem müssen Sie eventuell noch die Menüressource
  10412. durch eine englischsprachige Version ersetzen.
  10413.  
  10414.  
  10415.  
  10416.  
  10417.  
  10418.  
  10419.  
  10420.  
  10421.  
  10422.  
  10423.  
  10424.  
  10425.  
  10426.  
  10427.  
  10428.  
  10429.  
  10430.  
  10431.  
  10432.  
  10433.  
  10434.  
  10435.  
  10436.  
  10437.  
  10438.  
  10439.  
  10440.  
  10441.  
  10442.  
  10443.  
  10444. Programmierhandbuch                                 WG-Vision - 195 -
  10445.  
  10446.  
  10447.  
  10448.  
  10449.  
  10450.  
  10451.  
  10452. 6. Objekte im Detail
  10453.  
  10454. 6.1. Unit WDRIVER.PAS
  10455.  
  10456. 6.1.1. Ansteuerung der Grafikkarte  - TVideoDevice
  10457.  
  10458. Das Objekt Video ist eine Instanz des Objektes TVideoDevice.
  10459. Dieses Objekt ist für die gesamte Grafikansteuerung verant-
  10460. wortlich. Es stellt Methoden zur Initialisierung der einzel-
  10461. nen Grafik-Modi und zum Umschalten in den Alphamodus zur
  10462. Verfügung. Außerdem lassen sich zur Laufzeit die Auflösung,
  10463. der gerade aktive Treiber und die Anzahl der unterstützten
  10464. Farben erfragen.
  10465.  
  10466. Felder
  10467.  
  10468. Treiber
  10469. Treiber:integer;
  10470. Aktiver Grafiktreiber. Die Zahlen entsprechen folgenden
  10471. Grafikkarten
  10472.  
  10473.   3   EGA        (16 Farben)
  10474.   9   VGA        (16 Farben)
  10475.   6   IBM 8514   (256 Farben)
  10476.  11   VESA       (256 Farben)
  10477.  
  10478. OrigMode
  10479. OrigMode:integer;
  10480. Enthält die Nummer des zuletzt aktiven Alphamodus (d.h.
  10481. bevor in die Grafik umgeschalten wurde)
  10482.  
  10483.   0   BW40    {siehe Turbo-Referenzhandbuch}
  10484.   1   CO40
  10485.   2   BW80
  10486.   3   CO80
  10487. 256           80 Zeichen mit 43 bzw. 50 Zeilen
  10488.  
  10489.  
  10490.  
  10491.  
  10492.  
  10493.  
  10494. Programmierhandbuch                                 WG-Vision - 196 -
  10495.  
  10496.  
  10497.  
  10498.  
  10499.  
  10500.  
  10501.  
  10502. Modus
  10503. Modus:integer;
  10504. Z.Z. aktiver Grafikmodus. Folgende Grafikmodi sind möglich:
  10505.  
  10506.   1   M640x350
  10507.   2   M640x480
  10508.   3   M800x600
  10509.   4   M1024x768
  10510.  
  10511. Modi
  10512. Modi:tMinSet;
  10513. Enthält als Menge alle für den konkreten Grafiktreiber
  10514. verfügbaren Grafikmodi
  10515.  
  10516. XMax,YMax
  10517. Maximal mögliche x- bzw. y-Koordinate des Bildschirms
  10518.  
  10519. Colors
  10520. Anzahl der verfügbaren Farben
  10521.  
  10522. Methoden
  10523.  
  10524. Init
  10525. constructor Init(Driver,Mode:integer);
  10526. Initialisierung des Grafiksystems. Es erfolgt die Registrie-
  10527. rung des gewünschten BGI-Treibers, der als Objekt-Datei vor-
  10528. liegen muß. Folgende Treiber werden unterstützt: EGAVGA.BGI,
  10529. IBM8514.BGI und VGAVESA.BGI. Anschließend schaltet der Rech-
  10530. ner in den unter Mode angegebenen Grafikmodus. Alle VESA-
  10531. Modi arbeiten mit 256 Farben. Tritt während der Initiali-
  10532. sierung ein Fehler auf, wird auf dem Alphabildschirm eine
  10533. entsprechende Fehlermeldung generiert.
  10534.  
  10535. Done
  10536. destructor Done; virtual;
  10537. Grafik schließen und den beim Programmstart aktiven
  10538. Textmodus setzen.
  10539.  
  10540.  
  10541.  
  10542.  
  10543.  
  10544. Programmierhandbuch                                 WG-Vision - 197 -
  10545.  
  10546.  
  10547.  
  10548.  
  10549.  
  10550.  
  10551.  
  10552. GetXMax
  10553. function GetXMax:word;
  10554. Maximale x-Koordinate des Bildschirms.
  10555.  
  10556. GetYMax
  10557. function GetYMax:word;
  10558. Maximale y-Koordinate des Bildschirms.
  10559.  
  10560. GetAnzColors
  10561. function GetAnzColors:word;
  10562. Anzahl der von der Grafikkarte im eingestellten Modus
  10563. unterstützten Farben (16 oder 256).
  10564.  
  10565. GetDriver
  10566. function GetDriver:string;
  10567. Übergibt den Namen des gerade aktiven Grafiktreibers.
  10568.  
  10569. GetGrafikMode
  10570. function GetGrafikMode:integer;
  10571. Liefert die Nummer des gerade aktiven Grafikmodus.
  10572.  
  10573. ChangeGraficMode
  10574. ChangeGraficMode(Mode:integer);
  10575. Diese Methode wird zum Wechseln des Grafikmodus benötigt.
  10576. Übergeben wird die Nummer des Grafikmodus, in welchen
  10577. gewechselt werden soll (bitte vordefinierte Konstanten
  10578. verwenden). Innerhalb der Methode wird geprüft, ob der
  10579. gerade aktive BGI-Treiber diesen Grafikmodus überhaupt
  10580. unterstützt. Wenn nicht oder wenn es beim Umschaltvorgang zu
  10581. Problemen kommt, wird eine Fehlermeldung an WG-Vision
  10582. abgesetzt.
  10583.  
  10584. SetTextMode
  10585. procedure SetTextMode;
  10586. Wechselt in den Textmodus, der vor der Grafikinitialisierung
  10587. aktiv war.
  10588.  
  10589.  
  10590.  
  10591.  
  10592.  
  10593.  
  10594. Programmierhandbuch                                 WG-Vision - 198 -
  10595.  
  10596.  
  10597.  
  10598.  
  10599.  
  10600.  
  10601.  
  10602. SetDirectVideo
  10603. procedure SetDirectVideo(Direct:boolean);
  10604. Mit dieser Methode können Sie festlegen, ob Schreibaktionen
  10605. über das BIOS (Direct=false) oder direkt in den Bildspeicher
  10606. erfolgen sollen. SetDirectVideo wirkt nur auf die Befehle
  10607. write und writeln. Außerdem wird das CRT-Scrolling
  10608. unterbunden.
  10609.  
  10610.  
  10611.  
  10612.  
  10613.  
  10614.  
  10615.  
  10616.  
  10617.  
  10618.  
  10619.  
  10620.  
  10621.  
  10622.  
  10623.  
  10624.  
  10625.  
  10626.  
  10627.  
  10628.  
  10629.  
  10630.  
  10631.  
  10632.  
  10633.  
  10634.  
  10635.  
  10636.  
  10637.  
  10638.  
  10639.  
  10640.  
  10641.  
  10642.  
  10643.  
  10644. Programmierhandbuch                                 WG-Vision - 199 -
  10645.  
  10646.  
  10647.  
  10648.  
  10649.  
  10650.  
  10651.  
  10652. 6.1.2. Ansteuerung eines Spielhebels - TJoyStickDevice
  10653.  
  10654. Wenn Ihr Rechner über einen Spieleadapter verfügt, können
  10655. Sie über eine Instanz des Objektes TJoyStickDevice einen
  10656. Joystick ansteuern.
  10657.  
  10658. Felder
  10659.  
  10660. JoyPresent
  10661. JoyPresent:boolean;
  10662. Diese logische Variable wird vom Konstruktor des TJoyStick-
  10663. Device-Objektes auf true gesetzt, wenn ein Spieleadapter
  10664. verfügbar ist.
  10665.  
  10666. JPos
  10667. JPos:TPoint;
  10668. Instanz eines TPoint-Objektes. Wird zur Speicherung der
  10669. absoluten Position des Spielhebels verwendet.
  10670.  
  10671. Phi
  10672. Phi:real;
  10673. Horizontale Auslenkung des Spielhebels.
  10674.  
  10675. Elongation
  10676. Elongation:real;
  10677. Betrag der vertikalen Auslenkung des Spielhebels.
  10678.  
  10679. FPush1,FPush2
  10680. FPush1:boolean; FPush2:boolean;
  10681. Status der Feuertasten. Wird eine Feuertaste gedrückt, dann
  10682. wird die entsprechende Variable auf true gesetzt.
  10683.  
  10684. Methoden
  10685.  
  10686. Init
  10687. constructor Init;
  10688. Initialisierung des Joysticks. Dabei wird überprüft, ob ein
  10689. Spieleadapter angeschlossen ist (Variable JoyPresent).
  10690.  
  10691.  
  10692.  
  10693.  
  10694. Programmierhandbuch                                 WG-Vision - 200 -
  10695.  
  10696.  
  10697.  
  10698.  
  10699.  
  10700.  
  10701.  
  10702. JoyStickHandle
  10703. procedure JoyStickHandle;
  10704. Joystick-Handler. Ermittelt die Koordinaten, die Auslenkung,
  10705. den Winkel der horizontalen Auslenkung und den Status der
  10706. Feuerknöpfe. Diese Werte werden in den Feldern des TJoy-
  10707. StickDevice-Objektes gespeichert.
  10708.  
  10709. IfJoyPresent
  10710. function IfJoyPresent:boolean;
  10711. Gibt true zurück, wenn der Rechner über einen Spieleadapter
  10712. verfügt.
  10713.  
  10714. Degree
  10715. function Degree:integer;
  10716. Gibt den Winkel der horizontalen Auslenkung mit einer
  10717. Genauigkeit von 5 Grad zurück. Wertebereich 0..360 Grad.
  10718.  
  10719. Turn
  10720. function Turn:word;
  10721. Gibt den Betrag der Auslenkung des Joysticks zurück.
  10722.  
  10723. GetXValue
  10724. function GetXValue:integer;
  10725. Liefert die momentane x-Koordinate der Auslenkung im Bereich
  10726. von 0..300 zurück.
  10727.  
  10728. GetYValue
  10729. function GetXValue:integer;
  10730. Liefert die momentane y-Koordinate der Auslenkung im Bereich
  10731. von 0..300 zurück.
  10732.  
  10733. PushOne
  10734. function PushOne:boolean;
  10735. Übergibt true, wenn die erste Feuertaste betätigt wurde.
  10736.  
  10737. PushTwo
  10738. function PushTwo:boolean;
  10739. Übergibt true, wenn die zweite Feuertaste betätigt wurde.
  10740.  
  10741.  
  10742.  
  10743.  
  10744. Programmierhandbuch                                 WG-Vision - 201 -
  10745.  
  10746.  
  10747.  
  10748.  
  10749.  
  10750.  
  10751.  
  10752. Beispiel
  10753.  
  10754. program JoyTest;
  10755.  
  10756. uses crt,
  10757.      WDriver;
  10758.  
  10759. var Joy:TJoyStickDevice;
  10760. begin
  10761.   ClrScr;
  10762.   Joy.Init;
  10763.   with Joy do
  10764.   repeat
  10765.     JoyStickHandle;
  10766.     GotoXY(10,10); writeln(Joy.x:5:0);
  10767.     GotoXY(10,11); writeln(Joy.y:5:0);
  10768.     GotoXY(10,13); writeln(Abstand:5:0);
  10769.     GotoXY(10,14); writeln(Degree:3);
  10770.   until FPush1;
  10771. end.
  10772.  
  10773.  
  10774.  
  10775.  
  10776.  
  10777.  
  10778.  
  10779.  
  10780.  
  10781.  
  10782.  
  10783.  
  10784.  
  10785.  
  10786.  
  10787.  
  10788.  
  10789.  
  10790.  
  10791.  
  10792.  
  10793.  
  10794. Programmierhandbuch                                 WG-Vision - 202 -
  10795.  
  10796.  
  10797.  
  10798.  
  10799.  
  10800.  
  10801.  
  10802. 6.1.3. Tastatur - TKeyboardDevice
  10803.  
  10804. Das Objekt TKeyboardDevice dient der Ansteuerung der Tasta-
  10805. tur. Es enthält Methoden zum Auslesen von Key- und Scancodes
  10806. und zur Bestimmung des Tastaturstatus (z.B. NumLock einge-
  10807. schaltet ?). Außerdem kann bei AT-Tastaturen die Tastatur-
  10808. Verzögerung und die Wiederholfrequenz bei gedrückter Taste
  10809. eingestellt werden. Weitere Methoden dienen dem Sperren und
  10810. der Freigabe der Tastatur.
  10811.  
  10812. Felder
  10813.  
  10814. ATFlag
  10815. ATFlag:boolean;
  10816. Wenn ATFlag true ist, dann ist eine AT-Tastatur ange-
  10817. schlossen. Nur in diesem Fall können Sie mit der Methode
  10818. SetTypmaticRate die Verzögerung und die Wiederholfrequenz
  10819. bei einem Tastendruck einstellen.
  10820.  
  10821. Delay
  10822. Delay:integer;
  10823. Diese Variable enthält die eingestellte Tastatur-Verzöge-
  10824. rung. Darunter ist die Zeitdauer, die bis zum Einsetzen der
  10825. automatischen Tastenwiederholung vergeht, zu verstehen.
  10826. Standardmäßig ist sie Null, was einer Verzögerung von
  10827. ungefähr 1/4 Sekunden entspricht. Nur wenn die Verzö-
  10828. gerungsrate verändert wird, erhält sie einen Wert ungleich
  10829. Null.
  10830. Folgende Werte sind möglich :
  10831.  
  10832. 0   1/4 Sekunde
  10833. 1   1/2 Sekunde
  10834. 2   3/4 Sekunde
  10835. 3    1  Sekunde
  10836.  
  10837.  
  10838.  
  10839.  
  10840.  
  10841.  
  10842.  
  10843.  
  10844. Programmierhandbuch                                 WG-Vision - 203 -
  10845.  
  10846.  
  10847.  
  10848.  
  10849.  
  10850.  
  10851.  
  10852. Speed
  10853. Speed:integer;
  10854. Wenn eine Taste längere Zeit niedergedrückt wird, dann sen-
  10855. det der Tastatur-Controller das entsprechende Zeichen immer
  10856. wieder an den Computer. Wie oft er das pro Sekunde macht,
  10857. bestimmt die Wiederholrate. Sie kann zwischen zwei Wiederho-
  10858. lungen pro Sekunde und dreisig Wiederholungen pro Sekunde
  10859. liegen. Ihr Wert wird in der Variablen Speed hinterlegt, wo-
  10860. bei folgende Zuordnung gilt:
  10861.  
  10862. 0   30.0   Wiederholungen pro Sekunde
  10863. 1   26.7               "
  10864. 2   24.0               "
  10865. 3   21.8               "
  10866.   .
  10867.   .
  10868.   .
  10869. 30  2,1                "
  10870. 31  2.0                "
  10871.  
  10872. KeyCode
  10873. KeyCode:char;
  10874. Speichert den ASCII-Code der zuletzt gedrückten Taste.
  10875.  
  10876. ScanCode
  10877. ScanCode:byte;
  10878. Speichert den Scancode der zuletzt gedrückten (Sonder-)
  10879. Taste.
  10880.  
  10881. Statusflag
  10882. StatusFlag
  10883. Speichert das Statusflag der Sondertasten.
  10884.  
  10885. KeyPush
  10886. KeyPush:boolean;
  10887. Diese logische Variable ist solange true, wie eine Taste
  10888. niedergedrückt ist.
  10889.  
  10890.  
  10891.  
  10892.  
  10893.  
  10894. Programmierhandbuch                                 WG-Vision - 204 -
  10895.  
  10896.  
  10897.  
  10898.  
  10899.  
  10900.  
  10901.  
  10902. Locking
  10903. Locking:boolean;
  10904. True, wenn die Tastatur nicht gesperrt ist.
  10905.  
  10906. Methoden
  10907.  
  10908. Init
  10909. constructor Init;
  10910. Initialisierung der Tastatur. Dabei wird untersucht, ob eine
  10911. AT-Tastatur angeschlossen ist. Wenn ja, wird die private
  10912. Variable ATFlag auf true gesetzt.
  10913.  
  10914. LockKeyboard
  10915. procedure LockKeyboard;
  10916. Durch Aufruf dieser Methode können Sie die Tastatur sperren,
  10917. d.h. alle Tastaturereignisse werden ignoriert.
  10918.  
  10919. UnLockKeyboard
  10920. procedure UnLockKeyboard;
  10921. Aufheben der Tastatursperre.
  10922.  
  10923. SetTypmaticRate
  10924. procedure SetTypmaticRate(Verzoegerung,Wiederholfrequenz
  10925.                           :integer):boolean;
  10926. Typmatikrate einer AT-Tastatur einstellen. Folgende Werte
  10927. sind sinnvoll:
  10928. Verzoegerung         0   1/4 Sekunde
  10929.                      1   1/2 Sekunde
  10930.                      2   3/4 Sekunde
  10931.                      3    1  Sekunde
  10932.  
  10933.  
  10934.  
  10935.  
  10936.  
  10937.  
  10938.  
  10939.  
  10940.  
  10941.  
  10942.  
  10943.  
  10944. Programmierhandbuch                                 WG-Vision - 205 -
  10945.  
  10946.  
  10947.  
  10948.  
  10949.  
  10950.  
  10951.  
  10952. Wiederholfrequenz    0   30.0   Wiederholungen pro Sekunde
  10953.                      1   26.7               "
  10954.                      2   24.0               "
  10955.                      3   21.8               "
  10956.                      .
  10957.                      .
  10958.                      .
  10959.                     30  2,1                 "
  10960.                     31  2.0                 "
  10961.  
  10962. ClearKeyboardBuffer
  10963. procedure ClearKeyboardBuffer;
  10964. Löschen des Tastatur-Puffers.
  10965.  
  10966. KeyboardHandler
  10967. function KeyboardHandler:boolean;
  10968. Der Keyboardhandler übergibt nur dann true, wenn eine Tasta-
  10969. tureingabe stattgefunden hat. In diesem Fall liest er die
  10970. Tastatur aus und setzt die Felder KeyCode, ScanCode, KeyPush
  10971. und StatusFlag. Um eine permanente Tastaturabfrage zu ge-
  10972. währleisten, sollte der Keyboardhandler permanent in einer
  10973. repeat-Schleife aufgerufen werden.
  10974.  
  10975. GetKeyCode
  10976. function GetKeyCode:char;
  10977. Übergibt den Keycode der zuletzt gedrückten Taste.
  10978.  
  10979. GetScanCode
  10980. function GetScanCode:byte;
  10981. Übergibt den Scancode der zuletzt gedrückten (Sonder-)
  10982. Taste.
  10983.  
  10984. IfKeyPush
  10985. function IfKeyPush:boolean;
  10986. Übergibt solange true, wie eine Taste gedrückt gehalten
  10987. wird.
  10988.  
  10989.  
  10990.  
  10991.  
  10992.  
  10993.  
  10994. Programmierhandbuch                                 WG-Vision - 206 -
  10995.  
  10996.  
  10997.  
  10998.  
  10999.  
  11000.  
  11001.  
  11002. IfKeybLock
  11003. function IfKeybLock:boolean;
  11004. Übergibt true, wenn die Tastatur nicht gesperrt ist.
  11005.  
  11006. RShiftKey
  11007. function RShiftKey:boolean;
  11008. Übergibt true, wenn die rechte Shift-Taste betätigt wurde.
  11009.  
  11010. LShiftKey
  11011. function LShiftKey:boolean;
  11012. Übergibt true, wenn die linke Shift-Taste betätigt wurde.
  11013.  
  11014. CtrlKey
  11015. function CtrlKey:boolean;
  11016. Übergibt true, wenn die Kontroll-Taste betätigt wurde.
  11017.  
  11018. AltKey
  11019. function AltKey:boolean;
  11020. Übergibt true, wenn die Alt-Taste betätigt wurde.
  11021.  
  11022. ScrollLock
  11023. function ScrollLock:boolean;
  11024. Übergibt true, wenn die Scroll-Lock-Taste (Rollen) einge-
  11025. schaltet ist.
  11026.  
  11027. NumLock
  11028. function NumLock:boolean;
  11029. Übergibt true, wenn die Num-Lock-Taste eingeschaltet ist.
  11030.  
  11031. CapsLock
  11032. function CapsLock:boolean;
  11033. Übergibt true, wenn die Caps-Lock-Taste eingeschaltet ist.
  11034.  
  11035. Beispiel
  11036.  
  11037. In der Statuszeile einer Applikation soll permanent der Sta-
  11038. tus der Sondertasten Caps-Lock, Num-Lock und Scroll-Lock an-
  11039. gezeigt werden. Außerdem soll noch angezeigt werden, ob die
  11040. linke bzw. rechte Shifttaste betätigt ist.
  11041.  
  11042.  
  11043.  
  11044. Programmierhandbuch                                 WG-Vision - 207 -
  11045.  
  11046.  
  11047.  
  11048.  
  11049.  
  11050.  
  11051.  
  11052. program StatusBar;
  11053.  
  11054. uses WApp,
  11055.      WDecl,
  11056.      WDlg,
  11057.      WDriver,
  11058.      WUtils,
  11059.      WEvent,
  11060.      graph;
  11061.  
  11062. const cmNewWindow   = 103;
  11063.  
  11064. type TApplication=object(TApp)
  11065.       procedure InitMenuBar; virtual;
  11066.       procedure HandleEvent; virtual;
  11067.       procedure StatusBar; virtual;
  11068.       procedure NewWindow;
  11069.      end;
  11070.  
  11071. var MyApp:TApplication;
  11072.  
  11073. {Implementation TApplication}
  11074.  
  11075. procedure TApplication.InitMenuBar;
  11076. begin
  11077.   MainMenu('~F~enster',0);
  11078.    SubMenu('~F~enster aufblenden',cmNewWindow,0,0,false,false);
  11079.    SubMenu('E~x~it  Alt-X',cmCloseApplication,0,altX,false,false);
  11080. end;
  11081.  
  11082. procedure TApplication.HandleEvent;
  11083. var i:integer;
  11084.  
  11085. Da die Statuszeile keinen eigenen Eventhandler besitzt, müssen wir sie
  11086. vom Eventhandler der Applikation aus bedienen. Um das Programm über-
  11087. sichtlicher zu gestalten, wird zu diesem Zweck die Prozedur HandleSta-
  11088. tusBar erstellt. In dieser Prozedur wird permanent der Status der
  11089. Sondertasten überwacht und die gewünschte Anzeige in der Statuszeile
  11090. realisiert. Da mit keypressed nicht festgestellt werden kann, ob eine
  11091.  
  11092.  
  11093.  
  11094. Programmierhandbuch                                 WG-Vision - 208 -
  11095.  
  11096.  
  11097.  
  11098.  
  11099.  
  11100.  
  11101.  
  11102. Statustaste gedrückt wird, kann auch mit Event.What=evKeyboard nicht
  11103. ausgetestet werden, ob eine Statustaste gedrückt wurde (der Keyboard-
  11104. handler setzt sich nur dann auf true, wenn auch keypressed true ist).
  11105. Deshalb der kleine Trick mit GetPixel, um zu sehen, wie der letzte Ta-
  11106. stenstatus war.
  11107.  
  11108. procedure HandleStatusBar;
  11109. begin
  11110.    if Keyb.CapsLock and (GetPixel(254,GetMaxY-16)=LightGray) then
  11111.     begin
  11112.       Mouse.HideMouse;
  11113.       FBar(250,GetMaxY-18,258,GetMaxY-12,LightCyan);
  11114.       Mouse.ShowMouse;
  11115.     end;
  11116.    if not (Keyb.CapsLock) and (GetPixel(254,GetMaxY-16)=LightCyan) then
  11117.     begin
  11118.       Mouse.HideMouse;
  11119.       FBar(250,GetMaxY-18,258,GetMaxY-12,LightGray);
  11120.       Mouse.ShowMouse;
  11121.     end;
  11122.    if Keyb.NumLock and (GetPixel(350,GetMaxY-16)=LightGray) then
  11123.     begin
  11124.       Mouse.HideMouse;
  11125.       FBar(346,GetMaxY-18,354,GetMaxY-12,LightCyan);
  11126.       Mouse.ShowMouse;
  11127.     end;
  11128.    if not (Keyb.NumLock) and (GetPixel(350,GetMaxY-16)=LightCyan) then
  11129.     begin
  11130.       Mouse.HideMouse;
  11131.       FBar(346,GetMaxY-18,354,GetMaxY-12,LightGray);
  11132.       Mouse.ShowMouse;
  11133.     end;
  11134.    if Keyb.ScrollLock and (GetPixel(470,GetMaxY-16)=LightGray) then
  11135.     begin
  11136.       Mouse.HideMouse;
  11137.       FBar(466,GetMaxY-18,474,GetMaxY-12,LightCyan);
  11138.       Mouse.ShowMouse;
  11139.     end;
  11140.    if not (Keyb.ScrollLock) and (GetPixel(470,GetMaxY-16)=LightCyan)
  11141.  
  11142.  
  11143.  
  11144. Programmierhandbuch                                 WG-Vision - 209 -
  11145.  
  11146.  
  11147.  
  11148.  
  11149.  
  11150.  
  11151.  
  11152.     then
  11153.     begin
  11154.       Mouse.HideMouse;
  11155.       FBar(466,GetMaxY-18,474,GetMaxY-12,LightGray);
  11156.       Mouse.ShowMouse;
  11157.     end;
  11158.    if Keyb.LShiftKey and (GetPixel(547,GetMaxY-16)=LightGray) then
  11159.     begin
  11160.       Mouse.HideMouse;
  11161.       FBar(544,GetMaxY-18,551,GetMaxY-12,LightCyan);
  11162.       Mouse.ShowMouse;
  11163.     end;
  11164.    if not (Keyb.LShiftKey) and (GetPixel(547,GetMaxY-16)=LightCyan) then
  11165.     begin
  11166.       Mouse.HideMouse;
  11167.       FBar(544,GetMaxY-18,551,GetMaxY-12,LightGray);
  11168.       Mouse.ShowMouse;
  11169.     end;
  11170.    if Keyb.RShiftKey and (GetPixel(561,GetMaxY-16)=LightGray) then
  11171.     begin
  11172.       Mouse.HideMouse;
  11173.       FBar(559,GetMaxY-18,566,GetMaxY-12,LightCyan);
  11174.       Mouse.ShowMouse;
  11175.     end;
  11176.    if not (Keyb.RShiftKey) and (GetPixel(561,GetMaxY-16)=LightCyan) then
  11177.     begin
  11178.       Mouse.HideMouse;
  11179.       FBar(559,GetMaxY-18,566,GetMaxY-12,LightGray);
  11180.       Mouse.ShowMouse;
  11181.     end;
  11182. end;
  11183.  
  11184.  
  11185.  
  11186.  
  11187.  
  11188.  
  11189.  
  11190.  
  11191.  
  11192.  
  11193.  
  11194. Programmierhandbuch                                 WG-Vision - 210 -
  11195.  
  11196.  
  11197.  
  11198.  
  11199.  
  11200.  
  11201.  
  11202. {-------}
  11203.  
  11204. begin
  11205.   TProgram.HandleEvent;
  11206.   HandleStatusBar;    {Hier wird der Handler der Statuszeile aufgerufen}
  11207.   case Event.Command of
  11208.    cmNewWindow   : NewWindow;
  11209.   end; {case}
  11210. end;
  11211.  
  11212. procedure TApplication.NewWindow;
  11213. var R:TRect;
  11214.     Window:PWindow;
  11215. begin
  11216.   R.Assign(60,80,440,280);
  11217.   Window:=new(PWindow, Init(R,'Beispiel',
  11218.               winDouble+winPanel+winMenu+winKey));
  11219.   InsertDesktop(Window);
  11220. end;
  11221.  
  11222. procedure TApplication.StatusBar;
  11223. var i:integer;
  11224. begin
  11225.   FBar(4,GetMaxY-26,GetMaxX-4,GetMaxY-4,LightGray);
  11226.   D3Frame(6,GetMaxY-24,GetMaxX-6,GetMaxY-6,Black,White);
  11227.   SetColor(Red);
  11228.   OutTextXY(15,GetMaxY-18,'Tataturstatus');
  11229.   SetColor(Black);
  11230.   OutTextXY(15,GetMaxY-18,'                   Caps Lock    Num Lock
  11231.                                Scroll Lock     Shift');
  11232.   D3Frame(249,GetMaxY-19,259,GetMaxY-11,Black,White);
  11233.  
  11234. {Damit es hübsch ausschaut ...}
  11235.  
  11236.   D3Frame(345,GetMaxY-19,355,GetMaxY-11,Black,White);
  11237.   D3Frame(465,GetMaxY-19,475,GetMaxY-11,Black,White);
  11238.   D3Frame(543,GetMaxY-19,552,GetMaxY-11,Black,White);
  11239.   D3Frame(558,GetMaxY-19,567,GetMaxY-11,Black,White);
  11240. end;
  11241.  
  11242.  
  11243.  
  11244. Programmierhandbuch                                 WG-Vision - 211 -
  11245.  
  11246.  
  11247.  
  11248.  
  11249.  
  11250.  
  11251.  
  11252. {Hauptprogramm}
  11253.  
  11254. begin
  11255.   MyApp.Init('Statusbar mit Tastaturstatusanzeige');
  11256.   MyApp.Run;
  11257.   MyApp.Done;
  11258. end.
  11259.  
  11260.  
  11261.  
  11262.  
  11263.  
  11264.  
  11265.  
  11266.  
  11267.  
  11268.  
  11269.  
  11270.  
  11271.  
  11272.  
  11273.  
  11274.  
  11275.  
  11276.  
  11277.  
  11278.  
  11279.  
  11280.  
  11281.  
  11282.  
  11283.  
  11284.  
  11285.  
  11286.  
  11287.  
  11288.  
  11289.  
  11290.  
  11291.  
  11292.  
  11293.  
  11294. Programmierhandbuch                                 WG-Vision - 212 -
  11295.  
  11296.  
  11297.  
  11298.  
  11299.  
  11300.  
  11301.  
  11302. 6.1.4. Maus - TMouseDevice
  11303.  
  11304. Die Maus spielt eine wichtige Rolle innerhalb einer grafi-
  11305. schen Nutzeroberfläche. Das Objekt TMouseDevice stellt eine
  11306. große Anzahl von Methoden bereit, mit deren Hilfe fast alle
  11307. Steuerungsaufgaben abgedeckt werden können. Eine der wich-
  11308. tigsten Routinen ist der Maushandler. Er muß in eine Abfra-
  11309. geschleife (repeat ... until) eingebettet sein und übergibt
  11310. nur dann true, wenn sich der Zustand der Maus verändert hat.
  11311. Aus der Zustandsänderung heraus wird der jeweils aktuelle
  11312. Zustand bestimmt und in den Feldern des Objekts gespeichert.
  11313. Das TMouseDevice-Objekt arbeitet nur im Grafikmodus.
  11314.  
  11315. Felder
  11316.  
  11317. MousePresent
  11318. MousePresent:boolean;
  11319. Diese logische Variable wird innerhalb der Initialisierungs-
  11320. routine auf true gesetzt, wenn der Maustreiber aktiv und ei-
  11321. ne Maus vorhanden ist.
  11322.  
  11323. FName
  11324. FName:string;
  11325. Dateiname einer Mauszeiger-Ressource. Mauszeiger lassen sich
  11326. in einer Ressourcendatei zusammenfassen und daraus über die
  11327. Methode LoadCursorTyp laden.
  11328.  
  11329. Position
  11330. Position:TPoint;
  11331. Aktuelle Lage des Mauszeigers auf dem Grafikbildschirm.
  11332.  
  11333. LeftButton
  11334. LeftButton:boolean;
  11335. Ist true, wenn die linke Maustaste gedrückt wurde.
  11336.  
  11337. RightButton
  11338. RightButton:boolean;
  11339. Wird auf true gesetzt, wenn die rechte Maustaste gedrückt
  11340. wurde.
  11341.  
  11342.  
  11343.  
  11344. Programmierhandbuch                                 WG-Vision - 213 -
  11345.  
  11346.  
  11347.  
  11348.  
  11349.  
  11350.  
  11351.  
  11352. LButtonChange
  11353. LButtonChange:boolean;
  11354. Ist true, wenn sich der Status der linken Maustaste verän-
  11355. dert hat.
  11356.  
  11357. RButtonChange
  11358. RButtonChange:boolean;
  11359. Ist true, wenn sich der Status der rechten Maustaste
  11360. verändert hat.
  11361.  
  11362. DoubleKlick
  11363. DoubleKlick:boolean;
  11364. Wird nach einem Doppelklick auf true gesetzt.
  11365.  
  11366. KlickTime
  11367. KlickTime:word;
  11368. Zeitdifferenz zwischen zwei Klicks, die noch als Doppelklick
  11369. interpretiert werden. Standardwert ist 25.
  11370.  
  11371. Area
  11372. Area:TRect;
  11373. Bereichsgrenzen für die Mausbewegung. Nur Innerhalb von Area
  11374. kann der Mauszeiger bewegt werden.
  11375.  
  11376.  
  11377.  
  11378.  
  11379.  
  11380.  
  11381.  
  11382.  
  11383.  
  11384.  
  11385.  
  11386.  
  11387.  
  11388.  
  11389.  
  11390.  
  11391.  
  11392.  
  11393.  
  11394. Programmierhandbuch                                 WG-Vision - 214 -
  11395.  
  11396.  
  11397.  
  11398.  
  11399.  
  11400.  
  11401.  
  11402. CursorTyp
  11403. CursorTyp:byte;
  11404. In dieser Variablen wird der Typ des gerade aktiven Mauskur-
  11405. sors gespeichert. Standardmäßig sind folgende Werte möglich
  11406. (gilt nicht für den Einsatz von Mauszeiger-Ressourcen):
  11407.  
  11408.    1   Pfeil   (Standard)
  11409.    2   Schräges Kursorkreuz  (Hair)
  11410.    3   Sanduhr
  11411.    4   Gerader Vierfach-Pfeil
  11412.    5   Gerader Doppelpfeil mit Pfeilspitze oben und unten
  11413.    6   Schräger Doppelpfeil von links unten nach schräg oben
  11414.    7   Gerader Doppelpfeil mit Pfeilspitze rechts und links
  11415.    8   Schräger Doppelpfeil von links oben nach rechts unten
  11416.    9   Kursorstrich (Caret)
  11417.   10   Handsymbol
  11418.   11   Gerades Kursorkreuz
  11419.  
  11420. Methoden
  11421.  
  11422. Init
  11423. procedure Init;
  11424. Initialisierung der Maus. Es wird überprüft, ob überhaupt
  11425. eine Maus vorhanden ist (Interrupt $33). Wenn ja, wird die
  11426. logische Variable MousePresent auf true gesetzt. Der Bewe-
  11427. gungsbereich der Maus ist der gesamte Bildschirm bis auf ei-
  11428. nem Randbereich von 4 Pixeln (das entspricht in WG-Vision
  11429. dem Doppelrahmen des Desktops). Außerdem erhalten die Felder
  11430. ihre Anfangsbelegungen.
  11431.  
  11432. ShowMouse
  11433. procedure ShowMouse;
  11434. Mauszeiger einschalten.
  11435.  
  11436. HideMouse
  11437. procedure HideMouse
  11438. Mauszeiger ausschalten
  11439.  
  11440.  
  11441.  
  11442.  
  11443.  
  11444. Programmierhandbuch                                 WG-Vision - 215 -
  11445.  
  11446.  
  11447.  
  11448.  
  11449.  
  11450.  
  11451.  
  11452. SetMouseArea
  11453. procedure SetMouseArea(x1,y1,x2,y2:integer);
  11454. Diese Methode legt den Bereich fest (Area), in dem sich die
  11455. Maus bewegen darf.
  11456.  
  11457. PutMouse
  11458. procedure PutMouse(x,y:integer);
  11459. Setzt den Mauszeiger an die Position x,y des Bildschirms.
  11460.  
  11461. MouseSpeed
  11462. procedure MouseSpeed(XSpeed,YSpeed:integer);
  11463. Durch den Aufruf dieser Methode wird das Verhältnis Mausbe-
  11464. wegung je Pixel verändert. Der Standardwert beträgt horizon-
  11465. tal 8 Mickeys je 8 Pixel und vertikal 16 Mickeys je 8 Pixel,
  11466. wobei ein Mickey 1/200 Zoll entspricht. Die Parameter XSpeed
  11467. und YSpeed sind Werte in Mickeys. Je größer sie gewählt wer-
  11468. den, desto langsamer bewegt sich der Mauszeiger auf dem
  11469. Bildschirm.
  11470.  
  11471. MouseHandler
  11472. function MouseHandler:boolean;
  11473. Der Mousehandler muß in eine Abfrageschleife eingebaut
  11474. werden. Er übergibt immer dann true, wenn sich der Zustand
  11475. der Maus verändert hat. Dazu aktualisiert er die Felder des
  11476. Objekts mit den veränderten Werten.
  11477.  
  11478. GetXPos
  11479. function GetXPos:integer;
  11480. Übergibt die momentane x-Position des Mauszeigers.
  11481.  
  11482. GetYPos
  11483. function GetYPos:integer;
  11484. Übergibt die momentane y-Position des Mauszeigers.
  11485.  
  11486. GetPos
  11487. procedure GetPos(var MP:TPoint);
  11488. Übergibt die momentane Position des Mauszeigers als Punkt.
  11489.  
  11490.  
  11491.  
  11492.  
  11493.  
  11494. Programmierhandbuch                                 WG-Vision - 216 -
  11495.  
  11496.  
  11497.  
  11498.  
  11499.  
  11500.  
  11501.  
  11502. LButtonKlick
  11503. function LButtonKlick:boolean;
  11504. Übergibt true, wenn die linke Maustaste angeklickt wurde.
  11505.  
  11506. RButtonKlick
  11507. function RButtonKlick:boolean;
  11508. Übergibt true, wenn die rechte Maustaste angeklickt wurde.
  11509.  
  11510. LButtonDrag
  11511. function LButtonDrag:boolean;
  11512. Übergibt true, wenn die linke Maustaste gedrückt bewegt
  11513. wurde.
  11514.  
  11515. RButtonDrag
  11516. function RButtonDrag:boolean;
  11517. Übergibt true, wenn die rechte Maustaste gedrückt bewegt
  11518. wurde.
  11519.  
  11520. LButtonRel
  11521. function LButtonRel:boolean;
  11522. Übergibt true, wenn die linke Maustaste losgelassen wird.
  11523.  
  11524. RButtonRel
  11525. function RButtonRel:boolean;
  11526. Übergibt true, wenn die rechte Maustaste losgelassen wird.
  11527.  
  11528. MDouble
  11529. function MDouble:boolean;
  11530. Übergibt bei einem Doppelklick true.
  11531.  
  11532. SetKlickTime
  11533. procedure SetKlickTime(t:byte);
  11534. Mit dieser Methode können Sie die Zeitdifferenz setzen, in-
  11535. nerhalb der zwei Klicks als Doppelklicks interpretiert wer-
  11536. den. Der Standardwert beträgt 25.
  11537.  
  11538. MMove
  11539. function MMove:boolean;
  11540. Übergibt true, wenn die Maus bewegt wird.
  11541.  
  11542.  
  11543.  
  11544. Programmierhandbuch                                 WG-Vision - 217 -
  11545.  
  11546.  
  11547.  
  11548.  
  11549.  
  11550.  
  11551.  
  11552. SetCursorTyp
  11553. procedure SetCursorTyp(CTyp:byte);
  11554. Wechseln des Kursortyps. Standardmäßig sind folgende Kursor-
  11555. typen verfügbar:
  11556.  
  11557.    1   Pfeil   (Standard)
  11558.    2   Schräges Kursorkreuz  (Hair)
  11559.    3   Sanduhr
  11560.    4   Gerader Vierfach-Pfeil
  11561.    5   Gerader Doppelpfeil mit Pfeilspitze oben und unten
  11562.    6   Schräger Doppelpfeil von links unten nach schräg oben
  11563.    7   Gerader Doppelpfeil mit Pfeilspitze rechts und links
  11564.    8   Schräger Doppelpfeil von links oben nach rechts unten
  11565.    9   Kursorstrich (Caret)
  11566.   10   Handsymbol
  11567.   11   Gerades Kursorkreuz
  11568.  
  11569. LoadCursorTyp
  11570. procedure LoadCursorTyp(f:string);
  11571. Mauskursor mit der Nummer n aus einer Ressourcendatei laden.
  11572. Der String f enthält den Dateinamen mit vorangestellten Dop-
  11573. pelkreuz und dahinter, durch den Schrägstrich getrennt, die
  11574. Kursor-Nummer. Die Mauszeiger-Ressource muß die Extension
  11575. .CUR besitzen.
  11576.  
  11577. Beispiel:
  11578.  
  11579. Mouse.LoadCursorTyp('#CURSOR/3');
  11580.  
  11581. Lädt den Mauszeiger Nr. 3 aus der Ressorcendatei CURSOR.CUR.
  11582.  
  11583.  
  11584.  
  11585.  
  11586.  
  11587.  
  11588.  
  11589.  
  11590.  
  11591.  
  11592.  
  11593.  
  11594. Programmierhandbuch                                 WG-Vision - 218 -
  11595.  
  11596.  
  11597.  
  11598.  
  11599.  
  11600.  
  11601.  
  11602. 6.1.4.1. Erstellung von Mauszeiger-Ressourcen
  11603.  
  11604. Mauszeiger lassen sich am elegantesten mit einem speziellen
  11605. Malprogramm entwerfen. Das soll aber nicht das Thema dieses
  11606. Abschnitts sein. Ich möchte Ihnen lediglich den prinzipielle
  11607. Weg aufzeigen, wie man eine WG-Vision-kompatible Mauszeiger-
  11608. Ressourcendatei erzeugt. In dem Sie die hier vorgestellten
  11609. Routinen in ein spezielles WG-Vision-Programm einbinden,
  11610. können Sie selbst einen Mauszeiger-Editor zusammenbasteln.
  11611. Mauszeiger werden durch folgenden Datentyp repräsentiert:
  11612.  
  11613. type GraphCursorTyp=record
  11614.                       Mask:array[0..1,0..15] of word;
  11615.                       xspot,yspot:word;
  11616.                     end;
  11617.  
  11618. Das Array Mask beschreibt zwei Masken, die Screenmask und
  11619. die Cursormask, die zusammen das Kursorbild ergeben. Beide
  11620. sind 16x16 Bit-Arrays. Zusätzlich gibt es noch einen "Hot
  11621. Spot", den Punkt des Cursors, der verwendet wird, um die Ko-
  11622. ordinaten des Punktes zu bestimmen, an der sich der Cursor
  11623. befindet. Die mit xspot und yspot angegebenen Werte beziehen
  11624. sich auf die linke obere Ecke der Cursormaske.
  11625. Am Beispiel des Pfeils soll nun gezeigt werden, wie Screen-
  11626. und Cursormask aufgebaut sind:
  11627.  
  11628. var Pfeil:GraphCursorTyp;
  11629.  
  11630. with Pfeil do
  11631.  begin
  11632.  
  11633.    {Screenmask}
  11634.  
  11635.    Mask : (($3FFF,$1FFF,$0FFF,$07FF,$03FF,$01FF,$00FF,$007F,
  11636.             $003F,$001F,$000F,$00FF,$10FF,$F87F,$F87F,$F87F),
  11637.  
  11638.  
  11639.  
  11640.  
  11641.  
  11642.  
  11643.  
  11644. Programmierhandbuch                                 WG-Vision - 219 -
  11645.  
  11646.  
  11647.  
  11648.  
  11649.  
  11650.  
  11651.  
  11652.    {Cursormask}
  11653.  
  11654.            ($0000,$4000,$6000,$7000,$7800,$7C00,$7E00,$7F00,
  11655.             $7F80,$7FC0,$7C00,$6600,$0600,$0300,$0300,$0000));
  11656.  
  11657.    {Hot Spot}
  11658.  
  11659.    xspot : 0;
  11660.    yspot : 0);
  11661.  end;
  11662.  
  11663.  
  11664. Screenmask
  11665.  
  11666.      8421 8421 8421 8421
  11667.  
  11668.  0   ..XX XXXX XXXX XXXX     3FFF
  11669.  1   ...X XXXX XXXX XXXX     1FFF
  11670.  2   .... XXXX XXXX XXXX     0FFF
  11671.  3   .... .XXX XXXX XXXX     07FF
  11672.  4   .... ..XX XXXX XXXX     03FF
  11673.  5   .... ...X XXXX XXXX     01FF
  11674.  6   .... .... XXXX XXXX     00FF
  11675.  7   .... .... .XXX XXXX     007F
  11676.  8   .... .... ..XX XXXX     003F
  11677.  9   .... .... ...X XXXX     001F
  11678. 10   .... .... .... XXXX     000F
  11679. 11   .... .... XXXX XXXX     00FF
  11680. 12   ...X .... XXXX XXXX     10FF
  11681. 13   XXXX X... .XXX XXXX     F87F
  11682. 14   XXXX X... .XXX XXXX     F87F
  11683. 15   XXXX X... .XXX XXXX     F87F
  11684.  
  11685.  
  11686.  
  11687.  
  11688.  
  11689.  
  11690.  
  11691.  
  11692.  
  11693.  
  11694. Programmierhandbuch                                 WG-Vision - 220 -
  11695.  
  11696.  
  11697.  
  11698.  
  11699.  
  11700.  
  11701.  
  11702. Cursormask
  11703.  
  11704.      8421 8421 8421 8421
  11705.  
  11706.  0   .... .... .... ....     0000
  11707.  1   .X.. .... .... ....     4000
  11708.  2   .XX. .... .... ....     6000
  11709.  3   .XXX .... .... ....     7000
  11710.  4   .XXX X... .... ....     7800
  11711.  5   .XXX XX.. .... ....     7C00
  11712.  6   .XXX XXX. .... ....     7E00
  11713.  7   .XXX XXXX .... ....     7F00
  11714.  8   .XXX XXXX X... ....     7F80
  11715.  9   .XXX XXXX XX.. ....     7FC0
  11716. 10   .XXX XXX. .... ....     7C00
  11717. 11   .XX. .XX. .... ....     6600
  11718. 12   .... .XX. .... ....     0600
  11719. 13   .... ..XX .... ....     0300
  11720. 14   .... ..XX .... ....     0300
  11721. 15   .... .... .... ....     0000
  11722.  
  11723. Hot Spot : 0,0
  11724.  
  11725. Auf diese Weise können Sie ihren eigenen Mauskursor entwer-
  11726. fen. Mit folgenden Programm erstellen Sie daraus eine
  11727. Ressourcendatei. Diese Ressourcendatei muß in WG-Vision die
  11728. Extension .CUR erhalten:
  11729.  
  11730. program Mouse_Ressource;
  11731.  
  11732. type GraphCursorTyp=record
  11733.                       Mask:array[0..1,0..15] of word;
  11734.                       xspot,yspot:word;
  11735.                     end;
  11736.  
  11737.  
  11738.  
  11739.  
  11740.  
  11741.  
  11742.  
  11743.  
  11744. Programmierhandbuch                                 WG-Vision - 221 -
  11745.  
  11746.  
  11747.  
  11748.  
  11749.  
  11750.  
  11751.  
  11752. var f:file;              {Ressourcendatei}
  11753.     Result,i:integer;
  11754.  
  11755. Hier folgt die Definition von 10 verschiedenen Mauszeigern. Sie können
  11756. die Anzahl der Mauszeiger natürlich beliebig erweitern, indem Sie das
  11757. array neu dimensionieren.
  11758.  
  11759. const    MCursor : array[1..11] of GraphCursorTyp =
  11760.           ((Mask : {Pfeil}
  11761.             (($3FFF,$1FFF,$0FFF,$07FF,$03FF,$01FF,$00FF,$007F,
  11762.               $003F,$001F,$000F,$00FF,$10FF,$F87F,$F87F,$F87F),
  11763.              ($0000,$4000,$6000,$7000,$7800,$7C00,$7E00,$7F00,
  11764.               $7F80,$7FC0,$7C00,$6600,$0600,$0300,$0300,$000));
  11765.             xspot : 0;
  11766.             yspot : 0),
  11767.           ( Mask : {Hair}
  11768.             (($FFFF,$8FF1,$87E1,$C3C3,$E187,$F00F,$F81F,$FC3F,
  11769.               $F81F,$F00F,$E187,$C3C3,$87E1,$8FF1,$FFFF,$FFFF),
  11770.              ($0000,$0000,$300C,$1818,$0C30,$0660,$03C0,$0180,
  11771.               $03C0,$0660,$0C30,$1818,$300C,$0000,$00000,$0000));
  11772.             xspot : 8;
  11773.             yspot : 7),
  11774.           ( Mask : {Sanduhr}
  11775.             (($007F,$007F,$007F,$80FF,$80FF,$80FF,$80FF,$C1FF,
  11776.               $C1FF,$80FF,$80FF,$80FF,$80FF,$007F,$007F,$007F),
  11777.              ($0000,$0000,$3E00,$0000,$3E00,$2A00,$1400,$0800,
  11778.               $0000,$0800,$1400,$2A00,$0000,$3E00,$0000,$0000));
  11779.             xspot : 5;
  11780.             yspot : 8),
  11781.           ( Mask : {Vierfach-Pfeil}
  11782.             (($FEFF,$FC7F,$F83F,$F01F,$E00F,$C447,$8003,$0001,
  11783.               $8003,$C447,$E00F,$F01F,$F83F,$FC7F,$FEFF,$FFFF),
  11784.              ($0000,$0100,$0380,$07C0,$0100,$1110,$3118,$7FFC,
  11785.               $3118,$1110,$0100,$07C0,$0380,$0100,$0000,$0000));
  11786.             xspot : 8;
  11787.             yspot : 8),
  11788.  
  11789.  
  11790.  
  11791.  
  11792.  
  11793.  
  11794. Programmierhandbuch                                 WG-Vision - 222 -
  11795.  
  11796.  
  11797.  
  11798.  
  11799.  
  11800.  
  11801.  
  11802.           ( Mask : {Pfeil oben/unten gerade}
  11803.             (($FEFF,$FC7F,$F83F,$F01F,$E00F,$C007,$F83F,$F83F,
  11804.               $F83F,$F83F,$C007,$E00F,$F01F,$F83F,$FC7F,$FEFF),
  11805.              ($0000,$0100,$0380,$07C0,$0FE0,$0380,$0380,$0380,
  11806.               $0380,$0380,$0380,$0FE0,$07C0,$0380,$0100,$0000));
  11807.             xspot : 8;
  11808.             yspot : 8),
  11809.           ( Mask : {Pfeil links/rechts schräg}
  11810.             (($FFFF,$FE03,$FF01,$FF81,$F701,$F201,$F001,$F009,
  11811.               $F01D,$F03F,$F01F,$F80F,$FFFF,$FFFF,$FFFF,$FFFF),
  11812.              ($0000,$0000,$007C,$003C,$007C,$00FC,$05F4,$07E0,
  11813.               $07C0,$0780,$07C0,$0000,$0000,$0000,$00000,$0000));
  11814.             xspot : 10;
  11815.             yspot : 7),
  11816.           ( Mask : {Pfeil links/rechts gerade}
  11817.             (($FFFF,$FFFF,$FBDF,$F3CF,$E3C7,$C003,$8001,$0000,
  11818.               $8001,$C003,$E3C7,$F3CF,$FBDF,$FFFF,$FFFF,$FFFF),
  11819.              ($0000,$0000,$0000,$0000,$0810,$1818,$3FFC,$7FFE,
  11820.               $3FFC,$1818,$0810,$0000,$0000,$0000,$00000,$0000));
  11821.             xspot : 8;
  11822.             yspot : 8),
  11823.           ( Mask : {Pfeil rechts/links schräg}
  11824.             (($FFFF,$C07F,$80FF,$81FF,$80EF,$804F,$800F,$900F,
  11825.               $B80F,$FC0F,$F80F,$F01F,$FFFF,$FFFF,$FFFF,$FFFF),
  11826.              ($0000,$0000,$3E00,$3C00,$3E00,$3F00,$2FA0,$07E0,
  11827.               $03E0,$01E0,$03E0,$0000,$0000,$0000,$0000,$0000));
  11828.             xspot : 7;
  11829.             yspot : 7),
  11830.           ( Mask : {Kursorstrich}
  11831.             (($FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,
  11832.               $FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF),
  11833.              ($0000,$6C00,$1000,$1000,$1000,$1000,$1000,$1000,
  11834.               $1000,$1000,$1000,$1000,$1000,$1000,$6C00,$0000));
  11835.             xspot : 4;
  11836.             yspot : 7),
  11837.  
  11838.  
  11839.  
  11840.  
  11841.  
  11842.  
  11843.  
  11844. Programmierhandbuch                                 WG-Vision - 223 -
  11845.  
  11846.  
  11847.  
  11848.  
  11849.  
  11850.  
  11851.  
  11852.           ( Mask : {Hand}
  11853.             (($E1FF,$E1FF,$E1FF,$E1FF,$E1FF,$E000,$E000,$E000,
  11854.               $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000),
  11855.              ($1E00,$1200,$1200,$1200,$1200,$13FF,$1249,$1249,
  11856.               $F249,$9049,$9001,$8001,$8001,$8001,$8001,$FFFF));
  11857.             xspot : 4;
  11858.             yspot : 7),
  11859.           ( Mask : {Kursor-Kreuz gerade}
  11860.             (($FC7F,$FC7F,$FC7F,$FC7F,$FC7F,$FC7F,$0001,$0001,
  11861.               $0001,$FC7F,$FC7F,$FC7F,$FC7F,$FC7F,$FC7F,$FFFF),
  11862.              ($0100,$0100,$0100,$0100,$0100,$0100,$0100,$FFFE,
  11863.               $0100,$0100,$0100,$0100,$0100,$0100,$0100,$0000));
  11864.             xspot : 8;
  11865.             yspot : 8));
  11866.  
  11867. Und das ist schon alles ...
  11868.  
  11869. begin
  11870.   assign(f,'CURSOR.CUR');                  {Name der Ressourcendatei}
  11871.   rewrite(f,SizeOf(GraphCursorTyp));
  11872.   for i:=1 to 11 do                        {11 Kursortypen schreiben}
  11873.    BlockWrite(f, MCursor[i],1,Result);
  11874.   close(f);
  11875. end.
  11876.  
  11877.  
  11878.  
  11879.  
  11880.  
  11881.  
  11882.  
  11883.  
  11884.  
  11885.  
  11886.  
  11887.  
  11888.  
  11889.  
  11890.  
  11891.  
  11892.  
  11893.  
  11894. Programmierhandbuch                                 WG-Vision - 224 -
  11895.  
  11896.  
  11897.  
  11898.  
  11899.  
  11900.  
  11901.  
  11902. 6.1.4.2. Einige Hinweise zur Benutzung des Mausobjekts
  11903.  
  11904. Wenn Sie mit irgendeinem Grafikbefehl auf den Bildschirm
  11905. schreiben, schalten Sie zuvor den Mauszeiger aus und danach
  11906. wieder ein. Sonst kann es zu Fehlern bei der Bildschirmaus-
  11907. gabe kommen.
  11908.  
  11909. ...
  11910. Mouse.HideMouse;
  11911. OutTextXY(12,56,'Test');
  11912. Bar(0,80,150,120);
  11913. Mouse.ShowMouse;
  11914. ...
  11915.  
  11916. Um zu überprüfen, ob sich der Mauszeiger innerhalb eines be-
  11917. stimmten Areals auf dem Bildschirm befindet, reicht folgende
  11918. if -Anweisung aus:
  11919.  
  11920. ...
  11921. Area.Assign(345,128,458,260);
  11922. if Area.Contains(Mouse.Position) then ...
  11923. ...
  11924.  
  11925. Diese Abfrage können Sie natürlich auch noch mit der Abfrage
  11926. der Maustaste koppeln:
  11927.  
  11928. ...
  11929. if Area.Contains(Mouse.Position) and Mouse.LButtonKlick then ...
  11930. ...
  11931.  
  11932. Da die Mouse quasi unabhängig vom Eventhandler arbeitet, ist
  11933. eine Abfrage der Form
  11934.  
  11935. ...
  11936. if Event.What=evMouse then ...
  11937. ...
  11938.  
  11939. nur in Ausnahmefällen notwendig. Das gilt auch für eine
  11940. Tastaturabfrage.
  11941.  
  11942.  
  11943.  
  11944. Programmierhandbuch                                 WG-Vision - 225 -
  11945.  
  11946.  
  11947.  
  11948.  
  11949.  
  11950.  
  11951.  
  11952. Der Maushandler wird in WG-Vision nur innerhalb der Prozedur
  11953. GetEvent aufgerufen. Wenn Sie sich in einem Programmteil aus
  11954. dem Eventhandler ausklinken, indem Sie z.B. eine separate
  11955. Schleife programmieren, dann müssen Sie, wenn Sie die Maus
  11956. weiterhin benutzen möchten, innerhalb dieser Schleife den
  11957. Maushandler aufrufen.
  11958.  
  11959. procedure MeinFenster.HandleEvent;
  11960. begin
  11961.   TDlgWindow.HandleEvent;
  11962.   ...
  11963.   if Kennzahl=1 then
  11964.    repeat
  11965.      if Mouse.MouseHandler then;
  11966.      ...
  11967.    until Area.Contains(Mouse.Position) and Mouse.LButtonKlick;
  11968.   ...
  11969. end;
  11970.  
  11971.  
  11972.  
  11973.  
  11974.  
  11975.  
  11976.  
  11977.  
  11978.  
  11979.  
  11980.  
  11981.  
  11982.  
  11983.  
  11984.  
  11985.  
  11986.  
  11987.  
  11988.  
  11989.  
  11990.  
  11991.  
  11992.  
  11993.  
  11994. Programmierhandbuch                                 WG-Vision - 226 -
  11995.  
  11996.  
  11997.  
  11998.  
  11999.  
  12000.  
  12001.  
  12002. 6.1.5. SummaSketch-Digitizer - TSSDigiDevice
  12003.  
  12004. Zur Ansteuerung eines SummaSketch-Digitizers der Typen MM II
  12005. 1201 und MM II 1812 stellt WG-Vision das Objekt TSSDigiDevi-
  12006. ce zur Verfügung. Die Summagraphic-Digitizer lassen sich in
  12007. zwei verschiedenen Betriebsmodi betreiben. Während im MM-Mo-
  12008. de einfache ASCII-Codes vom Host-Rechner zur Steuerung des
  12009. Tabletts verwendet werden, ähnelt der UIOF ("Universal Input
  12010. Output Format") Mode mehr der Ansteuerung eines Druckers. In
  12011. diesem Modus wird zuerst das ESC-Zeichen und anschließend
  12012. meistens zwei Befehls-Codes gesendet.
  12013. Das Objekt TSSDigiDevice verwendet eine Auswahl der wichtig-
  12014. sten Befehle des MM-Modus. Sie unterteilen sich im wesentli-
  12015. chen in vier Gruppen:
  12016.  
  12017. 1. Übertragungs-Mode einschalten
  12018.  
  12019. POINT
  12020. Punkt-Modus. Das Tablett sendet nur dann ein Koordinaten-
  12021. paar, wenn der Stift oder eine Lupentaste gedrückt wird
  12022.  
  12023. STREAM
  12024. Stream-Modus. Das Tablett sendet kontinuierlich Daten.
  12025.  
  12026. SWSTREAM
  12027. Switch-Stream-Modus. Das Tablett überträgt immer dann konti-
  12028. nuierlich Daten, wenn der Stift oder eine Lupentaste ge-
  12029. drückt ist.
  12030.  
  12031. 2. Report-Rate einstellen
  12032.  
  12033. Die Reportrate gibt an, wieviele Koordinatenpaare pro Sekun-
  12034. de vom Tablett gesendet werden.
  12035.  
  12036.  
  12037.  
  12038.  
  12039.  
  12040.  
  12041.  
  12042.  
  12043.  
  12044. Programmierhandbuch                                 WG-Vision - 227 -
  12045.  
  12046.  
  12047.  
  12048.  
  12049.  
  12050.  
  12051.  
  12052. 3. Auflösung einstellen
  12053.  
  12054. Ein Digitizer läßt sich in verschiedenen Auflösungen betrei-
  12055. ben. In der Unit WDecl von WG-Vision finden Sie vordefinier-
  12056. te Konstanten, die Sie mit dem Befehl SetCommand zum Tablett
  12057. übertragen können. Die Maßeinheit ist Linien pro Zoll (lpi).
  12058.  
  12059. 4. Allgemeine Steuerfunktionen
  12060.  
  12061. Zu dieser Gruppe gehören Kommandos für den Selbsttest, zum
  12062. Rücksetzen des Tabletts auf die Standardwerte, zur Überprü-
  12063. fung der momentanen Konfiguration und zur Definition des Ko-
  12064. ordinatensystems.
  12065.  
  12066. Bedingung für die Arbeit mit TSSDigiDevice ist, daß das gra-
  12067. fische Tablett an einer der beiden seriellen Schnittstellen
  12068. des Rechners angeschlossen ist und in der Standardeinstel-
  12069. lung betrieben wird (9600 Baud, ungerade Parität, 8 Daten-
  12070. bits, 1 Stoppbit). Zur Übertragung wird das XON-XOFF-
  12071. Protokoll verwendet.
  12072. Bei der Initialisierung schaltet das Tablett in den ASCII-
  12073. BCD-Report-Mode um. In diesem Moment sendet der Digitizer
  12074. die Stift- bzw. Lupenkoordinaten als ASCII-Strings. Mit ein-
  12075. fachen Stringoperationen lassen sich daraus die momentanen
  12076. Koordinaten und der Stiftstatus bestimmen. Diese Arbeit wird
  12077. von der privaten Methode SelectValue ausgeführt. Sie über-
  12078. nimmt die vom Digitizer-Handler in einem Puffer bereitge-
  12079. stellten Daten, sucht sie nach Terminatorzeichen ab (Kommas)
  12080. und extrahiert daraus die x- und y-Koordinaten und die Num-
  12081. mer der gedrückten Taste. Anschließend werden diese Werte in
  12082. einem tDigiData-Record zwischengespeichert und können von
  12083. dort mit den Methoden GetXValue, GetYValue und GetTaste aus-
  12084. gelesen werden.
  12085.  
  12086.  
  12087.  
  12088.  
  12089.  
  12090.  
  12091.  
  12092.  
  12093.  
  12094. Programmierhandbuch                                 WG-Vision - 228 -
  12095.  
  12096.  
  12097.  
  12098.  
  12099.  
  12100.  
  12101.  
  12102. Konstanten (Befehlscodes), implementiert in WDECL.PAS
  12103.  
  12104. Übertragungsprotokoll
  12105.  
  12106. XON   = ^Q;
  12107. XOFF  = ^S;
  12108.  
  12109. Konfigurationsbefehle
  12110.  
  12111. DGRESET   = #0;      Rücksetzen
  12112. SELFTEST  = #116;    Selbsttest
  12113. SENDRES   = #119;    Senden der Selbsttest-Resultate
  12114. SENDCONF  = #97;     Konfiguration senden
  12115. SENDMODEL = #5;      Modell-Identifikationsstring senden
  12116.  
  12117. Modi
  12118.  
  12119. BCD       = #122#97; Ausgabe im ASCII-BCD-Format
  12120.  
  12121. POINT     = #66;     Point-Mode einschalten
  12122. STREAM    = #64;     Stream-Mode einschalten
  12123. SWSTREAM  = #65;     Switch-Stream-Mode einschalten
  12124.  
  12125. Report-Rate
  12126.  
  12127. RR110     = #81;     Report-Rate 110 rps (reports per
  12128.                                           second)
  12129. RR50      = #82;     Report-Rate 50 rps
  12130. RR10      = #83;     Report-Rate 10 rps
  12131. RR2       = #84;     Report-Rate 2 rps
  12132.  
  12133.  
  12134.  
  12135.  
  12136.  
  12137.  
  12138.  
  12139.  
  12140.  
  12141.  
  12142.  
  12143.  
  12144. Programmierhandbuch                                 WG-Vision - 229 -
  12145.  
  12146.  
  12147.  
  12148.  
  12149.  
  12150.  
  12151. Auflösung
  12152.  
  12153. Res1      = #108     Auflösung 1 lpi (lines per inch)
  12154. Res2      = #110;    Auflösung 2 lpi
  12155. Res4      = #112;    Auflösung 12 lpi
  12156. Res100    = #100;    Auflösung 100 lpi
  12157. Res200    = #101;    Auflösung 200 lpi
  12158. Res400    = #103;    Auflösung 400 lpi
  12159. Res500    = #104;    Auflösung 500 lpi
  12160. Res1000   = #106;    Auflösung 1000 lpi
  12161.  
  12162. Koordinatensystem
  12163.  
  12164. ABSOLUT   = #70;     absolutes Koordinatensystem
  12165. RELATIV   = #69;     relatives Koordinatensystem
  12166.  
  12167. Felder
  12168.  
  12169. COMPort
  12170. COMPort:byte;
  12171. Nummer der seriellen Schnittstelle (1 = COM1, 2 = COM2).
  12172.  
  12173. Buffer
  12174. Buffer:string[20];
  12175. Puffer zum Zwischenspeichern der Koordinaten
  12176.  
  12177. DigiData
  12178. DigiData:tDigiData;
  12179. Enthält die Koordinaten und die Nummer der gedrückten Lupen-
  12180. Taste.
  12181.  
  12182. Methoden
  12183.  
  12184. Init
  12185. procedure Init(SPort:byte);
  12186. Initialisierung des grafischen Tabletts. Übergabeparameter
  12187. ist die Nummer der seriellen Schnittstelle.
  12188.  
  12189.  
  12190.  
  12191.  
  12192.  
  12193.  
  12194. Programmierhandbuch                                 WG-Vision - 230 -
  12195.  
  12196.  
  12197.  
  12198.  
  12199.  
  12200.  
  12201.  
  12202. SetCommand
  12203. procedure SetCommand(cc:string);
  12204. Kommando oder Kommandofolge senden.
  12205.  
  12206. SetStreamMode
  12207. procedure SetStreamMode;
  12208. Stream-Mode setzen. Auflösung 50 lpi.
  12209.  
  12210. SetPointMode
  12211. procedure SetPointMode;
  12212. Point-Mode setzen. Koordinaten werden immer nur dann über-
  12213. tragen, wenn eine der Lupentasten oder der Stift gedrückt
  12214. wurde.
  12215.  
  12216. SetSwitchStream;
  12217. procedure SetSwitchStream;
  12218. Switch-Sream-Mode setzen. Kontinuierliches Senden von Koor-
  12219. dinaten, wenn eine Lupentaste oder der Stift gedrückt ist.
  12220.  
  12221. SetResolution
  12222. procedure SetResolution(cc:char);
  12223. Auflösung des Tabletts festlegen. Bitte verwenden Sie nur
  12224. die in der Unit WDecl vordefinierten Konstanten (Res1 ...).
  12225.  
  12226. SetReportRate
  12227. procedure SetReportRate(cc:char);
  12228. Einstellen der Reportrate des Tabletts. Verwenden Sie als
  12229. Übergabeparameter bitte die in der Unit WDecl vordefinierten
  12230. Konstanten (RR110 ...).
  12231.  
  12232. SetFrameWork
  12233. procedure SetFrameWork(cc:char);
  12234. Festlegen des Koordinatensystems. Für cc können die
  12235. Konstanten ABSOLUT und RELATIV verwendet werden.
  12236.  
  12237. GetModelIdentifier
  12238. function GetModelIdentifier:string;
  12239. Übertragung des Modell-Identifikationsstrings veranlassen.
  12240.  
  12241.  
  12242.  
  12243.  
  12244. Programmierhandbuch                                 WG-Vision - 231 -
  12245.  
  12246.  
  12247.  
  12248.  
  12249.  
  12250.  
  12251.  
  12252. DigiHandle
  12253. procedure DigiHandle;
  12254. Digitizer-Handler. Diese Routine muß in eine Handler-Schlei-
  12255. fe eingebunden werden. Der Handler übernimmt kontinuierlich
  12256. Daten vom Digitizer in seinen Puffer und bestimmt daraus die
  12257. Koordinaten und den Tastenstatus.
  12258.  
  12259. GetXValue
  12260. function GetXValue:word;
  12261. Übergibt den x-Wert der Lupenposition.
  12262.  
  12263. GetYValue
  12264. function GetYValue:word;
  12265. Übergibt den y-Wert der Lupenposition.
  12266.  
  12267. GetTaste
  12268. function GetTaste:byte;
  12269. Übergibt die Nummer der gedrückten Taste.
  12270.  
  12271. Beispiel
  12272.  
  12273. program DigiTest;
  12274. uses WDecl,
  12275.      WDriver;
  12276. var Digi:TSSDigiDevice;
  12277. begin
  12278.   with Digi do
  12279.    begin
  12280.      Init(2);
  12281.      SetStreamMode;
  12282.      repeat
  12283.        DigiHandle;
  12284.        write(GetXValue:10);
  12285.        writeln(GetYValue:10);
  12286.      until GetTaste=2;
  12287.    end;
  12288. end.
  12289.  
  12290.  
  12291.  
  12292.  
  12293.  
  12294. Programmierhandbuch                                 WG-Vision - 232 -
  12295.  
  12296.  
  12297.  
  12298.  
  12299.  
  12300.  
  12301.  
  12302. 6.2. UNIT WTEXT.PAS
  12303.  
  12304. Die Unit WText gehört mit zu den Kernroutinen von WG-Vision,
  12305. obwohl sie nur ein Objekt (TText) und drei Routinen zur Aus-
  12306. gabe der VGA-Sonderzeichensätze beinhaltet.
  12307.  
  12308. 6.2.1. Standard-VGA: Sonderzeichensätze
  12309.  
  12310. Die Sonderzeichensätze, die als Objekt-Dateien in die Unit
  12311. eingebunden sind, können nur in den 16-farbigen VGA-Modi
  12312. verwendet werden. Folgende Zeichensätze sind verfügbar:
  12313.  
  12314. type GraficFont=(Thin8,Thin14,Thin16,Brdwy19,Wndw19,Sansf19,VGAF);
  12315.  
  12316. VGAF ist der Standardzeichensatz der Unit Graph, die gewöhn-
  12317. lich in Verbindung mit OutTextXY verwendet wird. Die Zei-
  12318. chenbreite der Sonderfonts beträgt 8 Pixel, die Höhe ist der
  12319. Zahl zu entnehmen, die Bestandteil des Fontnamens ist.
  12320. Zur Arbeit mit den Sonderzeichensätzen stehen folgende Pro-
  12321. zeduren zur Verfügung:
  12322.  
  12323. SetFont
  12324. procedure SetFont(NewFont:GraficFont);
  12325. Aktivieren eines Sonderzeichensatzes vom Typ GraficFont.
  12326.  
  12327. WriteText
  12328. procedure WriteText(x,y:integer;st:string);
  12329. Entspricht OutTextXY, verwendet aber den aktivierten Sonder-
  12330. zeichensatz.
  12331.  
  12332. SetFontColor
  12333. procedure SetFontColor(bg,vg:byte);
  12334. Legt die Hintergrund- und Vordergrundfarbe des Sonderzei-
  12335. chensatzes fest.
  12336.  
  12337.  
  12338.  
  12339.  
  12340.  
  12341.  
  12342.  
  12343.  
  12344. Programmierhandbuch                                 WG-Vision - 233 -
  12345.  
  12346.  
  12347.  
  12348.  
  12349.  
  12350.  
  12351.  
  12352. Um die Geschwindigkeit der Textausgabe zu erhöhen, wurde ein
  12353. Teil der Routine WriteText in BASM formuliert.
  12354. Die Horizontale Positionierung des mit WriteText ausgegebe-
  12355. nen Strings ist nur an den Scan-Lines (d.h. alle 8 Pixel)
  12356. möglich.
  12357.  
  12358. Objekt TText
  12359.  
  12360. Felder
  12361.  
  12362. R
  12363. R:TRect;
  12364. Rechteckiger Bereich, der den Viewport bestimmt, in das der
  12365. Text geschrieben wird. Die Bereichsgrenzen sind gleichzeitig
  12366. die Clip-Grenzen.
  12367.  
  12368. Font
  12369. Font:word;
  12370. Aktiver Vektorzeichensatz. Die Nummern entsprechen den in
  12371. der Unit WDecl vorgegebenen Konstanten.
  12372.  
  12373. Direction
  12374. Direction:word;
  12375. Ausrichtung des Textes. Folgende Werte sind möglich: Horiz-
  12376. Dir, VertDir
  12377.  
  12378. CharSize
  12379. CharSize:byte;
  12380. Buchstabengröße entsprechend der Konventionen der Unit
  12381. Graph.
  12382.  
  12383. TextHeight
  12384. TextHeight:word;
  12385. Texthöhe entsprechend der Konventionen der Unit Graph.
  12386.  
  12387. TextWidth
  12388. TextWidth:word;
  12389. Textbreite entsprechend der Konventionen der Unit Graph.
  12390.  
  12391.  
  12392.  
  12393.  
  12394. Programmierhandbuch                                 WG-Vision - 234 -
  12395.  
  12396.  
  12397.  
  12398.  
  12399.  
  12400.  
  12401.  
  12402. Zeile
  12403. Zeile:string;
  12404. Auszugebender Text.
  12405.  
  12406. Methoden
  12407.  
  12408. Init
  12409. constructor Init;
  12410. Setzt R auf den gesamten Bildschirm, aktiviuert den Stan-
  12411. dardzeichensatz und setzt die Textkonstanten auf die Stan-
  12412. dardwerte.
  12413.  
  12414. Done
  12415. destructor Done;
  12416. Leere Methode. (Hier müßte eigentlich der zuletzt geladene
  12417. Vektorzeichensatz aus dem Speicher geschmissen werden. Wer
  12418. hat dazu eine Idee ?)
  12419.  
  12420. SetFont
  12421. procedure SetFont(FFont,FDirection:word);
  12422. Vektorzeichensatz und Ausgaberichtung festlegen.
  12423.  
  12424. SetCharSize
  12425. procedure SetCharSize(FCharSize:byte);
  12426. Buchstabengröße festlegen.
  12427.  
  12428. SetClipFrame
  12429. procedure SetClipFrame(T:TRect);
  12430. Bereich festlegen, in welcher geschrieben werden darf. Die
  12431. Bereichsgrenzen dienen als Clip-Grenzen.
  12432.  
  12433. SetDefaultText;
  12434. procedure SetDefaultText;
  12435. Aktiviert den Standardzeichensatz.
  12436.  
  12437. LText
  12438. procedure LText(x,y:integer;z:string);
  12439. Linksbündige Ausgabe des Textes z an der Position x,y rela-
  12440. tiv zum Clipfenster.
  12441.  
  12442.  
  12443.  
  12444. Programmierhandbuch                                 WG-Vision - 235 -
  12445.  
  12446.  
  12447.  
  12448.  
  12449.  
  12450.  
  12451.  
  12452. RText
  12453. procedure RText(x,y:integer;z:string);
  12454. Rechtsbündige Ausgabe des Textes z an der Position x,y rela-
  12455. tiv zum Clipfenster.
  12456.  
  12457. CText
  12458. procedure CText(x,y:integer;z:string);
  12459. Zentrierte Ausgabe des Textes z an der Position x,y relativ
  12460. zum Clipfenster.
  12461.  
  12462. Instanzen des Objekts TText werden besonders in der Unit
  12463. WDlg verwendet (Paneltext, statischer Text in Dialogfen-
  12464. stern). Weitere Zeichensätze stellt die WG-Vision Zusatz-
  12465. Unit WFONT zur Verfügung.
  12466.  
  12467. Beispiel:  Auflisten aller in WText implementierten
  12468.            Sonderzeichensätze
  12469.  
  12470. program Sonderzeichensaetze;
  12471.  
  12472. uses WDecl,
  12473.      WDriver,
  12474.      WText,
  12475.      crt,
  12476.      graph;
  12477.  
  12478. begin
  12479.   Video.Init(VGA,M640x480);
  12480.   SetFont(Brdwy19);
  12481.   SetFontColor(Black,Yellow);
  12482.   WriteText(10,50,'Sonderzeichensätze der Unit WText');
  12483.   SetFontColor(Black, White);
  12484.   SetFont(Thin8);
  12485.   WriteText(10,100,'Thin8   ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ
  12486.                             abcdefghijklmnopqrstuvwxyzäöü0123456789');
  12487.  
  12488.  
  12489.   SetFont(Thin14);
  12490.  
  12491.  
  12492.  
  12493.  
  12494. Programmierhandbuch                                 WG-Vision - 236 -
  12495.  
  12496.  
  12497.  
  12498.  
  12499.  
  12500.  
  12501.  
  12502.   WriteText(10,125,'Thin14  ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ
  12503.                             abcdefghijklmnopqrstuvwxyzäöü0123456789');
  12504.   SetFont(Thin16);
  12505.   WriteText(10,150,'Thin16  ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ
  12506.                             abcdefghijklmnopqrstuvwxyzäöü0123456789');
  12507.   SetFont(Wndw19);
  12508.   WriteText(10,175,'Wndw19  ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ
  12509.                             abcdefghijklmnopqrstuvwxyzäöü0123456789');
  12510.   SetFont(Sans19);
  12511.   WriteText(10,200,'Sans19  ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ
  12512.                             abcdefghijklmnopqrstuvwxyzäöü0123456789');
  12513.   SetFont(Brdwy19);
  12514.   WriteText(10,225,'Brdwy19 ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ
  12515.                             abcdefghijklmnopqrstuvwxyzäöü0123456789');
  12516.   SetFont(VGAF);
  12517.   WriteText(10,255,'VGAF    ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ
  12518.                             abcdefghijklmnopqrstuvwxyzäöü0123456789');
  12519.   repeat until keypressed;
  12520.   Video.Done;
  12521. end.
  12522.  
  12523.  
  12524.  
  12525.  
  12526.  
  12527.  
  12528.  
  12529.  
  12530.  
  12531.  
  12532.  
  12533.  
  12534.  
  12535.  
  12536.  
  12537.  
  12538.  
  12539.  
  12540.  
  12541.  
  12542.  
  12543.  
  12544. Programmierhandbuch                                 WG-Vision - 237 -
  12545.  
  12546.  
  12547.  
  12548.  
  12549.  
  12550.  
  12551.  
  12552. 6.3. UNIT WFONT.PAS
  12553.  
  12554. Die Verwendung von BGI-Vektorzeichensätzen und von VGA-ROM-
  12555. Zeichensätzen, Erstellung von eigenen Zeichensatz-Ressourcen
  12556. mit dem Shareware-Programm FontMania von REXXCOM-Systems
  12557.  
  12558. 6.3.1. ROM- und Userzeichensätze in WG-Vision - TPixelFont
  12559.  
  12560. Die Anzahl der Pixelzeichensätze, die ein geschickter Turbo-
  12561. Pascal-Programmierer seiner VGA-Karte entlocken kann, ist
  12562. nicht gerade überwältigend. Dabei bietet das BIOS der VGA-
  12563. Karte alle Möglichkeiten, um in Verbindung mit einem VGA-
  12564. Zeichensatzeditor die schönsten Fonts auf dem Bildschirm zu
  12565. zaubern.
  12566. Derartige Zeichensatzeditoren findet man in vielen Shareware-
  12567. und Public Domain-Sammlungen. Das Programm FontMania der
  12568. amerikanischen Firma REXXCOM-Systems ist für diesen Zweck
  12569. besonders gut geeignet. Es besitzt die interessante Eigen-
  12570. schaft, daß mit diesem Programm erzeugte Fonts in Form von
  12571. Pascal-Includedateien abge-legt werden können. Aus diesen In-
  12572. clude-Dateien lassen sich leicht allgemein nutzbare "Font-
  12573. Ressourcen" erstellen, aus denen man zur Laufzeit eines Pro-
  12574. gramms Zeichensätze laden und über den Interrupt $11 den
  12575. Textausgaberoutinen von Turbo-Pascal zugänglich machen kann.
  12576.  
  12577. 6.3.2. FONTMANIA
  12578.  
  12579. FontMania besticht durch seine vielfältigen Editiermöglich-
  12580. keiten. So können Fonts verschiedener Größe erstellt oder
  12581. bereits vorhandene Schriften geladen und nachträglich verän-
  12582. dert werden. Der eigenen Kreativität sind hier kaum Grenzen
  12583. gesetzt. Wer sich jedoch diese Arbeit ersparen will, braucht
  12584. nur die Vollversion bestellen. Neben dem Programm erhält man
  12585. zusätzlich einen Satz von 25 ausgesuchten Schriften. Aber
  12586. auch die Assembler- und C-Programmierer kommen nicht zu
  12587. kurz. FontMania legt auf Wunsch die Fontdaten in Dateien ab,
  12588. die Assembler- und C-Programme nutzen können. Das normale
  12589. Ausgabeformat ist jedoch eine COM-Datei. Um im Alphamodus
  12590. den Zeichensatz zu wechseln (wie wär's mal mit einem Kyril-
  12591.  
  12592.  
  12593.  
  12594. Programmierhandbuch                                 WG-Vision - 238 -
  12595.  
  12596.  
  12597.  
  12598.  
  12599.  
  12600.  
  12601.  
  12602. lischen oder Hebräischen ?) brauchen Sie nur noch vom Sys-
  12603. temprompt aus eine derartige COM-Datei zu starten. Bis auf
  12604. Widerruf (mode co80) werden jetzt alle Textausgaben im neuen
  12605. Zeichensatz ausgeführt. Sogar die meisten Programme zeigen
  12606. sich nun mit den neuen Schriftzeichen. Starten Sie einfach
  12607. innerhalb der Turbo-Pascal-IDE das Testprogramm zur
  12608. Darstellung der Zeichensätze im Alphamodus. Da innerhalb
  12609. dieses Programms der Destruktor nicht aufgerufen wird,
  12610. erscheint nach Beendigung des Programms die Compiler-
  12611. Oberfläche in einem neuen Zeichensatz.
  12612.  
  12613. Aufbau
  12614.  
  12615. Haben Sie einen neuen Font komplett erstellt (also alle 256
  12616. Zeichen), dann können Sie über den Menüpunkt "Pascal" von
  12617. FontMania eine Includedatei erzeugen. Diese Includedatei
  12618. enthält als array of char die Pixeldaten der einzelnen
  12619. Schriftzeichen und in der Variablen Points die Höhe der Zei-
  12620. chen in Pixel. Im Deklarationsteil der Unit WFONT.PAS wird
  12621. diese Struktur verallgemeinert:
  12622.  
  12623. type FontType=record
  12624.       Name   : string[10];                       {Font-Name}
  12625.       Points : char;                           {Zeichenhöhe}
  12626.       Data   : array[1..4096] of char;         {Rasterdaten}
  12627.      end;
  12628.  
  12629. Ist Points=$10, dann beschreibt FonType einen 8x16-Pixel-
  12630. font. Data enthält die Rasterdaten für 256 Zeichen, so daß
  12631. zur Kodierung eines Zeichens 16 Bytes benötigt werden. Der
  12632. genauen Aufbau eines Zeichens wird im folgenden Abschnitt
  12633. behandelt. Mit diesen Informationen können Sie dann selbst
  12634. Zeichensätze auf kariertem Papier entwerfen und auf diese
  12635. Weise ohne FontMania eigene VGA-Fontdateien erstellen (ich
  12636. meine nur, wenn Sie nichts besseres zu tun haben ...).
  12637.  
  12638.  
  12639.  
  12640.  
  12641.  
  12642.  
  12643.  
  12644. Programmierhandbuch                                 WG-Vision - 239 -
  12645.  
  12646.  
  12647.  
  12648.  
  12649.  
  12650.  
  12651.  
  12652. 6.3.3. Fonts-Ressourcen
  12653.  
  12654. Fonts mit prinzipiell gleichem Aufbau sollten Sie in soge-
  12655. nannten Fontressourcen speichern. Darunter versteht man un-
  12656. typisierte Dateien, die aus Blöcken vom Typ FontType
  12657. bestehen. Sie können beliebig viele Zeichensätze enthalten,
  12658. die ein Anwendungsprogramm bei Bedarf nachladen kann.
  12659. Der prinzipielle Aufbau eines Programms, welches aus FontMa-
  12660. nia-Daten Fontressourcen erzeugen kann, zeigt Listing 1. Da-
  12661. mit die Fontressource mit dem Objekt TPixelFont mitspielt,
  12662. muß sie die Extension .FNT tragen.
  12663. Die Rasterdaten kopieren Sie einfach innerhalb der IDE mit-
  12664. tels der Blockbefehle aus den Include-Dateien in das Pro-
  12665. gramm CreateFontFile. Anschließend löschen Sie alle unnützen
  12666. Daten heraus und überprüfen die Klammerung. Nach fehlerfrei-
  12667. er Kompilierung und Abarbeitung erhalten Sie die Fontdatei
  12668. VGAFONT.FNT.
  12669.  
  12670. 6.3.4. Objekt TPixelFont
  12671.  
  12672. Die Methoden zum Zugriff auf VGA-ROM-Fonts und FontMania-Pixel-
  12673. ressourcen sind in einem Objekt mit dem Namen TPixelFont verpackt:
  12674.  
  12675. const Underline = 1;   {Schriftattribute für ROM-Zeichensätze}
  12676.       Bold      = 2;
  12677.       Small     = 3;
  12678.  
  12679.      PPixelFont=^TPixelFont;
  12680.      TPixelFont=object(TObject)
  12681.        Font      : FontType;          {User-Zeichensatz}
  12682.        ROMFont   : byte;              {Funktionsnummer ROM-ZS}
  12683.        CharSize  : byte;              {Zeichenhöhe}
  12684.        constructor SetFont(f:string); {Zeichensatz installieren}
  12685.        destructor Done; virtual;      {Rücksetzen auf 8x8}
  12686.                                       {Standardzeichensatz}
  12687.        function GetFontName:string;   {Name des gerade aktiven}
  12688.                                       {Pixelfonts}
  12689.        procedure SetFontStyle(Style:byte);
  12690.      end;
  12691.  
  12692.  
  12693.  
  12694. Programmierhandbuch                                 WG-Vision - 240 -
  12695.  
  12696.  
  12697.  
  12698.  
  12699.  
  12700.  
  12701.  
  12702. Mit dem Konstruktor SetFont können Sie eine Instanz von TPixel-
  12703. font auf dem Heap anlegen. Für den String, den Sie dabei
  12704. übergeben müssen, gelten folgende Konventionen:
  12705.  
  12706. 1. ROM-Fonts
  12707.  
  12708. Wenn Sie einen ROM-Font laden möchten, dann übergeben Sie
  12709. einen der Bezeichner ROM8x8, ROM8x14 oder ROM8x16 als
  12710. String. Die Rasterdaten für die Schriftsätze werden in die-
  12711. sem Fall aus der entsprechenden Tabelle des VGA-BIOS ko-
  12712. piert.
  12713.  
  12714. 2. Font-Ressource
  12715.  
  12716. Möchten Sie jedoch einen Zeichensatz aus einer Fontressource
  12717. laden, dann übergeben Sie den Namen der Fontdatei mit
  12718. vorangestellten Doppelkreuz und, mit einem Schrägstrich vom
  12719. Dateinamen getrennt, die Nummer des Zeichensatzes (siehe
  12720. Beispielprogramm).
  12721.  
  12722. Der Destruktor Done schaltet wieder auf den 8x8 Standardzei-
  12723. chensatz zurück. Mit der Funktion GetFontName erhalten Sie
  12724. den Namen des gerade aktiven Zeichensatzes.
  12725.  
  12726. Schriftattribute
  12727.  
  12728. Durch Manipulation der ROM-Fonts im Speicher lassen sich
  12729. leicht dünne, fette und unterstrichene Zeichensätze erzeu-
  12730. gen. Sie brauchen dazu der Methode SetFontStyle nur die ent-
  12731. sprechende typisierte Konstante (Underline, Bold, Small)
  12732. übergeben. Auf diese Weise kommen Sie zu weiteren 9 Schrift-
  12733. typen. In der in der Unit WFont implementierten Form lassen
  12734. sich diese modifizierten Zeichensätze nur im Grafikmodus
  12735. verwenden. Im Alphamode hat der Befehl SetFontStyle keine
  12736. Auswirkungen.
  12737.  
  12738.  
  12739.  
  12740.  
  12741.  
  12742.  
  12743.  
  12744. Programmierhandbuch                                 WG-Vision - 241 -
  12745.  
  12746.  
  12747.  
  12748.  
  12749.  
  12750.  
  12751.  
  12752. Grafikmodus
  12753.  
  12754. Damit Sie die neuen Schriftarten auch im Grafikmodus nutzen
  12755. können, sind ein paar Vorarbeiten notwendig. Neben der obli-
  12756. gatorischen Unit Graph benötigen Sie die Unit CRT. Sie ist
  12757. zwar in erster Linie für den Alphabildschirm konzipiert.
  12758. Aber indem Sie die Variable DirectVideo auf false setzen,
  12759. sind die wichtigsten Routinen von CRT wie z.B. write/wri-
  12760. teln, gotoXY oder TextColor auch im Grafikmodus nutzbar.
  12761. DirectVideo:=false erzwingt, daß sämtliche Textausgaben über
  12762. das BIOS erfolgen.
  12763. Daß das aber nicht völlig fehlerfrei vonstatten geht, merken
  12764. Sie, wenn Sie im VGA-Standardmode ($12) mehr als 25 Zeilen
  12765. schreiben möchten. Es kommt zu einem Scrolling mit der unan-
  12766. genehmen Eigenschaft, daß jede neue Zeile mit der gerade ak-
  12767. tiven Vordergrundfarbe gefüllt wird. Um Abhilfe zu schaffen
  12768. gibt es einen einfachen, aber leider undokumentierten Trick.
  12769. Sie setzen die in der Unit CRT vordefinierte Variable WindMax
  12770. einfach auf $FFFF. und schon ist alles OK.
  12771. Im Grafikmodus lassen sich Ausgaben mit verschiedenen Fonts
  12772. mischen. Auf diese Weise ist echtes Wysiwyg ("what you see
  12773. is what you get") möglich. Im Alphamodus bleibt Ihnen leider
  12774. nichts anderes übrig, als mit immer nur einem Zeichensatz zu
  12775. arbeiten. Ein Wechsel des Fonts hat Auswirkungen auf alle
  12776. Ausgaben auf dem Bildschirm.
  12777. In der Unit WFont wird mit einem kleinen Trick ausgetestet,
  12778. ob sich der Rechner im Alpha- oder Grafikmodus befindet. Das
  12779. ist notwendig, da in beiden Modi User-Zeichensätze unter-
  12780. schiedlich aufgerufen werden. Die Prozedur GetMaxX ermittelt
  12781. im Grafikmodus die maximal mögliche x-Koordinate des Bild-
  12782. schirms. Ist jedoch ein Alphamode eingeschaltet, dann lie-
  12783. fert diese Funktion Null.
  12784.  
  12785. Beispiel-Listing 1
  12786.  
  12787. Mit diesem Programm können Sie Fontressourcen erstellen. Die
  12788. Rasterdaten für die einzelnen Schriften entnehmen Sie den
  12789. Pascal-Include-Dateien, die Sie mit dem Zeichensatzeditor
  12790. FontMania erzeugen (wenn Sie Lust haben, können Sie natür-
  12791.  
  12792.  
  12793.  
  12794. Programmierhandbuch                                 WG-Vision - 242 -
  12795.  
  12796.  
  12797.  
  12798.  
  12799.  
  12800.  
  12801.  
  12802. lich auch Zeichensätze selbst kodieren. Oder, was noch bes-
  12803. ser wäre, schreiben Sie mit WG-Vision selbst einen
  12804. Fonteditor!).
  12805.  
  12806. program CreateFontFile;
  12807.  
  12808. type FontType=record
  12809.                 Name   : string[10];             {Font-Name}
  12810.                 Points : char;                   {Zeichenhöhe}
  12811.                 Data   : array[1..4096] of char; {Rasterdaten}
  12812.               end;
  12813.  
  12814. const VGAFont:array[1..4] of FontType=  {4 Schriftarten}
  12815.       ((Name: 'JULIE';
  12816.         Points:#16;
  12817.         Data:( ---> hier stehen die aus der Include-Datei ent-
  12818.                nommenen Rasterdaten für 256 Zeichen der
  12819.                Schriftart JULIE ));
  12820.  
  12821.        (Name: 'POOTER';
  12822.         Points:#16;
  12823.         Data:( ---> hier stehen die aus der Include-Datei ent-
  12824.                nommenen Rasterdaten für 256 Zeichen der
  12825.                Schriftart POOTER ));
  12826.         ...
  12827.  
  12828. var f:file;
  12829.     Font:FontType;
  12830.     i,Result:integer;
  12831. begin
  12832.   assign(f,'VGAFONT.FNT');
  12833.   rewrite(f,SizeOf(Font));
  12834.   for i:=1 to 4 do BlockWrite(f, VGAFont[i],1,Result);
  12835.   close(f);
  12836. end.
  12837.  
  12838.  
  12839.  
  12840.  
  12841.  
  12842.  
  12843.  
  12844. Programmierhandbuch                                 WG-Vision - 243 -
  12845.  
  12846.  
  12847.  
  12848.  
  12849.  
  12850.  
  12851.  
  12852. Aufbau eines Eintrags in der Font-Ressource
  12853.  
  12854. Codierung des Buchstabens "A"
  12855.  
  12856.          8421 8421
  12857.  
  12858.      0   .... ....           00
  12859.      1   .... ....           00
  12860.      2   .... ....           00
  12861.      3   .... X...           08
  12862.      4   .... X...           08
  12863.      5   ...X .X..           14
  12864.      6   ...X .X..           14
  12865.      7   XXXX XXX.           FE
  12866.      8   ..X. ..X.           22
  12867.      9   ..X. ..X.           22
  12868.     10   .X.. ...X           41
  12869.     11   -X.. ...X           41
  12870.     12   .X.. ...X           41
  12871.     13   .... ....           00
  12872.     14   .... ....           00
  12873.     15   .... ....           00
  12874.  
  12875. Der neue Buchstabe "A" wird durch folgende Bytefolge
  12876. codiert:
  12877.  
  12878. $00,$00,$00,$08,$08,$14,$14,$FE,$22,$22,$41,$41,$41,$00,$00,$00
  12879.  
  12880. 256 Zeichen ergeben demnach 4096 Byte (siehe Datenstruktur
  12881. FontType). Die Zeichen müssen entsprechend der ASCII-Tabelle
  12882. angeordnet sein.
  12883. Wer bastelt mal einen ordentlichen Fonteditor (natürlich mit
  12884. WG-Vision) zusammen ?
  12885.  
  12886.  
  12887.  
  12888.  
  12889.  
  12890.  
  12891.  
  12892.  
  12893.  
  12894. Programmierhandbuch                                 WG-Vision - 244 -
  12895.  
  12896.  
  12897.  
  12898.  
  12899.  
  12900.  
  12901.  
  12902. Beispiel-Listing 2
  12903.  
  12904. Ausschnitt aus der Unit WFONT.PAS von WG-Vision. Implementation der
  12905. Objektklasse TPixelFont.
  12906.  
  12907. UNIT WFont;
  12908.  
  12909. INTERFACE
  12910.  
  12911. uses dos,
  12912.      crt,
  12913.      graph;
  12914.  
  12915. const Underline = 1;             {Schriftattribute für ROM-Zeichensätze}
  12916.       Bold      = 2;
  12917.       Small     = 3;
  12918.  
  12919.       intern    = 1;                             {Fehlerindex für Error}
  12920.  
  12921. type FontType=record                        {Zeichensatzblock aus einer}
  12922.                 Name    : string[10];          {WG-Vision-Fontressource}
  12923.                 Points  : char;
  12924.                 Data    : array[1..4096] of char;
  12925.               end;
  12926.  
  12927.      tError =array[1..10] of integer;                      {Fehler-Code}
  12928.  
  12929.      PPixelFont=^TPixelFont;
  12930.      TPixelFont=object
  12931.        Font      : FontType;                          {User-Zeichensatz}
  12932.        ROMFont   : byte;                    {Funktionsnummer des ROM-ZS}
  12933.        CharSize  : byte;                                   {Zeichenhöhe}
  12934.        constructor SetFont(f:string);         {Zeichensatz installieren}
  12935.        destructor Done; virtual;                    {Rücksetzen auf 8x8}
  12936.                                                    {Standardzeichensatz}
  12937.        function GetFontName:string;            {Name des gerade aktiven}
  12938.                                                             {Pixelfonts}
  12939.        procedure SetFontStyle(Style:byte);
  12940.      end;
  12941.  
  12942.  
  12943.  
  12944. Programmierhandbuch                                 WG-Vision - 245 -
  12945.  
  12946.  
  12947.  
  12948.  
  12949.  
  12950.  
  12951.  
  12952. var Error:tError;
  12953.  
  12954. IMPLEMENTATION
  12955.  
  12956. type CMatrix8 = array[0..7]   of byte;        {Zeichenmatrizen für ver-}
  12957.      CMatrix14= array[0..13]  of byte;         {schiedene Schriftgrößen}
  12958.      CMatrix16= array[0..15]  of byte;
  12959.      FType8   = array[0..255] of CMatrix8;
  12960.      FType14  = array[0..255] of CMatrix14;
  12961.      FType16  = array[0..255] of CMatrix16;
  12962.  
  12963. var reg:Registers;
  12964.  
  12965.      Font8    : array[1..3] of FType8;         {Zeichensatztabellen für}
  12966.      Font14   : array[1..3] of FType14;         {manipulierte ROM-Fonts}
  12967.      Font16   : array[1..3] of FType16;
  12968.  
  12969.      p   : pointer;
  12970.      i,j : integer;
  12971.  
  12972.  
  12973. {Implementation TPixelFont}
  12974.  
  12975. Laden eines Pixelzeichensatzes aus einer Ressourcendatei (#Name/n) bzw
  12976. aus dem VGA-ROM
  12977.  
  12978. constructor TPixelFont.SetFont(f:string);
  12979. var Nr:byte;
  12980.     s:string;
  12981.     err,Anzahl:integer;
  12982.     OK:word;
  12983.     dat:file;
  12984.     p:pointer;
  12985. begin
  12986.   if f[1]='#' then
  12987.    begin
  12988.      delete(f,1,1);
  12989.      Nr:=Pos('/',f);
  12990.      s:=copy(f,Nr+1,length(f)-Nr);
  12991.  
  12992.  
  12993.  
  12994. Programmierhandbuch                                 WG-Vision - 246 -
  12995.  
  12996.  
  12997.  
  12998.  
  12999.  
  13000.  
  13001.  
  13002.      delete(f,Nr,(length(f)-Nr)+1);
  13003.      val(s,Nr,err);
  13004.      if err<>0 then Exit;
  13005.      f:=f+'.FNT';                                   {Extension anhängen}
  13006.      assign(dat,f);
  13007.      {$I-}
  13008.      reset(dat,SizeOf(Font));
  13009.      {$I+}
  13010.      if IOResult<>0 then
  13011.       begin
  13012.         Error[intern]:=IOResult;
  13013.         Exit;
  13014.       end;
  13015.      Anzahl:=FileSize(dat);           {Anzahl Schriftarten in der Datei}
  13016.      if (Nr>0) and (Nr<=Anzahl) then
  13017.       begin
  13018.         seek(dat,Nr-1);
  13019.         BlockRead(dat,Font,1,OK);
  13020.       end;
  13021.      close(dat);
  13022.      if GetMaxX>0 then               {im Grafikmodus ? --> Trick 0-8-15}
  13023.       with reg do               {User-Zeichensatz Grafikmode aktivieren}
  13024.        begin
  13025.          ah:=$11;
  13026.          al:=$21;
  13027.          bl:=0;
  13028.          cx:=byte(Font.Points);
  13029.          dl:=43;
  13030.          es:=seg(Font.Data);
  13031.          bp:=ofs(Font.Data);
  13032.          intr($10,reg);
  13033.        end
  13034.        else
  13035.       with reg do
  13036.        begin                                                 {Alphamode}
  13037.          ah:=$11;
  13038.          al:=$10;                         {automatische Zeilenanpassung}
  13039.          bl:=0;
  13040.          bh:=byte(Font.Points);
  13041.  
  13042.  
  13043.  
  13044. Programmierhandbuch                                 WG-Vision - 247 -
  13045.  
  13046.  
  13047.  
  13048.  
  13049.  
  13050.  
  13051.  
  13052.          cx:=256;
  13053.          dx:=0;
  13054.          es:=seg(Font.Data);
  13055.          bp:=ofs(Font.Data);
  13056.          intr($10,reg);
  13057.        end;
  13058.      CharSize:=byte(Font.Points);
  13059.      ROMFont:=0;
  13060.    end
  13061.    else                                         {ROM-Zeichensätze holen}
  13062.    begin
  13063.      ROMFont:=0;
  13064.      if f='ROM8x14' then
  13065.       begin
  13066.         ROMFont:=$22;
  13067.         CharSize:=14;
  13068.       end;
  13069.      if f='ROM8x8'  then
  13070.       begin
  13071.         ROMFont:=$23;
  13072.         CharSize:=8;
  13073.       end;
  13074.      if f='ROM8x16' then
  13075.       begin
  13076.         ROMFont:=$24;
  13077.         CharSize:=16;
  13078.       end;
  13079.      with reg do                           {ROM-Zeichensätze aktivieren}
  13080.       begin
  13081.         ah:=$11;
  13082.         al:=ROMFont;
  13083.         bl:=0;
  13084.         dl:=43;
  13085.         intr($10,reg);
  13086.       end
  13087.    end;
  13088. end;
  13089.  
  13090.  
  13091.  
  13092.  
  13093.  
  13094. Programmierhandbuch                                 WG-Vision - 248 -
  13095.  
  13096.  
  13097.  
  13098.  
  13099.  
  13100.  
  13101.  
  13102. Lädt den 8x8 Standardzeichensatz
  13103.  
  13104. destructor TPixelFont.Done;
  13105. begin
  13106.   with reg do
  13107.    begin
  13108.      ah:=$11;
  13109.      al:=$23;                   {Unterfunktion zum Laden des 8x8 ROM-ZS}
  13110.      bl:=0;
  13111.      dl:=43;
  13112.      intr($10,reg);
  13113.    end;
  13114. end;
  13115.  
  13116. Ermittelt den Namen des gerade aktiven Fonts
  13117.  
  13118. function TPixelFont.GetFontName:string;
  13119. begin
  13120.   if ROMFont in [$22..$24] then
  13121.    begin
  13122.      case ROMFont of
  13123.       $22 : GetFontName:='ROM8x14';
  13124.       $23 : GetFontName:='ROM8x8';
  13125.       $24 : GetFontName:='ROM8x16';
  13126.      end;
  13127.    end
  13128.    else GetFontName:=Font.Name;
  13129. end;
  13130.  
  13131. Zusatzzeichensätze für unterstrichene, fette und schmale Zeichen. Die
  13132. Ableitung erfolgt aus den ROM-Zeichensätzen.
  13133.  
  13134. procedure TPixelFont.SetFontStyle(Style:byte);
  13135.  
  13136.  
  13137.  
  13138.  
  13139.  
  13140.  
  13141.  
  13142.  
  13143.  
  13144. Programmierhandbuch                                 WG-Vision - 249 -
  13145.  
  13146.  
  13147.  
  13148.  
  13149.  
  13150.  
  13151.  
  13152. function FontAdr:pointer;
  13153. begin
  13154.   if ROMFont in [$22..$24] then
  13155.    begin
  13156.      with reg do
  13157.       begin
  13158.         ah:=$11;
  13159.         al:=$30;
  13160.         case ROMFont of
  13161.          $22 : bh:=2;
  13162.          $23 : bh:=3;
  13163.          $24 : bh:=6;
  13164.         end; {case}
  13165.         intr($10,reg);
  13166.         FontAdr:=ptr(es,bp);
  13167.       end;
  13168.    end
  13169.    else FontAdr:=nil;                            {kein ROM-Font aktiv}
  13170. end;
  13171.  
  13172. procedure SetSpecialFont(var FTable);
  13173. begin
  13174.   if GetMaxX>0 then
  13175.   with reg do                         {Spezial-Zeichensatz aktivieren}
  13176.    begin
  13177.      ah:=$11;
  13178.      al:=$21;
  13179.      bl:=0;
  13180.      cx:=CharSize;
  13181.      dl:=43;
  13182.      es:=seg(FTable);
  13183.      bp:=ofs(FTable);
  13184.      intr($10,reg);
  13185.    end;
  13186. end;
  13187.  
  13188. begin
  13189.   if ROMFont=0 then Exit;
  13190.   p:=FontAdr;
  13191.  
  13192.  
  13193.  
  13194. Programmierhandbuch                                 WG-Vision - 250 -
  13195.  
  13196.  
  13197.  
  13198.  
  13199.  
  13200.  
  13201.  
  13202.   case ROMFont of
  13203.    $22 : begin      {8x14}
  13204.            for i:=1 to 3 do move(p^,Font14[i],CharSize*256);
  13205.            for i:=0 to 255 do
  13206.             begin
  13207.               Font14[1,i,CharSize-1]:=$FF;
  13208.               for j:=0 to CharSize-1 do
  13209.                begin
  13210.                  Font14[2,i,j]:=Font14[2][i][j]
  13211.                                  or (Font14[2,i,j] shr 1);
  13212.                  Font14[3,i,j]:=Font14[3,i,j] and (Font14[3,i,j] shr 1);
  13213.                end;
  13214.             end;
  13215.            SetSpecialFont(Font14[Style]);
  13216.          end;
  13217.    $23 : begin      {8x8}
  13218.            for i:=1 to 3 do move(p^,Font8[i],CharSize*256);
  13219.            for i:=0 to 255 do
  13220.             begin
  13221.               Font8[1,i,CharSize-1]:=$FF;   {Unterstreichen}
  13222.               for j:=0 to CharSize-1 do
  13223.                begin
  13224.                  Font8[2,i,j]:=Font8[2,i,j] or (Font8[2,i,j] shr 1);
  13225.                  Font8[3,i,j]:=Font8[3,i,j] and (Font8[3,i,j] shr 1);
  13226.                end;
  13227.             end;
  13228.            SetSpecialFont(Font8[Style]);
  13229.          end;
  13230.    $24 : begin      {8x16}
  13231.            for i:=1 to 3 do move(p^,Font16[i],CharSize*256);
  13232.            for i:=0 to 255 do
  13233.             begin
  13234.               Font16[1,i,CharSize-1]:=$FF;   {Unterstreichen}
  13235.               for j:=0 to CharSize-1 do
  13236.                begin
  13237.                  Font16[2,i,j]:=Font16[2,i,j] or (Font16[2,i,j] shr 1);
  13238.                  Font16[3,i,j]:=Font16[3,i,j] and (Font16[3,i,j] shr 1);
  13239.                end;
  13240.             end;
  13241.  
  13242.  
  13243.  
  13244. Programmierhandbuch                                 WG-Vision - 251 -
  13245.  
  13246.  
  13247.  
  13248.  
  13249.  
  13250.  
  13251.  
  13252.            SetSpecialFont(Font16[Style]);
  13253.          end;
  13254.   end; {case}
  13255. end;
  13256.  
  13257. END.
  13258.  
  13259. Beispiel-Listing 3
  13260.  
  13261. Dieses Programm demonstriert, wie Sie WFont im Grafikmodus
  13262. einsetzen können
  13263.  
  13264. Testprogramm zur Demonstration der Unit WFont im Grafikmodus
  13265.  
  13266. program test;
  13267.  
  13268. uses WFont,
  13269.      crt,
  13270.      graph;
  13271.  
  13272. var FNT          : PPixelFont;
  13273.     i,j,
  13274.     Driver,Modus : integer;
  13275.     ZSName,zz    : string;
  13276.     kb           : char;
  13277. begin
  13278.   Driver:=VGA; Modus:=VGAHi;
  13279.   DirectVideo:=false;                            {Textausgabe über BIOS}
  13280.   WindMax:=$FFFF;                             {crt-Scrolling verhindern}
  13281.   InitGraph(Driver,Modus,'\bp\bgi');                {Grafik einschalten}
  13282.   TextColor(White);
  13283.   for j:=1 to 4 do
  13284.    begin
  13285.      gotoXY(1,4);
  13286.      str(j,zz);
  13287.      ZSName:='#VGAFONT/'+zz;
  13288.      new(FNT, SetFont(ZSName));
  13289.  
  13290.  
  13291.  
  13292.  
  13293.  
  13294. Programmierhandbuch                                 WG-Vision - 252 -
  13295.  
  13296.  
  13297.  
  13298.  
  13299.  
  13300.  
  13301.  
  13302.      for i:=31 to 255 do
  13303.       begin
  13304.         if (i-30) mod 80=0 then writeln;
  13305.         write(char(i));
  13306.       end;
  13307.      writeln; writeln;
  13308.      writeln('FontMania-Fonts im VGA-Grafikmodus');
  13309.      writeln(FNT^.GetFontName);
  13310.      writeln;
  13311.      kb:=ReadKey;
  13312.      ClearViewPort;
  13313.    end;
  13314.   new(FNT, SetFont('ROM8x8'));              {ROM-Fonts modifizieren und}
  13315.   gotoXY(1,5);                                              {darstellen}
  13316.   writeln('8x8 VGA-ROM-Font, normal');
  13317.   FNT^.SetFontStyle(Small);
  13318.   writeln('8x8 VGA-ROM-Font, schmal');
  13319.   FNT^.SetFontStyle(Bold);
  13320.   writeln('8x8 VGA-ROM-Font, fett');
  13321.   FNT^.SetFontStyle(UnderLine);
  13322.   writeln('8x8 VGA-ROM-Font, unterstrichen');
  13323.   kb:=ReadKey;
  13324.   new(FNT, SetFont('ROM8x14'));
  13325.   gotoXY(1,8); TextColor(LightRed);
  13326.   writeln('8x14 VGA-ROM-Font, normal');
  13327.   FNT^.SetFontStyle(Small);
  13328.   writeln('8x14 VGA-ROM-Font, schmal');
  13329.   FNT^.SetFontStyle(Bold);
  13330.   writeln('8x14 VGA-ROM-Font, fett');
  13331.   FNT^.SetFontStyle(UnderLine);
  13332.   writeln('8x14 VGA-ROM-Font, unterstrichen');
  13333.   kb:=ReadKey;
  13334.   new(FNT, SetFont('ROM8x16'));
  13335.   gotoXY(1,12); TextColor(LightCyan);
  13336.   writeln('8x16 VGA-ROM-Font, normal');
  13337.   FNT^.SetFontStyle(Small);
  13338.   writeln('8x16 VGA-ROM-Font, schmal');
  13339.   FNT^.SetFontStyle(Bold);
  13340.   writeln('8x16 VGA-ROM-Font, fett');
  13341.  
  13342.  
  13343.  
  13344. Programmierhandbuch                                 WG-Vision - 253 -
  13345.  
  13346.  
  13347.  
  13348.  
  13349.  
  13350.  
  13351.  
  13352.   FNT^.SetFontStyle(UnderLine);
  13353.   writeln('8x16 VGA-ROM-Font, unterstrichen');
  13354.   FNT^.Done;
  13355.   kb:=ReadKey;
  13356.   CloseGraph;
  13357. end.
  13358.  
  13359. Beispiel-Listing 4
  13360.  
  13361. Userzeichensätze im Alphamodus
  13362. Testprogramm zur Demonstration der Unit WFont im Alphamodus
  13363.  
  13364. program AlphaTest;
  13365. uses WFont,
  13366.      crt;
  13367.  
  13368. var FNT          : PPixelFont;
  13369.     i,j          : integer;
  13370.     ZSName,zz    : string;
  13371.     kb           : char;
  13372. begin
  13373.   TextColor(White);
  13374.   for j:=1 to 4 do
  13375.    begin
  13376.      gotoXY(1,4); str(j,zz);
  13377.      ZSName:='#VGAFONT/'+zz;
  13378.      new(FNT, SetFont(ZSName));
  13379.      for i:=31 to 255 do
  13380.       begin
  13381.         if (i-30) mod 80=0 then writeln;
  13382.         write(char(i));
  13383.       end;
  13384.      writeln; writeln;
  13385.      writeln('FontMania-Fonts im VGA-Alphamodus');
  13386.      writeln(FNT^.GetFontName);
  13387.      writeln;
  13388.      kb:=ReadKey;
  13389.    end;
  13390. end.
  13391.  
  13392.  
  13393.  
  13394. Programmierhandbuch                                 WG-Vision - 254 -
  13395.  
  13396.  
  13397.  
  13398.  
  13399.  
  13400.  
  13401.  
  13402. Objekt TPixelFont
  13403.  
  13404. Felder
  13405.  
  13406. Font
  13407. Font:FontType;
  13408. User-Zeichensatz. FontType ist folgendermaßen deklariert:
  13409.  
  13410. type FontType=record
  13411.                 Name   : string[10];   {WG-Vision Fontressource}
  13412.                 Points : char;
  13413.                 Data   : array[1..4096] of char;
  13414.               end;
  13415.  
  13416. ROMFont
  13417. ROMFont:byte;
  13418. Funktions-Nummer des ROM-Zeichensatzes
  13419.  
  13420. CharSize
  13421. CharSize:byte;
  13422. Zeichenhöhe in Pixel.
  13423.  
  13424. Methoden
  13425.  
  13426. SetFont
  13427. constructor SetFont(f:string);
  13428. Laden eines Pixelzeichensatzes.
  13429.  
  13430. ROM-Zeichensätze :  ROM8x8
  13431.                     ROM8x14
  13432.                     ROM8x16
  13433.  
  13434. Ressource        : #Name/n    Name Dateiname der
  13435.                               Fontressource ohne Extension,
  13436.                               n Nr. des Zeichensatzes
  13437.  
  13438. Fontressourcen müssen die Extension FNT besitzen !
  13439.  
  13440.  
  13441.  
  13442.  
  13443.  
  13444. Programmierhandbuch                                 WG-Vision - 255 -
  13445.  
  13446.  
  13447.  
  13448.  
  13449.  
  13450.  
  13451.  
  13452. Done
  13453. destructor Done; virtual;
  13454. Lädt den 8x8 Standardzeichensatz
  13455.  
  13456. GetFontName
  13457. function GetFontName:string;
  13458. Ermittelt den Namen des gerade aktiven Pixelfonts und
  13459. übergibt ihn als String.
  13460.  
  13461. SetFontStyle
  13462. procedure SetFontStyle(Style:byte);
  13463. Aktiviert die Zusatzzeichensätze für unterstrichene, fette
  13464. und schmale Zeichen. Die Ableitung erfolgt aus den ROM-
  13465. Zeichensätzen. User-Zeichensätze werden nicht unterstützt.
  13466.  
  13467.  
  13468.  
  13469.  
  13470.  
  13471.  
  13472.  
  13473.  
  13474.  
  13475.  
  13476.  
  13477.  
  13478.  
  13479.  
  13480.  
  13481.  
  13482.  
  13483.  
  13484.  
  13485.  
  13486.  
  13487.  
  13488.  
  13489.  
  13490.  
  13491.  
  13492.  
  13493.  
  13494. Programmierhandbuch                                 WG-Vision - 256 -
  13495.  
  13496.  
  13497.  
  13498.  
  13499.  
  13500.  
  13501.  
  13502. 6.3.5. Verwendung der Vektorzeichensätze - TVectorFont
  13503.  
  13504. Das Objekt TVectorFont ist sehr einfach. Es besitzt aber die
  13505. angenehme Eigenschaft, daß alle Vektorfonts normiert sind.
  13506. Damit ist eine quasi stufenlose Skalierung der Font-Größe
  13507. einheitlich für alle verfügbaren Fonts möglich.
  13508.  
  13509. 6.3.5.1. Skalierung der BGI-Vektorzeichensätze
  13510.  
  13511. Vielen Programmierern ist es schon unangenehm aufgefallen,
  13512. daß trotz gleicher Parameterangabe in SetTextStyle die ein-
  13513. zelnen Vektorfonts unterschiedlich groß auf dem Grafikbild-
  13514. schirm dargestellt werden. Dieses Verhalten macht es
  13515. schwierig, Texte eine bestimmte Größe (z.B. 25 Pixel hoch)
  13516. zuzuweisen.
  13517. Oftmals hilft dabei nur Probieren. Das in der Unit WFONT.PAS
  13518. implementierte Objekt TVectorFont erlaubt es, alle Vektor-
  13519. zeichensätzen mit Hilfe der Methode SetCharSize einheitlich
  13520. zu skalieren. Ein Wert von z=1 und n=1 bewirkt, daß ein
  13521. Textstring unabhängig vom aktivierten Vektorzeichensatz mit
  13522. einer Höhe von 30 Pixeln ausgegeben wird. Die Variablen z
  13523. und n sind als Zähler und Nenner eines Bruchs aufzufassen.
  13524. Ist beispielsweise n=2, dann wird der Text nur halb so groß,
  13525. also 15 Pixel hoch, dargestellt.
  13526. Indem man den Skalierungsfaktor in einen gemeinen Bruch um-
  13527. wandelt, kann die Zeichensatzhöhe auf jede gewünschte Größe
  13528. gebracht werden.
  13529.  
  13530. Felder
  13531.  
  13532. Font
  13533. Font:word;
  13534. Nummer des aktiven Vektorfonts. Folgende Konstanten sind
  13535. möglich (definiert in der Unit WDecl):
  13536.  
  13537.  
  13538.  
  13539.  
  13540.  
  13541.  
  13542.  
  13543.  
  13544. Programmierhandbuch                                 WG-Vision - 257 -
  13545.  
  13546.  
  13547.  
  13548.  
  13549.  
  13550.  
  13551.  
  13552. DefaultFont   = 0      Pixel-Zeichensatz, entspricht ROM8x8
  13553. oder ROM8x16
  13554. TriplexFont   = 1
  13555. SmallFont     = 2
  13556. SansSerifFont = 3
  13557. GothicFont    = 4
  13558. ScriptFont    = 5
  13559. SimpleFont    = 6
  13560. TSCRFont      = 7
  13561. LCOMFont      = 8
  13562. EuroFont      = 9
  13563. BoldFont      =10
  13564.  
  13565. Direction
  13566. Direction:word;
  13567. Ausgaberichtung der Textzeile. Es sind die Werte HorizDir
  13568. und VertDir möglich.
  13569.  
  13570. CharSize
  13571. CharSize:TPoint;
  13572. Charsize enthält die Buchstabengröße, beschrieben durch n
  13573. und z (CharSize.x:=n; CharSize.y:=z;)
  13574.  
  13575. Methoden
  13576.  
  13577. SetVectorFont
  13578. constructor SetVectorFont(f:word);
  13579. Vektorzeichensatz aktivieren. Bitte verwenden Sie für f die
  13580. in der Unit WDecl vordefinierten Bezeichner.
  13581.  
  13582. Done
  13583. destructor Done; virtual;
  13584. Rücksetzen auf den Defaultfont. Ausrichtung horizontal.
  13585.  
  13586. SetCharSize
  13587. procedure SetCharSize(z,n:word);
  13588. Setzt die Größe eines Vektorfonts. Die Korrekturfaktoren
  13589. innerhalb dieser Methode wurden so gewählt, daß ein Aufruf
  13590. von n=1 und z=1 eine Texthöhe von 30 Pixeln ergibt.
  13591.  
  13592.  
  13593.  
  13594. Programmierhandbuch                                 WG-Vision - 258 -
  13595.  
  13596.  
  13597.  
  13598.  
  13599.  
  13600.  
  13601.  
  13602. SetDirection
  13603. procedure SetDirection(Dir:word);
  13604. Legt die Ausgaberichtung einer Zeichenkette fest (HorizDir
  13605. oder VertDir), die mit OutTextXY oder OutText ausgegeben
  13606. wird.
  13607.  
  13608.  
  13609.  
  13610.  
  13611.  
  13612.  
  13613.  
  13614.  
  13615.  
  13616.  
  13617.  
  13618.  
  13619.  
  13620.  
  13621.  
  13622.  
  13623.  
  13624.  
  13625.  
  13626.  
  13627.  
  13628.  
  13629.  
  13630.  
  13631.  
  13632.  
  13633.  
  13634.  
  13635.  
  13636.  
  13637.  
  13638.  
  13639.  
  13640.  
  13641.  
  13642.  
  13643.  
  13644. Programmierhandbuch                                 WG-Vision - 259 -
  13645.  
  13646.  
  13647.  
  13648.  
  13649.  
  13650.  
  13651.  
  13652. 6.4. Unit WEMS  -  Die Verwaltung des Expanded Memory
  13653.  
  13654. Die Unit WEMS ist nicht objektorientiert programmiert. Sie
  13655. stellt lediglich Verwaltungs- und Zugriffsroutinen für den
  13656. Expansionsspeicher zur Verfügung. Diese Routinen benutzt WG-
  13657. Vision beispielsweise, um den Untergrund von Fensterobjekten
  13658. in den EMS zu laden bzw. von dort wieder zu holen. Sie kön-
  13659. nen diese Routinen in ihr eigenes Programm einbauen, um bei-
  13660. spielsweise Daten im EMS unterzubringen. Wenn Sie mit
  13661. Borland Pascal arbeiten, müssen Sie während der Entwick-
  13662. lungsphase darauf achten, daß der DPMI-Server nicht den ge-
  13663. samten verfügbaren Erweiterungs- und Expansionsspeicher
  13664. belegt. Mit der Umgebungsvariablen DPMIMEM können Sie BP7
  13665. anweisen, eine bestimmte Menge von Speicher freizuhalten.
  13666. Sie müssen dazu lediglich die Zeilen
  13667.  
  13668. SET DPMIMEM=MAXMEM nnnn
  13669.  
  13670. in die AUTOEXEC.BAT einfügen. nnnn bezeichnet die maximale
  13671. Größe des Speichers in KByte, die der DPMI-Server benutzen
  13672. darf.
  13673. Wenn Sie innerhalb eines WG-Vision-Programms mit Expanded
  13674. Memory hantieren, sollten Sie in der Entwicklungsphase immer
  13675. den EMS-Wächter aktivieren. Er zeigt permanent den noch ver-
  13676. fügbaren Speicher und die Anzahl der noch verfügbaren Spei-
  13677. cherseiten an. Auf diese Weise können Sie leicht erkennen,
  13678. ob Sie den nicht mehr benötigten Expansionsspeicher auch
  13679. ordentlich deallokiert haben. Ansonsten wird der Griff zum
  13680. Reset-Schalter zu einem nicht sehr angenehmen Sport.
  13681. In der Regel ist Expansionsspeicher nur in Maschinen mit ei-
  13682. nem 386/486-Prozessor verfügbar. Wenn Sie solch eine Maschi-
  13683. ne besitzen (und das sollten Sie, wenn Sie mit WG-Vision
  13684. programmieren), dann installieren Sie vor der Verwendung der
  13685. WEMS-Unit einen entsprechenden Gerätetreiber. Eine Anleitung
  13686. dazu finden Sie in den Handbüchern Ihres Betriebssystems.
  13687. WG-Vision testet in der Initialisierungsphase automatisch,
  13688. ob ein EMS-Treiber installiert ist und setzt entsprechend
  13689. die logische Variable EMS_Installed.
  13690.  
  13691.  
  13692.  
  13693.  
  13694. Programmierhandbuch                                 WG-Vision - 260 -
  13695.  
  13696.  
  13697.  
  13698.  
  13699.  
  13700.  
  13701.  
  13702. WEMS unterstützt nur die Funktionen, die in der EMS-Spezifi-
  13703. kation nach LIM 3.2 enthalten sind.
  13704.  
  13705. 6.4.1. Ein paar Worte zur Funktionsweise
  13706.  
  13707. In diesem Handbuch kann nicht detailliert auf die Funktions-
  13708. weise des Expansionsspeichers eingegangen werden. Wenn Sie
  13709. mehr darüber wissen möchten, dann empfehle ich Ihnen das
  13710. Buch "Speicherverwaltung unter DOS" von Mario Bez, erschie-
  13711. nen im te-wi Verlag. Darin finden Sie sehr detailliert alles
  13712. Wissenswerte über Extended und Expanded Memory sowie eine
  13713. ausführliche Referez aller EMS-Funktionen.
  13714. Der gesamte als Expanded Memory zu nutzende Speicher wird in
  13715. Stücke von 16 KByte Größe aufgeteilt. Diese Stücke werden
  13716. als logische Seiten (logical pages) bezeichnet. Soll auf die
  13717. darin enthaltenen Daten zugegriffen werden, dann werden sie
  13718. vom EMS-Treiber in ein 64 KByte großes Fenster, welches ir-
  13719. gendwo zwischen 640 KByte und 1024 KByte innerhalb des
  13720. Adressbereiches von DOS im Hauptspeicher liegt, eingeblen-
  13721. det. Diese "Page-Frame" besteht selbst aus 4 physikalischen
  13722. Seiten (physical pages), auf die die CPU im Unterschied zu
  13723. den logischen Seiten sofort zugreifen kann.
  13724. Es wird also durch das Umschalten entschieden, welche Spei-
  13725. cherbereiche (und ihre Inhalte) für die CPU zugänglich sind.
  13726. Das Umschalten erfolgt durch ein "bank-switching", d.h. es
  13727. wird zwischen den einzelnen Speicherbänken hin- und herge-
  13728. schaltet.
  13729.  
  13730. Globale Variablen
  13731.  
  13732. EMS_Installed
  13733. EMS_Installed:boolean;
  13734. Wird auf true gesetzt, wenn bei der Initialisierung der Unit
  13735. ein aktiver EMS-Treiber entdeckt wird.
  13736.  
  13737. EMM_Version
  13738. EMM_Version:string[3];
  13739. Enthält nach der Initialisierung die EMS-Versionsnummer.
  13740.  
  13741.  
  13742.  
  13743.  
  13744. Programmierhandbuch                                 WG-Vision - 261 -
  13745.  
  13746.  
  13747.  
  13748.  
  13749.  
  13750.  
  13751.  
  13752. Error
  13753. Error:word;
  13754. Enthält die Nummer des zuletzt aufgetretenen Fehlers.
  13755.  
  13756. PageFrame
  13757. PageFrame:word;
  13758. Segmentadresse des Pageframe.
  13759.  
  13760. Pages
  13761. Pages:array[0..3] of word;
  13762. Enthält die Segmentadressen der physikalischen Seiten.
  13763.  
  13764. Prozeduren und Funktionen
  13765.  
  13766. HexString
  13767. function HexString(Number:word):string;
  13768. Wandelt die Zahl Number in einen Hexstring um.
  13769.  
  13770. GetUnallocatedPages
  13771. function GetUnallocatedPages:word;
  13772. Bestimmt die Gesamtzahl möglicher EMS-Seiten.
  13773.  
  13774. GetFreePages
  13775. function GetFreePages:word;
  13776. Übergibt die Anzahl der noch freien EMS-Seiten.
  13777.  
  13778. GetPageFrameAddress
  13779. function GetPageFrameAddress:word;
  13780. Diese Funktion liefert die Segmentadresse des Anfangs vom
  13781. 64-KByte-Fenster des EMS-Bereichs (PageFrame).
  13782.  
  13783. MapPages
  13784. procedure MapPages(NumberPages,P1,P2,P3,P4:word;
  13785.                    var Handle:word);
  13786. Reserviert die in NumberPages angegebene Anzahl von EMS-Sei-
  13787. ten und weist ihnen ein eindeutiges Handle zu. In P1 bis P4
  13788. sind die Nummern der logischen Seiten einzutragen, welche
  13789. auf die physikalischen Seiten abgebildet werden sollen. Lo-
  13790. gische Seiten werden von Null an durchnumeriert. Die logi-
  13791.  
  13792.  
  13793.  
  13794. Programmierhandbuch                                 WG-Vision - 262 -
  13795.  
  13796.  
  13797.  
  13798.  
  13799.  
  13800.  
  13801.  
  13802. sche Seite muß sich im Bereich von Null bis (NumberPages-1)
  13803. befinden. Mit einem Aufruf von MapPages können maximal 64
  13804. KByte allokiert werden.
  13805.  
  13806. ReMapPages
  13807. procedure ReMapPages(P1,P2,P3,P4:word;var Handle:word);
  13808. Diese Prozedur bildet die logischen Seiten P1 .. P4, die zum
  13809. Handle gehören, auf das Pageframe ab.
  13810.  
  13811. AllocatePages
  13812. function AllocatePages(NumberPages:word):word;
  13813. Allokiert die Anzahl der in NumberPages angegebenen Seiten
  13814. und übergibt ein eindeutiges Handle.
  13815.  
  13816. DeAllocatePages
  13817. procedure DeAllocatePages(Handle:word);
  13818. Diese Prozedur gibt die aktuell an einen Handle gebundenen
  13819. Seiten wieder frei.
  13820.  
  13821. MapHandlePages
  13822. procedure MapHandlePages(Handle:word;PhysicalPage,
  13823.                                 LogicalPage:byte);
  13824. Bildet die zum Handle gehörende logische Seite LogicalPage
  13825. auf die physikalische Seite PhysicalPage ab.
  13826.  
  13827. GetHandleCount
  13828. function GetHandleCount:word;
  13829. Diese Funktion liefert die Anzahl der im System gerade akti-
  13830. ven EMM-Handles zurück.
  13831.  
  13832. GetHandlePages
  13833. function GetHandlePages(var Handle:word):word;
  13834. Diese Funktion liefert die Anzahl der Seiten, die für den
  13835. angegebenen EMM-Handle reserviert wurden.
  13836.  
  13837.  
  13838.  
  13839.  
  13840.  
  13841.  
  13842.  
  13843.  
  13844. Programmierhandbuch                                 WG-Vision - 263 -
  13845.  
  13846.  
  13847.  
  13848.  
  13849.  
  13850.  
  13851.  
  13852. Komplexbeispiel    Text im EMS speichern
  13853.  
  13854. Die Verwendung von Expansionsspeicher in eigenen Programmen
  13855. ist nicht sonderlich schwierig, aber etwas gewöhnungsbedürf-
  13856. tig. Im folgenden Beispiel möchte ich Ihnen zeigen, wie man
  13857. unser Listprogramm veranlassen kann, die Quelltexte anstatt
  13858. in den Heap in den Expansionsspeicher auszulagern. Zum Auf-
  13859. listen verwenden wir ein Scrollfenster, dessen Scroller al-
  13860. lein für die Verwaltung der Daten, die im Fenster
  13861. aufgelistet werden sollen, verantwortlich ist. In allen un-
  13862. seren Beispielen haben wir die Daten in eine doppelt verket-
  13863. teten Liste eingelesen, die TLine-Objekte aufnehmen kann und
  13864. bereits vom TScroller zur Verfügung gestellt wird (Liste).
  13865. Die Kapazität dieser Liste hängt entscheidend von der Größe
  13866. des zur Laufzeit noch vorhandenen Heaps ab. Das Listen gro-
  13867. ßer Quelltexte ist ohne das Heraufbeschwören eines Heap-Feh-
  13868. lers kaum möglich.
  13869. Jetzt soll das TScroller-Objekt so umgestaltet werden, daß
  13870. die Daten im Expanded Memory gespeichert und auch von dort
  13871. wieder gelesen werden können.
  13872. Zur Vereinfachung verwenden wir jetzt ein einfaches Array,
  13873. welches 3072 Programmzeilen mit einer Maximallänge von
  13874. jeweils 128 Byte aufnehmen kann. 3072 Strings deshalb, weil
  13875. zu ihrer Speicherung genau 3072*128/16384=24 logische Seiten
  13876. benötigt werden. Eine logische Seite faßt genau 16 KByte.
  13877. Da eine Zeile Turbo-Pascal-Quelltext 128 Bytes enthalten
  13878. kann, definieren wir folgenden neuen Datentyp und einen Zei-
  13879. ger darauf:
  13880.  
  13881. type str128=string[128];       {String mit einer Länge von 128 Zeichen}
  13882.      pStr=^str128;             {String-Pointer}
  13883.  
  13884. Die Pointerliste wird Bestandteil des neuen TScroller-
  13885. Objekts genauso wie das Handle, welches wir für den Zugriff
  13886. auf den Expanded Memory benötigen:
  13887.  
  13888.  
  13889.  
  13890.  
  13891.  
  13892.  
  13893.  
  13894. Programmierhandbuch                                 WG-Vision - 264 -
  13895.  
  13896.  
  13897.  
  13898.  
  13899.  
  13900.  
  13901.  
  13902. type TNewScroller=object(TScroller)
  13903.        EMSHandle:word;
  13904.        Eintrag:array[1..3072] of pStr;
  13905.        destructor Done; virtual;
  13906.        procedure CreateData;
  13907.        procedure ScrollDraw; virtual;
  13908.      end;
  13909.  
  13910. Den Destruktor müssen wir auf jeden Fall überschreiben,
  13911. damit wir am Ende beim Schließen des Scrollfensters auch
  13912. alle dem Handle zugeordneten Seiten wieder freigeben. Nicht
  13913. wieder freigegebene Seiten sind quasi verloren ! Sie können
  13914. nicht wieder neu belegt werden. Damit dieser Fehler niemals
  13915. auftreten kann, sollten Sie die Anzeige des Heapwächters im
  13916. Auge behalten.
  13917.  
  13918. destructor TNewScroller.Done;
  13919. begin
  13920.   DeAllocatePages(EMSHandle);
  13921.   TScroller.Done;
  13922. end;
  13923.  
  13924. In der Methode CreateData werden die Zeilen der Textdatei in
  13925. das Array und damit in den EMS geschrieben:
  13926.  
  13927. procedure TNewScroller.CreateData;
  13928. var dat:text;
  13929.     i,k,S,AnzPages:word;
  13930.     zz:string[120];
  13931.     z:string[4];
  13932. begin
  13933.   SetFont(Wndw19);
  13934.   k:=1; S:=0;
  13935.   assign(dat,Event.InfoString);
  13936.   reset(dat);
  13937.  
  13938.  
  13939.  
  13940.  
  13941.  
  13942.  
  13943.  
  13944. Programmierhandbuch                                 WG-Vision - 265 -
  13945.  
  13946.  
  13947.  
  13948.  
  13949.  
  13950.  
  13951.  
  13952. Als Erstes schauen wir nach, ob überhaupt 24 logische Seiten verfügbar
  13953. sind. Wenn nicht, dann sollte entweder der Heap genutzt oder eine
  13954. Fehlerbehandlung realisiert werden.
  13955.  
  13956.   AnzPages:=GetFreePages;
  13957.   if AnzPages<=24 then
  13958.    begin
  13959.  
  13960. An dieser Stelle sollte die Fehlerbehandlung stehen.
  13961.  
  13962.    end
  13963.    else
  13964.    begin
  13965.  
  13966. Wir allokieren 24 logische Seiten unter dem Handle "EMSHandle"
  13967.  
  13968.      EMSHandle:=AllocatePages(24);
  13969.  
  13970. In diesem Beispiel verwenden wir nur die physikalische Seite Null zum
  13971. Übertragen der Daten in den Expansionsspeicher. Die ersten 128
  13972. Textzeilen werden in die logische Seite Null geschrieben.
  13973.  
  13974.      MapHandlePages(EMSHandle,0,0);
  13975.  
  13976. Index-Schleife für das Daten-Array
  13977.  
  13978.      for i:=1 to 3072 do
  13979.       begin
  13980.  
  13981. Immer wenn 128 Strings geschrieben wurden, muß eine neue logische Seite
  13982. in das Pageframe eingeblendet werden.
  13983.  
  13984.         if i mod 128=0 then
  13985.          begin
  13986.            k:=1;
  13987.  
  13988.  
  13989.  
  13990.  
  13991.  
  13992.  
  13993.  
  13994. Programmierhandbuch                                 WG-Vision - 266 -
  13995.  
  13996.  
  13997.  
  13998.  
  13999.  
  14000.  
  14001.  
  14002. Hier ordnen wir der physikalischen Seite Null die neue logische Seite
  14003. mit der Nummer (i div 128) zu,
  14004.  
  14005.            MapHandlePages(EMSHandle,0,i div 128);
  14006.          end
  14007.  
  14008. sonst erhöhen wir nur den "Zeilenzähler" innerhalb der Seite.
  14009.  
  14010.          else inc(k);
  14011.  
  14012. Hier wird ein Pointer absolut im Pageframe, physikalische Seite Null,
  14013. positioniert
  14014.  
  14015.          Eintrag[i]:=ptr(PageFrame,(k-1)*128);
  14016.  
  14017. und dann mit "Daten" beladen.
  14018.  
  14019.          if (i<=3071) and (not EOF(dat)) then
  14020.           begin
  14021.             readln(dat,zz);                  {Zeilennummern dranbasteln}
  14022.             str(i:4,z);
  14023.             Eintrag[i]^:=z+'  '+zz
  14024.           end
  14025.          else
  14026.  
  14027. Ist das Ende der Textdatei erreicht oder das Array voll, dann
  14028. verabschieden wir uns mit einer kleinen Mitteilung an uns selbst
  14029. (SetLimit...) aus dieser Methode.
  14030.  
  14031.           begin
  14032.             SetLimit(65,i-1,8,16);
  14033.             close(dat);
  14034.             Exit;                                      {Adios Amigos !}
  14035.           end;
  14036.       end;
  14037.    end;
  14038. end;
  14039.  
  14040.  
  14041.  
  14042.  
  14043.  
  14044. Programmierhandbuch                                 WG-Vision - 267 -
  14045.  
  14046.  
  14047.  
  14048.  
  14049.  
  14050.  
  14051.  
  14052. Der Scroller muß jetzt in Abhängigkeit der Lage der Rollbal-
  14053. ken die im EMS abgelegten Strings wieder auf den Bildschirm
  14054. zaubern. Zu diesem Zweck muß die gerade benötigte logische
  14055. Seite wieder in das Pageframe eingeblendet werden. Wie das
  14056. konkret geschieht, zeigt die Methode ScrollDraw:
  14057.  
  14058. procedure TNewScroller.ScrollDraw;
  14059. var i:integer;
  14060.     Max:word;
  14061.     LfdPtr:PGroup;
  14062.  
  14063. function clip(p,n:byte;z:string):string;
  14064. begin
  14065.   clip:=copy(z,p,n);
  14066. end;
  14067.  
  14068. {------}
  14069.  
  14070. begin
  14071.   SetFontColor(White,Red);
  14072.  
  14073. Wieviele Seiten hat EMSHandle allokiert ?
  14074.  
  14075.   Max:=GetHandlePages(EMSHandle);
  14076.   Mouse.HideMouse;
  14077.   with Border do
  14078.    begin
  14079.      SetFillStyle(SolidFill,GetPalColor(1));
  14080.      SetColor(GetPalColor(2));
  14081.  
  14082. Das einzige Problem an dieser Stelle ist auszurechnen, in welcher
  14083. logischer Seite sich der Eintrag mit dem Index i befindet. Wenn diese
  14084. logische Seite ins Pageframe eingeblendet wird (konkret wieder in die
  14085. physikalische Seite 0), sind die darin enthaltenen Daten sofort
  14086. zugänglich.
  14087.  
  14088.      for i:=Delta.y to WDelta.y do
  14089.       begin
  14090.  
  14091.  
  14092.  
  14093.  
  14094. Programmierhandbuch                                 WG-Vision - 268 -
  14095.  
  14096.  
  14097.  
  14098.  
  14099.  
  14100.  
  14101.  
  14102. Einblenden der zum Index i gehörenden logischen Seite (i div 128)
  14103.  
  14104.         MapHandlePages(EMSHandle,0,i div 128);
  14105.         Bar(A.x,A.y+(i-Delta.y)*Py+10,B.x,A.y+(i-Delta.y)*Py+10+Py);
  14106.  
  14107. und auf den Bildschirm malen.
  14108.  
  14109.         WriteText(A.x+20,A.y+(i-Delta.y)*Py+10,clip(Delta.x,
  14110.                   Spalten*8 div 8-5,Eintrag[i]^));
  14111.       end;
  14112.      if VertiScrollBar<>nil then
  14113.       for i:=(WDelta.y-Delta.y)+1 to Zeilen do
  14114.        Bar(A.x,A.y+i*Py+10,B.x,A.y+i*Py+10+Py);
  14115.    end;
  14116.   Mouse.ShowMouse;
  14117. end;
  14118.  
  14119. Wie Sie sehen, ist bei der Arbeit mit Expanded Memory etwas
  14120. Überlegung und ein klein wenig Rechnen nötig. Wenn das Prin-
  14121. zip aber erst einmal verstanden ist, dann kann man sich auch
  14122. mit der Ablage komplizierterer Datenstrukturen (z.B. Records
  14123. oder Listen) befassen.
  14124. Im folgenden Beispiel gilt es einen rechteckigen Ausschnitt
  14125. des Grafikbildschirms in den EMS zu schaufeln. In WG-Vision
  14126. ist dafür das Objekt TEMS zuständig. Sie finden es in der
  14127. Unit WViews.
  14128. Die Implementation sieht folgendermaßen aus:
  14129.  
  14130. type TEMS=object(TMemory)
  14131.        Version    : byte;                                  {EMS-Version}
  14132.        FreeMemory : LongInt;                       {freier EMS-Speicher}
  14133.        ...
  14134.  
  14135.        Handle     : word;                {EMS-Handle für den Ausschnitt}
  14136.        Part       : word;          {Speichert Höhe eines 16 KByte-Teils}
  14137.                                                        {des Ausschnitts}
  14138.        constructor Init(Bounds:TRect);
  14139.        destructor Done; virtual;
  14140.  
  14141.  
  14142.  
  14143.  
  14144. Programmierhandbuch                                 WG-Vision - 269 -
  14145.  
  14146.  
  14147.  
  14148.  
  14149.  
  14150.  
  14151.  
  14152.        procedure Save; virtual;
  14153.        procedure Restore(P:TPoint); virtual;
  14154.        ...
  14155.  
  14156.      end;
  14157. ...
  14158.  
  14159. constructor TEMS.Init(Bounds:TRect);
  14160. begin
  14161.   SetBounds(Bounds);      {Größe des zu speichernden Bildschirmbereichs}
  14162.   FreeMemory:=GetFreePages*LONGINT(16384);    {verfügbarer EMS-Speicher}
  14163.                                                                {in Byte}
  14164.   ...
  14165.  
  14166. end;
  14167.  
  14168. destructor TEMS.Done;
  14169. begin
  14170.   DeAllocatePages(Handle);   {Alle zum Handle gehörenden Speicherseiten}
  14171.                                                              {freigeben}
  14172. end;
  14173.  
  14174. procedure TEMS.Save;
  14175. var Seiten:word;
  14176.     i:integer;
  14177.     S,ss:single;
  14178.     Buffer:pointer;                     {Pointer auf den Zwischenpuffer}
  14179.     EMSBuffer:pointer;           {Pointer auf die physikalische Seite 0}
  14180.                                                           {im FramePage}
  14181. begin
  14182.   EMSBuffer:=Ptr(Pages[0],0);
  14183.  
  14184. Anzahl der Bytes, die zur Speicherung des Ausschnitts notwendig sind.
  14185. Mit ImageSize können maximal 64 KByte erfaßt werden. Ist der Bereich
  14186. größer, dann wird für BSize Null übergeben.
  14187.  
  14188.   BSize:=ImageSize(0,0,Size.X,Size.Y);
  14189.  
  14190.  
  14191.  
  14192.  
  14193.  
  14194. Programmierhandbuch                                 WG-Vision - 270 -
  14195.  
  14196.  
  14197.  
  14198.  
  14199.  
  14200.  
  14201.  
  14202. Speicherbedarf des Ausschnitts größer 64 KByte. Deshalb Handarbeit.
  14203.  
  14204.   if BSize=0 then
  14205.  
  14206. Da der Speicher bei Super-VGA's in den 256-Farb-Modi anders ausschaut
  14207. als bei der normalen VGA-Auflösung 640x480x16 muß BSize natürlich auch
  14208. anders berechnet werden, nähmlich viel einfacher ...
  14209.  
  14210.    if SVGA then BSize:=LongInt(Size.X)*LongInt(Size.Y)+6
  14211.     else BSize:=(LongInt(Size.X)*LongInt(Size.Y)+6) div 2;
  14212.        {normale VGA}
  14213.  
  14214. Wieviele Speicherseiten benötigen wir, um den Ausschnitt zu speichern ?
  14215. (man beachte den kleinen "Trick")
  14216.  
  14217.   S:=BSize/16384;                               {zu allokierende Seiten}
  14218.   Seiten:=BSize div 16384;
  14219.   while Seiten<=S do inc(Seiten,2);
  14220.   ss:=Size.Y/Seiten;
  14221.  
  14222. Unter Umständen müssen wir den Ausschnitt in horizontale Streifen der
  14223. Höhe Part mit einem Inhalt <= 16 KByte aufteilen.
  14224.  
  14225.   Part:=Size.Y DIV Seiten;
  14226.   while Part<=ss do inc(Part);
  14227.  
  14228. Wieviele Bytes faßt solch ein Streifen ?
  14229.  
  14230.   BSize:=ImageSize(0,0,Size.X,Part);
  14231.  
  14232. Pufferspeicher im Heap zum Zwischenspeichern allokieren.
  14233.  
  14234.   GetMem(Buffer,BSize);
  14235.  
  14236. Speicherseiten im EMS allokieren
  14237.  
  14238.   Handle:=AllocatePages(Seiten);
  14239.  
  14240.  
  14241.  
  14242.  
  14243.  
  14244. Programmierhandbuch                                 WG-Vision - 271 -
  14245.  
  14246.  
  14247.  
  14248.  
  14249.  
  14250.  
  14251.  
  14252. "Streifen" in den EMS schreiben.
  14253.  
  14254.   for I:=0 to Seiten-1 DO
  14255.    begin
  14256.      MapHandlePages(Handle,0,I);              {immer in Page 0 abbilden}
  14257.      GetImage(Origin.X,Origin.Y+I*Part,Origin.X+Size.X,Origin.Y+(I+1)
  14258.                                                       *Part, Buffer^);
  14259.      Move(Buffer^,EMSBuffer^,BSize);     {in das Pageframe, Seite Null,}
  14260.                                                               {schieben}
  14261.    end;
  14262.   FreeMem(Buffer,BSize);       {Pufferspeicher im Heap wieder freigeben}
  14263. end;
  14264.  
  14265. Das Lesen aus dem EMS ist besonders einfach, da wir uns die
  14266. Streifenbreite gemerkt haben. Mit PutImage wird der Bildschirmausschnitt
  14267. rekonstruiert.
  14268.  
  14269. procedure TEMS.Restore(P:TPoint);
  14270. var Buffer:Pointer;
  14271.     EMSBuffer:Pointer;
  14272.     Max,I:word;
  14273. begin
  14274.   EMSBuffer:=Ptr(Pages[0],0);
  14275.   Max:=GetHandlePages(Handle);       {Anzahl vom Handle belegter Seiten}
  14276.   GetMem(Buffer,BSize);
  14277.   for I:=0 to Max-1 do
  14278.    begin
  14279.      MapHandlePages(Handle,0,I);
  14280.      Move(EMSBuffer^,Buffer^,BSize);
  14281.      PutImage(P.X,P.Y+(I*Part),Buffer^,NormalPut);        {Restaurieren}
  14282.    end;
  14283.   FreeMem(Buffer,BSize);
  14284.   Done;    {Auf keinem Fall vergessen, sonst ist beizeiten der EMS alle}
  14285. end;
  14286.  
  14287.  
  14288.  
  14289.  
  14290.  
  14291.  
  14292.  
  14293.  
  14294. Programmierhandbuch                                 WG-Vision - 272 -
  14295.  
  14296.  
  14297.  
  14298.  
  14299.  
  14300.  
  14301.  
  14302. 6.5. Schwelgen in Farben - Die Unit WPalette.pas
  14303.  
  14304. Die Ausführungen in diesem Abschnitt beziehen sich aus-
  14305. schließlich auf die VESA Super-VGA-Modi mit 256 Farben. Alle
  14306. Routinen befinden sich in der Unit WPalette.pas.
  14307.  
  14308. WG-Vision arbeitet in den VESA-Modi mit 256 Farben, die aus
  14309. einer Palette von insgesamt 262144 möglichen Farben ausge-
  14310. wählt werden können. Zur Beschreibung einer Farbe wird das
  14311. RGB-Modell verwendet. Im RGB-Modell wird eine Farbe durch
  14312. seine Rot (R) -, Grün (G) - und Blau (B) - Bestandteile be-
  14313. schrieben. Jeder Farbbestanteil gibt gewissermaßen seine
  14314. "Helligkeit" an, mit der er der Farbe beigemischt ist. Der
  14315. Helligkeitswert kann nur innerhalb des Bereichs 0 bis 63 va-
  14316. riiert werden.
  14317. Um eine Farbpalette aus 256 Farben zu beschreiben, verwendet
  14318. die Unit WPalette folgende Datenstruktur:
  14319.  
  14320. type tRGB=record
  14321.             R,G,B:byte;
  14322.           end;
  14323.  
  14324.       tPalType=array[0..255] of tRGB;
  14325.  
  14326. Zur Manipulation einzelner Farben bzw. der gesamten Farbpa-
  14327. lette (bei vielen Methoden mit Ausschluß der ersten 16 Ein-
  14328. tragungen, da sie für das Desktop verwendet werden) dient
  14329. das Objekt TPalette:
  14330.  
  14331. Felder
  14332.  
  14333. F
  14334. F:file;
  14335. Palettendatei. In einer Palettendatei kann jeweils eine
  14336. Farbpalette gespeichert werden.
  14337.  
  14338. LUT
  14339. LUT:tPalType;
  14340. Look Up Table. Enthält die gerade aktive Farbpalette.
  14341.  
  14342.  
  14343.  
  14344. Programmierhandbuch                                 WG-Vision - 273 -
  14345.  
  14346.  
  14347.  
  14348.  
  14349.  
  14350.  
  14351.  
  14352. CLUT
  14353. CLUT:array[1..10] of tPalType;
  14354. Dieses Array von LUT's kann maximal 10 verschiedene Farbpa-
  14355. letten aufnehmen, die damit zur Laufzeit schnell zugänglich
  14356. sind.
  14357.  
  14358. Methoden
  14359.  
  14360. SetPaletteColor
  14361. procedure SetPaletteColor(Nr,Rot,Gruen,Blau:byte);
  14362. Der Paletteneintrag mit der Nummer "Nr" wird mit den Farbbe-
  14363. standteilen Rot, Gruen und Blau geladen (Wertebereich je-
  14364. weils 0..63). Die Werte werden aus Geschwindigkeitsgründen
  14365. sofort in die Ports der VGA-Karte geschrieben. Es kann in
  14366. ungünstigen Fällen dabei zu "Schnee" auf dem Bildschirm kom-
  14367. men, da die Retrace-Phase des Elektronenstrahls nicht abge-
  14368. wartet wird (führt u.U. zu einem starken Geschwindigkeits-
  14369. verlust beim Setzen vieler Farben).
  14370.  
  14371. GetPaletteColor
  14372. procedure GetPaletteColor(var Nr,Rot,Gruen,Blau:byte);
  14373. Der Rot, Grün und Blau-Anteil des Paletteneintrags Nr wird
  14374. ausgelesen und in den var -Variablen übergeben.
  14375.  
  14376. GetPalette
  14377. procedure GetPalette;
  14378. Schreibt die gerade aktive Farbpalette in die Tabelle LUT.
  14379.  
  14380. SetPalette
  14381. procedure SetPalette;
  14382. Übergibt die Werte in der Tabelle LUT an die VGA-Karte
  14383. (schnelles Setzen einer Farbpalette).
  14384.  
  14385. SetNewPalette
  14386. procedure SetNewPalette(NLUT:tPalType);
  14387. Setzen einer neuen, in NLUT gespeicherten Farbpalette.
  14388.  
  14389.  
  14390.  
  14391.  
  14392.  
  14393.  
  14394. Programmierhandbuch                                 WG-Vision - 274 -
  14395.  
  14396.  
  14397.  
  14398.  
  14399.  
  14400.  
  14401.  
  14402. LoadPalette
  14403. procedure LoadPalette(FName:PathStr);
  14404. Eine in der Datei FName gespeicherte Farbpalette wird gela-
  14405. den und aktiviert.
  14406.  
  14407. SavePalette
  14408. procedure SavePalette(FName:PathStr);
  14409. Die in der Tabelle LUT enthaltenen Farbwerte werden in die
  14410. Datei FName geschrieben.
  14411.  
  14412. RotatePalette
  14413. procedure RotatePalette(Typ,Direction:byte);
  14414. Rotiert die gerade aktive Palette um jeweils einen Eintrag
  14415. nach links (Direction=0) oder rechts (Direction=1). Die er-
  14416. sten 16 Eintragungen bleiben unverändert. Der Typ legt fest,
  14417. ob die Palette rotiert werden soll (im Sinne der letzte Ein-
  14418. trag wird zum Ersten) oder ob der letzte bzw erste Eintrag
  14419. ins "Nichts" verschoben wird.
  14420.  
  14421. RotatePart
  14422. procedure RotatePart(Direction,Von,Bis:byte);
  14423. Der durch die Farbnummern "Von" und "Bis" begrenzte Palet-
  14424. tenbereich wird in die Richtung Direction rotiert.
  14425.  
  14426. SetVerlauf
  14427. procedure SetVerlauf(Nr1,Rot1,Gruen1,Blau1,
  14428.           Nr2,Rot2,Gruen2,Blau2:byte);
  14429. Erzeugt einen stufenlosen Farbverlauf zwischen den Farbnum-
  14430. mern Nr1 und Nr2.
  14431.  
  14432. TransFormRGBtoHSV
  14433. procedure TransFormRGBtoHSV(R,G,B:byte;var H,S,V:real);
  14434. Transformiert eine Farbe im RGB-Modell in die gleiche Farbe
  14435. im HSV-Modell. H (Hue) stellt den Farbwinkel (0..360 Grad),
  14436. S (Saturation) die Farbsättigung (0..1) und V (Value) den
  14437. Helligkeitswert (0..1) dar.
  14438.  
  14439.  
  14440.  
  14441.  
  14442.  
  14443.  
  14444. Programmierhandbuch                                 WG-Vision - 275 -
  14445.  
  14446.  
  14447.  
  14448.  
  14449.  
  14450.  
  14451.  
  14452. TransFormHSVtoRGB
  14453. procedure TransformHSVtoRGB(H,S,V:real;var R,G,B:byte);
  14454. Zerlegt eine Farbe im HSV-Modell in seine Farbbestandteile
  14455. Rot, Grün und Blau.
  14456.  
  14457. TransFormtoGrayScale
  14458. procedure TransformtoGrayScale(Nr,Number:byte);
  14459. Wandelt ab dem Registereintrag Nr eine bestimmte Anzahl von
  14460. Farbregister (Number) in Graustufen um.
  14461.  
  14462. StretchScale
  14463. procedure StretchScale(Minimalwert,Maximalwert,
  14464.                        Delta:byte;Positiv:boolean);
  14465. Erzeugt eine lineare Graustufenpalette zwischen den Werten
  14466. Minimalwert und Maximalwert. Ist Positiv=true, wird eine po-
  14467. sitive, ansonsten eine negative Farbpalette (von Weiß nach
  14468. Schwarz) erzeugt. Die ersten 16 Farbregister bleiben von der
  14469. Manipulation ausgeschlossen.
  14470.  
  14471. StretchPolynom
  14472. procedure StretchPolynom(Minimalwert,Maximalwert:byte;
  14473.                          Degree:real;Positiv:boolean);
  14474. Funktionsweise wie StretchScale. Es wird jedoch eine Potenz-
  14475. funktion vom Grad Degree als Display-Transferfunktion ver-
  14476. wendet.
  14477.  
  14478. StretchColor
  14479. procedure StretchColor(Minimalwert,Maximalwert:integer);
  14480. Berechnung eines linearen Farbübergangs (Spektrum) zwischen
  14481. den Paletteneintragungen Minimalwert und Maximalwert.
  14482.  
  14483. Isophote
  14484. procedure Isophote(Delta,Brightness:byte;Positiv:boolean);
  14485. Eine Isophote ist ein Bereich gleicher Helligkeit oder Far-
  14486. be. Delta gibt die Breite dieses Bereiches und Brightness
  14487. den Anfangswert der Helligkeit an (die Isophote erstreckt
  14488. sich zwischen Brightness und Brightness+Delta). Im Positiv-
  14489. Modus (Positiv=true) wird die Isophote Weiß auf schwarzem
  14490. Untergrund dargestellt. Im Negativmodus genau umgekehrt.
  14491.  
  14492.  
  14493.  
  14494. Programmierhandbuch                                 WG-Vision - 276 -
  14495.  
  14496.  
  14497.  
  14498.  
  14499.  
  14500.  
  14501.  
  14502. Aequidensiten
  14503. procedure Aequidensiten(Delta,Abstand:byte;Positiv:boolean);
  14504. Es wird eine Schar von Isophoten der Breite Delta und gege-
  14505. benen Abstand berechnet.
  14506.  
  14507. Komplexbeispiel: Völlig nutzloses Demonstrationsbeispiel für
  14508.                  die Arbeit mit der Unit WPalette
  14509.  
  14510. Das Programm PalTest.pas zeigt, wie man mit minimalen Auf-
  14511. wand durch Manipulation der Farbregister der Super-VGA-Karte
  14512. interessante Animationseffekte programmieren kann. Auf das
  14513. Desktop, welches einen stufenlosen Übergang von Hell- zu
  14514. Dunkelblau zeigt (wie die Oberfläche des Windows-Installati-
  14515. onsprogramms) soll ein skalierbares Fenster mit einer aus
  14516. 700 Rechtecken bestehenden Spirale aufgeblendet werden, die
  14517. in den VGA-Standardfarben rotiert. Außerdem soll ein Palet-
  14518. tenworkshop zur Änderung der Paletteneintragungen aufblend-
  14519. bar sein (Objekt TPalWorkShop in der Unit WPalette).
  14520.  
  14521. program PalTest;
  14522.  
  14523. uses WDecl,
  14524.      WApp,
  14525.      WEvent,
  14526.      WViews,
  14527.      WDlg,
  14528.      WDriver,
  14529.      WUtils,
  14530.      WPalette,
  14531.      graph;
  14532.  
  14533. const cmPalEdit=101;
  14534.       cmDemo=102;
  14535.       cmGrayBar=103;
  14536.  
  14537. var  Pal:TPalette;
  14538.  
  14539.  
  14540.  
  14541.  
  14542.  
  14543.  
  14544. Programmierhandbuch                                 WG-Vision - 277 -
  14545.  
  14546.  
  14547.  
  14548.  
  14549.  
  14550.  
  14551.  
  14552. type TApplication=object(TApp)
  14553.       procedure InitVideoDevice; virtual;
  14554.       procedure SetDesktopBackground; virtual;
  14555.       procedure InitMenuBar; virtual;
  14556.       procedure HandleEvent; virtual;
  14557.       procedure PalettenEditor;
  14558.       procedure PalettenDemo;
  14559.       procedure Graukeil;
  14560.      end;
  14561.  
  14562.      PPalDemo=^TPalDemo;
  14563.      TPalDemo=object(TWindow)
  14564.       Richtung:byte;   {gibt die Richtung an, in welcher "spiralt" wird}
  14565.       constructor Init;
  14566.       procedure InitBackGround; virtual;
  14567.       procedure SetPalette; virtual;
  14568.       procedure HandleEvent; virtual;
  14569.      end;
  14570.  
  14571.      PNewDTBgrd=^TNewDTBgrd;
  14572.      TNewDTBgrd=object(TDsktpBgrd)
  14573.       procedure Draw; virtual;
  14574.      end;
  14575.  
  14576.      PPalDemoBgrd=^TPalDemoBgrd;
  14577.      TPalDemoBgrd=object(TBackground)
  14578.       procedure Draw; virtual;
  14579.      end;
  14580.  
  14581. var MyApp:TApplication;
  14582.  
  14583. {Implementation TApplication}
  14584.  
  14585. Dieses Beispiel funktioniert nur in den 256-Farben VESA-Modi. Deshalb
  14586. ist es unerläßlich, die Methode InitVideoDevice zu überschreiben.
  14587.  
  14588.  
  14589.  
  14590.  
  14591.  
  14592.  
  14593.  
  14594. Programmierhandbuch                                 WG-Vision - 278 -
  14595.  
  14596.  
  14597.  
  14598.  
  14599.  
  14600.  
  14601.  
  14602. procedure TApplication.InitVideoDevice;
  14603. begin
  14604.   Video.Init(VESA,M640x480);
  14605. end;
  14606.  
  14607. procedure TApplication.SetDesktopBackground;
  14608. var R:TRect;
  14609. begin
  14610.   with Desktop^ do
  14611.    begin
  14612.      R:=Frame^.Area;
  14613.      Bgrd:=new(PNewDTBgrd, Init(R));
  14614.      List^.InsertItem(Bgrd);
  14615.    end;
  14616. end;
  14617.  
  14618. procedure TApplication.InitMenuBar;
  14619. begin
  14620.   MainMenu('~P~alette',1);
  14621.     SubMenu('~P~aletteneditor', cmPalEdit,0,0,false,false);
  14622.     SubMenu('~D~emonstration',cmDemo,0,0,false,false);
  14623.     SubMenu('~G~raukeil',cmGrayBar,0,0,false,false);
  14624.     NewLine;
  14625.     SubMenu('E~x~it  <Alt><X>',cmCloseApplication,0,0,false,false);
  14626. end;
  14627.  
  14628. procedure TApplication.HandleEvent;
  14629. begin
  14630.   TProgram.HandleEvent;
  14631.   case Event.Command of
  14632.    cmPalEdit:PalettenEditor;
  14633.    cmDemo:PalettenDemo;
  14634.    cmGrayBar:Graukeil;
  14635.   end; {case}
  14636. end;
  14637.  
  14638.  
  14639.  
  14640.  
  14641.  
  14642.  
  14643.  
  14644. Programmierhandbuch                                 WG-Vision - 279 -
  14645.  
  14646.  
  14647.  
  14648.  
  14649.  
  14650.  
  14651.  
  14652. Der Paletteneditor ist ein Bestandteil der Unit WPalette. Mit seiner
  14653. Hilfe können sehr komfortabel Paletteneintragungen im RGB- und HSV-
  14654. Farbmodell editiert werden. Außerdem lassen sich Paletten abspeichern
  14655. und wieder laden.
  14656.  
  14657. procedure TApplication.PalettenEditor;
  14658. var Window:PPalWorkShop;
  14659. begin
  14660.   Window:=new(PPalWorkShop, Init(180,100));
  14661.   InsertDesktop(Window);
  14662. end;
  14663.  
  14664. procedure TApplication.PalettenDemo;
  14665. var Window:PPalDemo;
  14666. begin
  14667.   Window:=new(PPalDemo, Init);
  14668.   InsertDesktop(Window);
  14669. end;
  14670.  
  14671. Der Graukeil dient der Anzeige der gerade aktiven Palette als "Graukeil"
  14672. oder "Spektrum". Das Objekt TGrayBar ist auch Bestandteil der Unit
  14673. WPalette.
  14674.  
  14675. procedure TApplication.Graukeil;
  14676. var Window:PGrayBar;
  14677. begin
  14678.   Window:=new(PGrayBar, Init(300,350));
  14679.   InsertDesktop(Window);
  14680. end;
  14681.  
  14682. {Implementation TPalDemo}
  14683.  
  14684. constructor TPalDemo.Init;
  14685. var R:TRect;
  14686. begin
  14687.   R.Assign(100,60,300,260);
  14688.   TWindow.Init(R,'Spirale',winDouble+winPanel+winKey+winMenu);
  14689.   Richtung:=0;
  14690. end;
  14691.  
  14692.  
  14693.  
  14694. Programmierhandbuch                                 WG-Vision - 280 -
  14695.  
  14696.  
  14697.  
  14698.  
  14699.  
  14700.  
  14701.  
  14702. procedure TPalDemo.InitBackground;
  14703. var R:TRect;
  14704. begin
  14705.   R:=Frame^.Area;
  14706.   Bgrd:=new(PPalDemoBgrd, Init(R));
  14707.   List^.InsertItem(Bgrd);
  14708. end;
  14709.  
  14710. Hier ändern wir die Panelfarbe in Gelb und die Textfarbe für die
  14711. Titelleiste in Blau.
  14712.  
  14713. procedure TPalDemo.SetPalette;
  14714. begin
  14715.   Palette:=Palette1;
  14716.   Palette[4]:=#14; Palette[5]:=#14; Palette[6]:=#1;
  14717. end;
  14718.  
  14719. Der Eventhandler des Demonstrationsfensters gestaltet sich sehr einfach.
  14720. In ihm wird bei jedem Durchgang die Methode RotatePart aufgerufen,
  14721. welche den Palettenbereich zwischen den Eintragungen 166 und 182
  14722. rotieren läßt. Durch Drücken der rechten Maustaste kann die Drehrichtung
  14723. jeweils umgeschalten werden.
  14724.  
  14725. procedure TPalDemo.HandleEvent;
  14726. begin
  14727.   TWindow.HandleEvent;
  14728.   Pal.GetPalette;
  14729.   if Mouse.RButtonKlick then
  14730.    if Richtung=0 then Richtung:=1 else Richtung:=0;
  14731.   Pal.RotatePart(Richtung,166,182);
  14732. end;
  14733.  
  14734. {Implementation TNewDTBgrd}
  14735.  
  14736. Erzeugen eines stufenlosen Übergangs von Hell- zu Dunkelblau. Für diesen
  14737. Übergang wird der Palettenbereich zwischen 16 und 155 genutzt.
  14738.  
  14739.  
  14740.  
  14741.  
  14742.  
  14743.  
  14744. Programmierhandbuch                                 WG-Vision - 281 -
  14745.  
  14746.  
  14747.  
  14748.  
  14749.  
  14750.  
  14751.  
  14752. procedure TNewDTBgrd.Draw;
  14753. var dy,i:integer;
  14754. begin
  14755.   Pal.GetPalette;        {aktive (Standard-) Palette in Pal übernehmen}
  14756.   Pal.SetVerlauf(16,0,0,63,155,0,0,20);    {von Hellblau zu Dunkelblau}
  14757.  
  14758. Damit die "Spirale" in den Standard-VGA-Farben Blau bis Weiß erstrahlt,
  14759. werden die Paletteneintragungen 166 bis 182 auf diese Werte gesetzt.
  14760.  
  14761.   for i:=1 to 15 do PAL.LUT[165+i]:=Pal.LUT[i];
  14762.  
  14763. Achtung! Die Palettenänderungen werden nur innerhalb des Paletten-
  14764. Objekts ausgeführt (konkret, die Tabelle LUT wird verändert). Das hat
  14765. keine Auswirkungen auf dem Bildschirm. Erst wenn die manipulierte
  14766. Palette in die VGA-Karte geladen wird, erscheinen die Änderungen auf dem
  14767. Bildschirm. Deshalb muß unbedingt die Methode SetPalette aufgerufen
  14768. werden.
  14769.  
  14770.   Pal.SetPalette;
  14771.  
  14772. Neuen Desktop-Hintergrund malen.
  14773.  
  14774.   with Border do
  14775.    begin
  14776.      dy:=(B.y-A.y) div 139;  {Streifenbreite}
  14777.      for i:=0 to 138 do
  14778.       FBar(A.x,A.y+i*dy+18,B.x,A.y+(i+1)*dy+18,15+i);
  14779.    end;
  14780. end;
  14781.  
  14782. {Implementation TPalDemoBgrd}
  14783.  
  14784. Auf den Fensterhintergrund wird eine Spirale aus farbigen Rechtecken
  14785. gezeichnet, wobei sich die Farbnummern der Rechtecke zyklisch zwischen
  14786. 166 und 182 bewegen. Da das Fenster skalierbar ist, muß auch die Größe
  14787. der Spirale (genauer ihr Radius nach dem Motto "kleines Fenster - kleine
  14788. Spirale, großes Fenster - große Spirale) an die Fenstergröße angepaßt
  14789. werden. Die Rechnungen dafür beanspruchen nur den wichtigsten
  14790. mathematischen Lehrsatz des Computergrafikers, des Dreisatzes.
  14791.  
  14792.  
  14793.  
  14794. Programmierhandbuch                                 WG-Vision - 282 -
  14795.  
  14796.  
  14797.  
  14798.  
  14799.  
  14800.  
  14801.  
  14802. procedure TPalDemoBgrd.Draw;
  14803. var Color:byte;
  14804.     i,x,y:integer;
  14805.     Radius:real;
  14806.     xm,ym:integer;
  14807.     dx,dy:real;
  14808.  
  14809. begin
  14810.   Color:=165;
  14811.   with Border do
  14812.    begin
  14813.      FBar(A.x,A.y,B.x,B.y,Black);                 {Schwarzer Untergrund}
  14814.      xm:=(B.x-A.x) div 2;                            {Mitte der Spirale}
  14815.      ym:=(B.y-A.y) div 2;
  14816.      dx:=B.x-A.x; dy:=B.y-A.y;
  14817.      for i:=0 to 700 do                                  {Spirale malen}
  14818.       begin
  14819.         inc(Color);
  14820.         if Color=182 then Color:=166;
  14821.         if dx<dy then Radius:=i*dx/4480.0       {Radius an Fenstergröße}
  14822.                                                               {anpassen}
  14823.          else Radius:=i*dy/4480.0;
  14824.         x:=trunc(Radius*cos(Radius)*3)+xm;
  14825.         y:=trunc(Radius*sin(Radius)*3)+ym;
  14826.         FBar(A.x+x,A.y+y,A.x+x+8,A.y+y+6,Color);
  14827.            {Farbrechteck malen}
  14828.       end;
  14829.    end;
  14830. end;
  14831.  
  14832. {Hauptprogramm}
  14833.  
  14834. begin
  14835.   MyApp.Init('Paletten-Demo');
  14836.   MyApp.Run;
  14837.   MyApp.Done;
  14838. end.
  14839.  
  14840.  
  14841.  
  14842.  
  14843.  
  14844. Programmierhandbuch                                 WG-Vision - 283 -
  14845.  
  14846.  
  14847.  
  14848.  
  14849.  
  14850.  
  14851.  
  14852. Das Objekt PAL als Instanz von TPalette wurde global im
  14853. Programm vereinbart, damit alle Programmteile ohne Umwege
  14854. darauf zugreifen können.
  14855.  
  14856. 6.5.1. Farbmodelle
  14857.  
  14858. WG-Vision unterstützt in den VESA-Modi zwei verschiedene
  14859. Farbmodelle, das RGB-Modell und das HSV-Modell.
  14860. Das RGB-Modell ist in der Computergrafik am weitesten ver-
  14861. breitet, wenn es auch meistens nur intern und damit für den
  14862. Benutzer nicht sichtbar wirkt. Die gesamte Funktionsweise
  14863. der VGA-Karte liegt diesem Farbmodell zugrunde.
  14864.  
  14865. 6.5.1.1. RGB-Modell
  14866.  
  14867. Beim RGB-Modell handelt es sich um ein sogenanntes additives
  14868. Farbmodell. Zur Darstellung verwendet man einen Einheitswür-
  14869. fel. Jede Farbe innerhalb dieses Würfels wird durch ihre Ko-
  14870. ordinaten, d.h. durch ihre Anteile an den Grundfarben Rot,
  14871. Grün und Blau charakterisiert. Die Farbe Gelb ergibt sich
  14872. z.B. als Summe von Rot und Grün in ihrer vollen Intensität,
  14873. dargestellt durch das Zahlentripel (1,1,0). Um einen konti-
  14874. nuierlichen Übergang zwischen zwei verschiedenen Farben zu
  14875. erreichen, muß man lediglich die beiden den Farben entspre-
  14876. chenden Punkte im Einheitswürfel durch eine Gerade verbinden
  14877. und in n gleiche Teile teilen, wobei n die Anzahl der ge-
  14878. wünschten Zwischenstufen ist. In der Prozedur SetVerlauf
  14879. wird von dieser Methode gebrauch gemacht. Aus technischen
  14880. Gründen wird die volle Intensität einer Farbe innerhalb der
  14881. Unit WPalette nicht der Wert 1, sondern der Wert 63 zugeord-
  14882. net. In WG-Vision würde die Farbe Gelb also durch das Tripel
  14883. (63,63,0) und die Farbe Blau durch das Tripel (0,0,63) be-
  14884. schrieben werden.
  14885.  
  14886.  
  14887.  
  14888.  
  14889.  
  14890.  
  14891.  
  14892.  
  14893.  
  14894. Programmierhandbuch                                 WG-Vision - 284 -
  14895.  
  14896.  
  14897.  
  14898.  
  14899.  
  14900.  
  14901.  
  14902. 6.5.1.2. HSV-Modell
  14903.  
  14904. Das RGB-Farbmodell ist für viele Anwendungsfälle nicht sehr
  14905. gut geeignet. Besser ist es, eine Farbe, so wie es ein Maler
  14906. macht, durch Farbton, Helligkeit und Schattierung zu be-
  14907. schreiben. Diesen Ansatz verfolgt das HSV-Modell, das zwar
  14908. letztendlich vom RGB-Modell abgeleitet wird, aber die Para-
  14909. meter Hue (Farbe, ausgedrückt als Winkel), Saturation /Farb-
  14910. sättigung) und Value (Helligkeit) verwendet. Der Parameter S
  14911. (Saturation) liegt im Bereich von 0 bis 1 und repräsentiert
  14912. das Verhältnis der Reinheit der Farbe zu ihrer maximalen
  14913. Reinheit (S=1). Die Intensität der Farbe wird durch den Pa-
  14914. rameter V (Value) bestimmt, der im Bereich zwischen Null
  14915. (keine Helligkeit) und 1 (maximale Helligkeit) liegt.
  14916. Die Farbe selbst wird durch einen Winkel repräsentiert, wo-
  14917. bei 0° der Farbe Rot, 60° Gelb, 120° Grün, 180° Cyan, 240°
  14918. Blau und 300° Magenta entspricht. Die reinsten Farben besit-
  14919. zen die Werte V=S=1 und unterscheiden sich nur im Farbwin-
  14920. kel.
  14921. Das Objekt TPalette enthält Methoden, wie man Farbwerte aus
  14922. dem RGB-Modell in das HSV-Modell umrechnen kann und umge-
  14923. kehrt. Eine Anwendung dieser Methoden finden Sie im Palet-
  14924. tenworkshop. Ich empfehle eine genaue Analyse dieses
  14925. Werkzeugs, da es sehr schön zeigt, wie Palettenmanipulatio-
  14926. nen innerhalb eines Dialogfensters in WG-Vision programmiert
  14927. werden.
  14928.  
  14929. Eine komplexe Anwendung, die von Palettenmanipulationen ex-
  14930. tensiv gebrauch macht, finden Sie im Demonstrationsprogramm
  14931. SBGDEMO.
  14932.  
  14933.  
  14934.  
  14935.  
  14936.  
  14937.  
  14938.  
  14939.  
  14940.  
  14941.  
  14942.  
  14943.  
  14944. Programmierhandbuch                                 WG-Vision - 285 -
  14945.  
  14946.  
  14947.  
  14948.  
  14949.  
  14950.  
  14951.  
  14952. 7. Die Kern-Units von WG-Vision
  14953.  
  14954. 7.1. Unit WAPP.PAS
  14955.  
  14956. Die Unit WAPP stellt das Applikationsobjekt zur Verfügung.
  14957. Jedes WG-Vision-Programm leitet sich von diesem Objekt ab.
  14958.  
  14959. 7.1.1. Aufbau eines WG-Vision-Programms
  14960.  
  14961. Das Minimalprogramm
  14962.  
  14963. program Mini;
  14964.  
  14965. uses WApp:
  14966.  
  14967. type WApplication=object(WApp)
  14968.      end;
  14969.  
  14970. var MyApp:TApplication;
  14971.  
  14972. begin
  14973.   MyApp.Init;
  14974.   MyApp.Run;
  14975.   MyApp.Done;
  14976. end.
  14977.  
  14978. führt im Einzelnen folgende Schritte aus:
  14979.  
  14980. constructor TApp.Init(Titel:string);
  14981. begin
  14982.  
  14983. Der Konstruktor des Vorgängerobjekts TProgram führt sämtliche Program-
  14984. minitialisierungen aus. Dazu gehört die Initialisierung der Grafik, der
  14985. Maus, der Tastatur und des Joysticks, für die jeweils Instanzen (Video,
  14986. Mouse,Keyboard und Joy) bereitgestellt werden. Anschließend wird ein
  14987. Desktop-Objekt auf dem Heap erzeugt. Dieses Objekt verwaltet in der dop-
  14988. pelt verketteten Liste mit der Bezeichnung List alle Bestandteile des
  14989. Desktops, die über die virtuellen Methoden SetDesktopFrame und SetDesk-
  14990. topBackground in das Desktop eingefügt werden. Eine weitere Initialisie-
  14991.  
  14992.  
  14993.  
  14994. Programmierhandbuch                                 WG-Vision - 286 -
  14995.  
  14996.  
  14997.  
  14998.  
  14999.  
  15000.  
  15001.  
  15002. rung betrifft Instanzen der Objekte TMemory und TEMS. Letztere Instanz
  15003. wird nur dann angelegt, wenn während der Abarbeitung des Initialisie-
  15004. rungsteils der Unit WEMS Expanded Memory entdeckt wurde. Zum Abschluß
  15005. wird das Menü erzeugt und die Dialogrecords initialisiert. InitMenuBar
  15006. und SetDialogData sind leere Methoden, die der Programmierer mit den
  15007. richtigen Code selbständig belegen muß.
  15008.  
  15009.   TProgram.InitTitel);
  15010.  
  15011. Die Draw-Methode von TProgram stellt alle Desktopelemente auf dem
  15012. Bildschirm dar und blendet eventuell vorhandene Menüs und Statuszeilen
  15013. auf.
  15014.  
  15015.   Draw;
  15016. end;
  15017.  
  15018. Die Methode Run ist die eigentliche Abarbeitungsschleife.
  15019. Ihr Aufbau ist recht einfach:
  15020.  
  15021. procedure TProgram.Run;
  15022. begin
  15023.  
  15024. Der anfänglich mit zufälligen Werten belegte Event-Record wird auf seine
  15025. Standardwerte gesetzt.
  15026.  
  15027.   ClearEvent;
  15028.   ClearMessage;
  15029.  
  15030. Jetzt folgt die große Abarbeitungsschleife, die solange ausgeführt wird,
  15031. bis der Eventhandler das Kommando cmCloseApplication sendet. GetEvent
  15032. arbeitet Tastatur und Maus ab und aktualisiert jeweils die Felder dieser
  15033. Objekte. In HandleEvent sind alle Eventhandler der zum Zeitpunkt aktiven
  15034. Fensterobjekte und der Eventhandler des Menüs enthalten. ClearEvent
  15035. setzt u.a. das Feld What des Event-Records auf evNothing.
  15036.  
  15037.  
  15038.  
  15039.  
  15040.  
  15041.  
  15042.  
  15043.  
  15044. Programmierhandbuch                                 WG-Vision - 287 -
  15045.  
  15046.  
  15047.  
  15048.  
  15049.  
  15050.  
  15051.  
  15052.   repeat
  15053.     Heap^.HeapWatch;
  15054.     if EMS_Installed then EMS^.Watch;
  15055.     GetEvent;
  15056.     HandleEvent;
  15057.     ClearEvent;
  15058.   until Event.Command=cmCloseApplication;
  15059. end;
  15060.  
  15061. TApp.Done entfernt alle dynamischen Objekte vom Heap und
  15062. beendet das Programm.
  15063.  
  15064. Objekt TProgramm
  15065.  
  15066. Felder (Auswahl)
  15067.  
  15068. Desktop
  15069. Desktop:PDesktop;
  15070. Desktop ist ein Nachfahre von TGroup und enthält Zeiger, die
  15071. auf den Desktop-Rahmen und den Hintergrund zeigen. Außerdem
  15072. enthält dieses Objekt die doppelt verkettete Liste WinList,
  15073. die alle Fensterobjekte aufnimmt.
  15074.  
  15075. MMenu
  15076. MMenu:PMainMenu;
  15077. Zeiger auf die Hauptmenüeintragungen. Jeder Hauptmenüpunkt
  15078. verwaltet separat sein Untermenü.
  15079.  
  15080. Heap,EMS
  15081. Instanzen der Objekte, die für die Verwaltung bzw. Überwa-
  15082. chung des Heaps und des Expanded Memory verantwortlich sind.
  15083.  
  15084. MAnzahl
  15085. MAnzahl:byte;
  15086. Enthält die Anzahl der Hauptmenüfelder.
  15087.  
  15088.  
  15089.  
  15090.  
  15091.  
  15092.  
  15093.  
  15094. Programmierhandbuch                                 WG-Vision - 288 -
  15095.  
  15096.  
  15097.  
  15098.  
  15099.  
  15100.  
  15101.  
  15102. Aktiv
  15103. Aktiv:boolean;
  15104. Aktiv ist immer dann true, wenn ein Menü aufgeblendet bzw.
  15105. die Menüzeile aktiviert ist.
  15106.  
  15107. SAktiv
  15108. SAktiv:boolean;
  15109. Immer wenn ein Pull-Down-Menü aufgeblendet ist, wird SAktiv
  15110. auf true gesetzt.
  15111.  
  15112. WinAnz
  15113. WinAnz:byte;
  15114. In WinAnz wird die Anzahl der Eintragungen in der Window-
  15115. Liste des Desktops gespeichert.
  15116.  
  15117. Modal
  15118. Modal:boolean;
  15119. Dieser Wert ist immer dann true, wenn das aktive Fenster
  15120. nicht-modal ist.
  15121.  
  15122. ifHelp
  15123. ifHelp:boolean;
  15124. Wenn das Desktop mit einem Hilfesystem ausgestattet ist, ist
  15125. diese Variable true.
  15126.  
  15127. HelpFile
  15128. HelpFile:string;
  15129. Enthält den Namen der Help-Datei, wenn das Hilfesystem akti-
  15130. viert ist.
  15131.  
  15132. Methoden (Auswahl)
  15133.  
  15134. InsertDesktop
  15135. procedure InsertDesktop(Item:PGroup);
  15136. Mit InsertDesktop wird ein Fenster in die Windowliste des
  15137. Desktops eingefügt. Item muß ein Zeiger auf solch ein Fen-
  15138. sterobjekt sein.
  15139.  
  15140.  
  15141.  
  15142.  
  15143.  
  15144. Programmierhandbuch                                 WG-Vision - 289 -
  15145.  
  15146.  
  15147.  
  15148.  
  15149.  
  15150.  
  15151.  
  15152. SetDesktopFrame
  15153. procedure SetDesktopFrame(Titel:string); virtual;
  15154. Einfügen des Rahmens mit Panel und Titelzeile in das Desk-
  15155. top. Wenn Sie den Rahmen des Desktops verändern möchten,
  15156. müssen Sie diese Methode überschreiben.
  15157.  
  15158. SetDesktopBackground
  15159. procedure SetDesktopBackground(Titel:string); virtual;
  15160. Einfügen des Clientbereichs (Hintergrund)in das Desktop.
  15161. Wenn Sie den Desktop-Hintergrund ändern möchten, müssen Sie
  15162. diese Methode überschreiben.
  15163.  
  15164. Statusbar
  15165. procedure Statusbar; virtual;
  15166. Leere Methode. Dient der Implementierung einer Statuszeile.
  15167.  
  15168. MainMenu, SubMenu, NewLine
  15169. Diese Methoden werden für die Implementierung eines
  15170. Menübaums benötigt. Sie werden innerhalb von InitMenuBar
  15171. implementiert.
  15172.  
  15173. InitVideoDevice
  15174. procedure InitVideoDevice; virtual;
  15175. Initialisierung der Grafik. Diese Methode muß überschrieben
  15176. werden, wenn ein neuer Grafikmodus eingestellt werden soll.
  15177.  
  15178. InitMenuBar
  15179. procedure InitMenuBar; virtual;
  15180. Diese leere Methode muß überschrieben werden, wenn ein Menü
  15181. benötigt wird.
  15182.  
  15183. LoadMenu
  15184. procedure LoadMenu(ResName:str80);
  15185. Laden eines Menübaums aus einer Menüressource. Diese Methode
  15186. wird innerhalb von InitMenuBar angewendet.
  15187.  
  15188. ClearMenu
  15189. procedure ClearMenu;
  15190. Löschen des momentan aktiven Menübaums.
  15191.  
  15192.  
  15193.  
  15194. Programmierhandbuch                                 WG-Vision - 290 -
  15195.  
  15196.  
  15197.  
  15198.  
  15199.  
  15200.  
  15201.  
  15202. DrawMainMenu
  15203. procedure DrawMainMenu;
  15204. Zeichnet die Hauptmenüzeile neu auf das Desktop.
  15205.  
  15206. SetDialogData
  15207. procedure SetDialogData; virtual;
  15208. Diese leere Methode, die im Anwendungsfall überschrieben
  15209. werden muß, dient der Initialisierung der Dialogrecords von
  15210. Dialogfenstern.
  15211.  
  15212. SetOnlineHelp
  15213. procedure SetOnlineHelp(HelpDatei:string);
  15214. Initialisiert die kontextsensitive Hilfe und lädt die
  15215. Helpdatei.
  15216.  
  15217. MessageBox
  15218. procedure MessageBox(Caption:word;PanelText,
  15219.                      InfoText:string);
  15220. Installiert ein Mitteilungsfenster in die Window-Liste des
  15221. Desktops.
  15222.  
  15223.  
  15224.  
  15225.  
  15226.  
  15227.  
  15228.  
  15229.  
  15230.  
  15231.  
  15232.  
  15233.  
  15234.  
  15235.  
  15236.  
  15237.  
  15238.  
  15239.  
  15240.  
  15241.  
  15242.  
  15243.  
  15244. Programmierhandbuch                                 WG-Vision - 291 -
  15245.  
  15246.  
  15247.  
  15248.  
  15249.  
  15250.  
  15251.  
  15252. 7.2. Unit WViews.pas
  15253.  
  15254. In der Unit WViews befinden sich ein paar wichtige Objekte,
  15255. die einmal für die innere Organisation (z.B. TView, TGroup)
  15256. der Toolbox und zum anderen für das äußere Erscheinungsbild
  15257. von WG-Vision (TFrame, TBackground, TMainMenu, TDeskTop)
  15258. verantwortlich sind. Alle Objekte, die irgendwie auf dem
  15259. Bildschirm sichtbar sind, leiten sich letztendlich von TView
  15260. ab.
  15261.  
  15262. 7.2.1. Objekt TView
  15263.  
  15264. Felder
  15265.  
  15266. Prev
  15267. Prev:PGroup;
  15268. Zeiger auf den Vorgänger (wichtig für die verkettete Liste
  15269. TGroup)
  15270.  
  15271. Next
  15272. Next:PGroup;
  15273. Zeiger auf den Nachfolger (wichtig für die verkettete Liste
  15274. TGroup)
  15275.  
  15276. Palette
  15277. Palette:TPalette;
  15278. Dem TView-Objekt zugeordnete Farbpalette
  15279.  
  15280. Origin
  15281. Origin:TPoint;
  15282. Koordinaten der linken oberen Ecke des TView-Objekts
  15283.  
  15284. Size
  15285. Size:TPoint;
  15286. Länge (Size.x) und Breite (Size.y) des TView-Objekts.
  15287.  
  15288.  
  15289.  
  15290.  
  15291.  
  15292.  
  15293.  
  15294. Programmierhandbuch                                 WG-Vision - 292 -
  15295.  
  15296.  
  15297.  
  15298.  
  15299.  
  15300.  
  15301.  
  15302. RSize
  15303. RSize:boolean;
  15304. Diese logische Variable wird auf true gesetzt, wenn ein Fen-
  15305. ster als Nachfolger von TView bis auf Minimalgröße verklei-
  15306. nerbar ist.
  15307.  
  15308. Methoden (Auswahl)
  15309.  
  15310. Init
  15311. constructor Init(var Bounds:TRect; SetSize:boolean);
  15312. Setzt Prev und Next auf nil und belegt die Felder Origin und
  15313. Size mit den Werten, die sich aus Bounds ergeben. SetSize
  15314. setzt die logische Variable RSize.
  15315.  
  15316. SetBounds
  15317. procedure SetBounds(var Bounds:TRect);
  15318. Belegt die Felder Origin und Size mit den Werten, die sich
  15319. aus Bounds ergeben. Ist RSize=true und Size.x<100 bzw.
  15320. Size.y<86, dann wird Size auf (100,86) gesetzt. (Minimale
  15321. Größe von Fenster mit Panel).
  15322.  
  15323. GetBounds
  15324. procedure GetBounds(var Bounds:TRect);
  15325. Übergibt die in Origin und Size gespeicherten Werte in
  15326. Bounds als TRect-Objekt.
  15327.  
  15328. ChangeBounds
  15329. procedure ChangeBounds(var Bounds:TRect);
  15330. Setzt die Werte von Origin und Size entsprechend Bounds neu.
  15331.  
  15332. GrowTo
  15333. procedure GrowTo(x,y:integer);
  15334. Vergrößert Size um x und y.
  15335.  
  15336. Locate
  15337. procedure Locate(var Bounds:TRect);
  15338. Stellt sicher, daß ein TView-Objekt mit RSize=true seine Mi-
  15339. nimalgröße von 100x86 nicht unterschreitet.
  15340.  
  15341.  
  15342.  
  15343.  
  15344. Programmierhandbuch                                 WG-Vision - 293 -
  15345.  
  15346.  
  15347.  
  15348.  
  15349.  
  15350.  
  15351.  
  15352. GetPalColor
  15353. GetPalColor(Index:byte):byte;
  15354. Übergibt die Nummer der Farbe an der Position Index der
  15355. Farbpalette von TView.
  15356.  
  15357. 7.2.2. Objekt TGroup
  15358.  
  15359. TGroup ist eines der wichtigsten Objekte in WG-Vision. Es
  15360. stellt eine doppelt verkettete Liste zur Verfügung, die alle
  15361. möglichen TView-Objekte aufnehmen und verwalten kann.
  15362.  
  15363. Felder
  15364.  
  15365. First
  15366. First:PGroup;
  15367. Zeiger auf das erste Element der Liste.
  15368.  
  15369. Last
  15370. Last:PGroup;
  15371. Zeiger auf das letzte Element der Liste
  15372.  
  15373. Current
  15374. Current:PGroup;
  15375. Zeiger auf das gerade aktive Element der Liste.
  15376.  
  15377. CurrNo
  15378. CurrNo:word;
  15379. Index des gerade aktiven Elements der Liste.
  15380.  
  15381. AnzElem
  15382. AnzElem:word;
  15383. Anzahl der Elemente der Liste.
  15384.  
  15385. Methoden  {Auswahl}
  15386.  
  15387. Init
  15388. constructor Init;
  15389. Setzt First, Last und Current auf nil sowie CurrNo und
  15390. AnzElem auf Null.
  15391.  
  15392.  
  15393.  
  15394. Programmierhandbuch                                 WG-Vision - 294 -
  15395.  
  15396.  
  15397.  
  15398.  
  15399.  
  15400.  
  15401.  
  15402. Done
  15403. destructor Done;
  15404. Löscht die Liste und entfernt sie vom Heap.
  15405.  
  15406. InsertItem
  15407. InsertItem(Item:PGroup);
  15408. Fügt das Element Item in die Liste ein.
  15409.  
  15410. DeleteItems
  15411. procedure DeleteItems;
  15412. Löscht die gesamte Liste.
  15413.  
  15414. GetItems
  15415. function GetItems(Nr:word):PGroup;
  15416. Übergibt einen Zeiger auf das Listenelement mit dem Index
  15417. Nr.
  15418.  
  15419. UnChainItem
  15420. procedure UnChainItem(N:PGroup);
  15421. Kettet das Element N aus der Liste aus.
  15422.  
  15423. DelItem
  15424. procedure DelItem(N:PGroup);
  15425. Löscht das Element N aus der Liste.
  15426.  
  15427. DelLastItem
  15428. procedure DelLastItem;
  15429. Löscht das letzte Element aus der Liste.
  15430.  
  15431. Draw
  15432. procedure Draw; virtual;
  15433. Veranlaßt, daß nacheinander die Draw-Methoden aller Listen-
  15434. elemente abgearbeitet werden.
  15435.  
  15436. Hide
  15437. procedure Hide; virtual;
  15438. Ruft die Hide-Methode aller Listenelemente auf. Die Objekte
  15439. verschwinden vom Bildschirm.
  15440.  
  15441.  
  15442.  
  15443.  
  15444. Programmierhandbuch                                 WG-Vision - 295 -
  15445.  
  15446.  
  15447.  
  15448.  
  15449.  
  15450.  
  15451.  
  15452. SwapItems
  15453. procedure SwapItems(i:word);
  15454. Tauscht das letzte Element der Liste gegen das Element mit
  15455. dem Index i aus.
  15456.  
  15457. 7.2.2.1. Aufbau einer doppelt verketteten Liste
  15458.  
  15459. Doppelt verkettete Listen enthalten in jedem Element zwei
  15460. Pointer, wobei der Eine auf den Vorgänger (Prev) und der
  15461. andere auf den Nachfolger (Next) zeigt:
  15462.  
  15463.  
  15464.           Item A <┐ ┌──> Item B  <┐ ┌──> Item C <┐ ┌──> Item D
  15465.         [Inhalt]  │ │   [Inhalt]  │ │   [Inhalt] │ │   [Inhalt]
  15466.           Next ───┼─┘     Next ───┼─┘    Next ───┼─┘    Next ─────> nil
  15467. nil <───  Prev    └─────  Prev    └───── Prev    └───── Prev
  15468.  
  15469.  
  15470.           FIRST                         (CURRENT)       LAST
  15471.  
  15472. Index      1               2              3 (CurrNo)     4 = AnzElem
  15473.  
  15474. Durch Umkettung können leicht Listenelemente aus der Liste
  15475. entfernt, ausgetauscht oder neue eingebaut werden.
  15476. Um die Arbeit mit Listen vom Typ TGroup zu demonstrieren,
  15477. folgt jetzt ein kommentierter Ausschnitt aus dem Eventhand-
  15478. ler des Applikationsobjekts (TProgram.HandleEvent), welches
  15479. sehr schön die Arbeit mit der Fensterliste des Desktops
  15480. zeigt:
  15481.  
  15482.  
  15483.  
  15484.  
  15485.  
  15486.  
  15487.  
  15488.  
  15489.  
  15490.  
  15491.  
  15492.  
  15493.  
  15494. Programmierhandbuch                                 WG-Vision - 296 -
  15495.  
  15496.  
  15497.  
  15498.  
  15499.  
  15500.  
  15501.  
  15502. In der Toolbox verwenden wir die Variable LfdPtr zum
  15503. Zwischenspeichern eines Listenelements:
  15504.  
  15505. var LfdPtr:PGroup;
  15506.  
  15507. ...
  15508. with DeskTop^ do             {Window zeichnen}
  15509.  begin
  15510.  
  15511. In Desktop werden in der Liste WinList alle Fenster verwaltet. WinAnz
  15512. und WinCount enthalten, gewissermaßen global, die Anzahl dieser Fenster,
  15513. wobei WinAnz bereits dann inkrementiert wird, wenn ein Fenster in die
  15514. Windowliste eingebaut wird. WinCount wird erst nach dem Aufblenden auf
  15515. dem Bildschirm um eins erhöht. Auf diese Weise kann der Eventhandler
  15516. entscheiden, ob er das in die Liste eingefügte Fenster aufblenden soll
  15517. oder nicht.
  15518.  
  15519.    if (WinAnz<>WinCount) and (WinCount<255) then
  15520.     begin
  15521.  
  15522. Mauskursor eventuell auf Standard setzen.
  15523.  
  15524.       if Mouse.CursorTyp<>1 then Mouse.SetCursorTyp(1);
  15525.  
  15526. Wenn WinCount größer Null ist, bedeutet das, daß bereits mindestens ein
  15527. Fenster auf der Arbeitsfläche angeordnet ist. Dieses Window kann entwe-
  15528. der ein reguläres Fenster oder ein Childfenster sein. Das Rahmenobjekt
  15529. dieses Fensters erhält die "Botschaft" FrameDeAktivated=true und wird
  15530. gezwungen, seinen Rahmen neu zu zeichnen, wobei die Palette für "inak-
  15531. tiv" verwendet wird. Anschließend wird die Draw-Methode des neuen Fen-
  15532. sters abgearbeitet, die Variable Modal gesetzt und dementsprechend die
  15533. Menüzeile neu gezeichnet. Bei modalen Fenstern wird die Schrift in der
  15534. Menüzeile Grau dargestellt, um auch optisch zu zeigen, daß das Menü de-
  15535. aktiviert ist. Zum Abschluß wird WinAnz und WinCount gleichgesetzt, um
  15536. zu verhindern, daß dieser Schleifenteil beim nächsten Durchlauf des
  15537. Eventhandlers nochmals abgearbeitet wird.
  15538.  
  15539.  
  15540.  
  15541.  
  15542.  
  15543.  
  15544. Programmierhandbuch                                 WG-Vision - 297 -
  15545.  
  15546.  
  15547.  
  15548.  
  15549.  
  15550.  
  15551.  
  15552.       if WinCount>1 then               {vorheriges Fenster deaktivieren}
  15553.        begin
  15554.          LfdPtr:=WinList^.GetItems(WinCount-1);  {Zeiger auf vorheriges}
  15555.                                                                {Fenster}
  15556.          FrameDeAktivated:=true;                  {Info an "Frame.Draw"}
  15557.          if (TypeOf(LfdPtr^)=TypeOf(TDlgWindow)) and
  15558.             (PDlgWindow(LfdPtr)^.ChildPresent) then       {Childfenster}
  15559.                                                                {aktiv ?}
  15560.           begin
  15561.             with PDlgWindow(LfdPtr)^ do       {Rahmen des Childfensters}
  15562.                                                           {deaktivieren}
  15563.              begin
  15564.                LfdPtr:=Child^.First;
  15565.                PWindow(LfdPtr)^.DrawNewFrame;
  15566.              end;
  15567.           end
  15568.           else
  15569.           begin
  15570.             if PDlgWindow(LfdPtr)^.ChildPresent then
  15571.              with PDlgWindow(LfdPtr)^ do
  15572.               begin
  15573.                 LfdPtr:=Child^.First;
  15574.                 PWindow(LfdPtr)^.DrawNewFrame;
  15575.               end
  15576.              else
  15577.               PWindow(LfdPtr)^.DrawNewFrame;         {reguläres Fenster}
  15578.                                                           {deaktivieren}
  15579.           end;
  15580.        end;
  15581.  
  15582.       LfdPtr:=WinList^.GetItems(WinCount);    {neues Fenster aufblenden}
  15583.                                                         {und aktivieren}
  15584.       LfdPtr^.Draw;
  15585.       Modal:=PWindow(LfdPtr)^.WinModal;     {Modalitätszustand auslesen}
  15586.       DrawMainMenu;                             {Menüzeile neu zeichnen}
  15587.       WinAnz:=WinCount;
  15588.     end
  15589.  
  15590.  
  15591.  
  15592.  
  15593.  
  15594. Programmierhandbuch                                 WG-Vision - 298 -
  15595.  
  15596.  
  15597.  
  15598.  
  15599.  
  15600.  
  15601.  
  15602. WinAnz=WinCount. Eventhandler des letzten Fensters aufrufen und
  15603. abarbeiten
  15604.  
  15605.     else
  15606.     if (WinAnz>0) then
  15607.      if not Modal then
  15608.       begin
  15609.         LfdPtr:=WinList^.Last;    {Pointer auf das letzte Listenelement}
  15610.         LfdPtr^.HandleEvent;                  {Fenster-Handler aufrufen}
  15611.       end
  15612.      else
  15613.       if not SAktiv then                   {kein Untermenü aufgeblendet}
  15614.        begin
  15615.          LfdPtr:=WinList^.Last;
  15616.          LfdPtr^.HandleEvent;
  15617.        end;
  15618.  
  15619. Wenn der Eventhandler des aktiven Fensters das Kommando cmCloseWindow
  15620. sendet, muß das Fenster geschlossen und aus der Window-Liste entfernt
  15621. werden.
  15622.  
  15623.      if Event.Command=cmCloseWindow then      {Fenster aus der WinList}
  15624.                                                             {entfernen}
  15625.       begin
  15626.         LfdPtr:=WinList^.Last;
  15627.         LfdPtr^.Hide;                       {aktives Fenster schließen}
  15628.         WinList^.DelLastItem;             {und aus der Liste entfernen}
  15629.         Dec(WinCount);                        {WinCount dekrementieren}
  15630.  
  15631. Wenn noch Fenster offen sind, muß das jetzt letzte Fenster (Index
  15632. WinCount) aktiviert werden, indem es seinen Rahmen neu zeichnet
  15633. (FrameDeaktivated=false) und seinen Eventhandler in die
  15634. Abarbeitungsschleife einklingt. Auch hier muß die Präsenz eines
  15635. Childfensters beachtet werden.
  15636.  
  15637.  
  15638.  
  15639.  
  15640.  
  15641.  
  15642.  
  15643.  
  15644. Programmierhandbuch                                 WG-Vision - 299 -
  15645.  
  15646.  
  15647.  
  15648.  
  15649.  
  15650.  
  15651.  
  15652.         if WinCount>0 then                      {noch Fenster offnen ?}
  15653.          begin
  15654.            LfdPtr:=WinList^.GetItems(WinCount);    {vorheriges Fenster}
  15655.                                                            {aufblenden}
  15656.            if (TypeOf(LfdPtr^)=TypeOf(TDlgWindow)) and
  15657.                (DlgWindow(LfdPtr)^.ChildPresent) then
  15658.             begin
  15659.               with PDlgWindow(LfdPtr)^ do
  15660.                begin
  15661.                  LfdPtr:=Child^.First;
  15662.                  PWindow(LfdPtr)^.DrawNewFrame;
  15663.                end;
  15664.             end
  15665.            else
  15666.             begin
  15667.              if PDlgWindow(LfdPtr)^.ChildPresent then
  15668.               with PDlgWindow(LfdPtr)^ do
  15669.                begin
  15670.                  LfdPtr:=Child^.First;
  15671.                  PWindow(LfdPtr)^.DrawNewFrame;
  15672.                end
  15673.               else
  15674.                PWindow(LfdPtr)^.DrawNewFrame;
  15675.             end;
  15676.            Modal:=PWindow(LfdPtr)^.WinModal;
  15677.            WinAnz:=WinCount;
  15678.          end
  15679.         else
  15680.          begin
  15681.            WinAnz:=0;                {keine Fenster mehr da. Liste leer}
  15682.            Modal:=true;
  15683.          end;
  15684.         DrawMainMenu;     {Je nach Modalitätszustand Hauptmenüzeile neu}
  15685.                                                             {darstellen}
  15686.         Event.Command:=cmNothing;                  {Kommando rücksetzen}
  15687.       end;
  15688.  
  15689.  
  15690.  
  15691.  
  15692.  
  15693.  
  15694. Programmierhandbuch                                 WG-Vision - 300 -
  15695.  
  15696.  
  15697.  
  15698.  
  15699.  
  15700.  
  15701.  
  15702. Wird mit der Maus die Größe eines Fensters oder seine Position
  15703. verändert, dann sendet das Rahmenobjekt das Kommando cmWindowNewSize.
  15704. Als Reaktion darauf wird das letzte Element der Fensterliste mit den
  15705. neuen Maßen bzw. der neuen Rahmenposition neu aufgeblendet.
  15706.  
  15707.      if Event.Command=cmWindowNewSize then   {Größe des aktives Fenster}
  15708.                                                                 {ändern}
  15709.       begin
  15710.         LfdPtr:=WinList^.Last;
  15711.         LfdPtr^.NewItemList;
  15712.         LfdPtr^.Draw;
  15713.         Event.Command:=cmNothing;                  {Kommando rücksetzen}
  15714.       end;
  15715.  
  15716. Wenn sich mehrere modale Fenster auf dem Bildschirm befinden, kann man
  15717. durch Anklicken eines deaktivierten Fensters dieses Fenster zum aktiven
  15718. Fenster machen. Technisch wird das wie folgt realisiert: Über die Maus-
  15719. position zum Zeitpunkt des Anklickens wird der Index Focus dieses Fen-
  15720. sters in der Window-Liste bestimmt. Anschließend wird dieses Element
  15721. ausgekettet und gegen das letzte Element der Liste ausgetauscht. Das zu-
  15722. letzt aktive Fenster wird an die Position des selektierten Fensters ein-
  15723. gebaut und das selektierte Fenster wird auf die letzte (also aktive)
  15724. Position der Fensterliste gesetzt. Danach werden die Draw-Methoden aller
  15725. Fenster von hinten nach vorn bis zur Position Focus abgearbeitet (wegen
  15726. möglicher Überlappungen).
  15727.  
  15728.      if Modal and (Event.Command=cmSelectWindow) then          {Fenster}
  15729.                                                            {selektieren}
  15730.       begin
  15731.         Focus:=SelectWindow;  {bestimmt Index des selektierten Fensters}
  15732.  
  15733. Die Iconbar ist nichts anderes als ein Dialogfenster an der Position
  15734. FIRST der Fensterliste !
  15735.  
  15736.         if IconBarPresent then ff:=1 else ff:=0;
  15737.  
  15738.         if Focus>ff then
  15739.          begin
  15740.  
  15741.  
  15742.  
  15743.  
  15744. Programmierhandbuch                                 WG-Vision - 301 -
  15745.  
  15746.  
  15747.  
  15748.  
  15749.  
  15750.  
  15751.  
  15752. Alle Fenster von AnzElem bis zur Position Focus löschen.
  15753.  
  15754.            for i:=WinList^.AnzElem downto Focus do
  15755.             begin
  15756.               LfdPtr:=WinList^.GetItems(I);
  15757.               LfdPtr^.Hide;
  15758.             end;
  15759.  
  15760. Fenster tauschen.
  15761.  
  15762.            WinList^.SwapItems(Focus);
  15763.  
  15764. Alle Fenster von Focus bis AnzElem neu zeichnen.
  15765.  
  15766.            for i:=Focus to WinList^.AnzElem do
  15767.             begin
  15768.               LfdPtr:=WinList^.GetItems(I);
  15769.  
  15770. Außer dem letzten Fenster müssen alle Fenster mit deaktivierten Rahmen
  15771. gezeichnet werden
  15772.  
  15773.               if i<>WinList^.AnzElem then FrameDeaktivated:=true;
  15774.               LfdPtr^.Draw;
  15775.               Modal:=PWindow(LfdPtr)^.WinModal;
  15776.               DrawMainMenu;
  15777.             end;
  15778.          end;
  15779.         Focus:=0;
  15780.       end;
  15781.  end;
  15782.  
  15783. Beim Anklicken des Systemmenüs Applikation schließen.
  15784.  
  15785.  if Modal then
  15786.   if SWButton.Contains(Mouse.Position) and Mouse.LButtonKlick then
  15787.    Event.Command:=cmCloseApplication;
  15788.  
  15789. ... und hier noch das Aufblenden einer Messagebox bei der Präsenz eines
  15790. modul-internen Fehlers.
  15791.  
  15792.  
  15793.  
  15794. Programmierhandbuch                                 WG-Vision - 302 -
  15795.  
  15796.  
  15797.  
  15798.  
  15799.  
  15800.  
  15801.  
  15802.   if Event.Message=msgError then
  15803.    begin
  15804.      ErrorMessage(Fehler,z1,z2,BoxTyp);
  15805.      MessageBox(BoxTyp,z1,z2);
  15806.      Event.Message:=msgNothing;
  15807.    end;
  15808. ...
  15809.  
  15810. An diesem wirklich nicht einfach zu verstehenden Programm-
  15811. fragment erkennen Sie deutlich die Vorgehensweise, wenn man
  15812. auf ein Listenelement zugreifen möchte:
  15813.  
  15814. 1. LfdPtr ein Listenelement über den Index zuordnen :
  15815.  
  15816.    LfdPtr:=WinList^.GetItems(Index);
  15817.  
  15818. 2. Methoden (eventuell über Typecast) aufrufen
  15819.  
  15820.    LfdPtr^.Draw;
  15821.  
  15822. In der prinzipiell gleichen Weise wie die Fensterliste wer-
  15823. den auch die Dialogelemente in einen Dialogfenster verwal-
  15824. tet. Auch dort erfolgt der Zugriff in den meisten Fällen
  15825. über einen LfdPtr vom Typ PGroup und den Positionsindex.
  15826.  
  15827. 7.2.3. Speicherobjekte
  15828.  
  15829. Speicherobjekte dienen modulintern der Speicherung von
  15830. rechteckigen Bildschirmausschnitten (Fensteruntergrund) in
  15831. Swapdateien bzw. in den Expanded Memory. Außerdem können Sie
  15832. verwendet werden, um zur Laufzeit den Heap, die Festplatte
  15833. und den EMS zu überwachen.
  15834. WViews stellt folgende Speicherobjekte zur Verfügung:
  15835.  
  15836. TMemory ─ THardDisk
  15837.           TEMS
  15838.           THeap
  15839.  
  15840.  
  15841.  
  15842.  
  15843.  
  15844. Programmierhandbuch                                 WG-Vision - 303 -
  15845.  
  15846.  
  15847.  
  15848.  
  15849.  
  15850.  
  15851.  
  15852. Im Feld FreeMemory wird der jeweils verfügbare Speicher
  15853. abgelegt. Ein kommentiertes Listing von TEMS finden Sie im
  15854. Abschnitt "Expansionsspeicher".
  15855.  
  15856. 7.2.4. Das Rahmenobjekt
  15857.  
  15858. TFrame ist mit einer gehörigen Portion "Eigenintelligenz"
  15859. ausgestattet worden. Sein Eventhandler kann z.B. auf Tasta-
  15860. tur- und Mausereignisse reagieren. Bei einem skalierbaren
  15861. Fenster ändert sich z.B. die Form des Mauszeigers bei Berüh-
  15862. rung des Rahmens mit der Maus. Die Gestalt des Mauszeigers
  15863. zeigt an, wie die Form des Fensters im Dragmode verändert
  15864. werden kann. Auch beim Anklicken des Panels und Verschieben
  15865. der Maus mit gedrückter linker Maustaste verändert sich die
  15866. Gestalt des Mauskursors. Außerdem wird ein Drag-Rahmen auf-
  15867. geblendet, welche die Neupositionierung oder Skalierung ei-
  15868. nes Fensters vereinfacht.
  15869. Auch das Systemmenü eines Fensters gehört eigentlich zu des-
  15870. sen Rahmen. Es kann sowohl mit der Maus als auch über die
  15871. Tastatur (<ESC>, Kursortasten) bedient werden.
  15872. Die für den Programmierer wichtigsten Felder von TFrame
  15873. sind:
  15874.  
  15875. FTyp
  15876. FTyp:byte;
  15877. Rahmentyp. FTyp ergibt sich aus der Summe folgender Konstan-
  15878. ten, die beliebig (d.h. soweit sinnvoll) kombiniert sein
  15879. können: winDouble, winSingle, winPanel, winMenu und winKey.
  15880. FTyp bestimmt das Aussehen und die Eigenschaften eines Rah-
  15881. mens.
  15882.  
  15883. Header
  15884. Header:TText;
  15885. Paneltext. Der Variablentyp TText stellt sicher, daß der
  15886. Text auch bei skalierbaren Fenstern immer richtig positio-
  15887. niert und gegebenenfalls abgeschnitten wird.
  15888.  
  15889.  
  15890.  
  15891.  
  15892.  
  15893.  
  15894. Programmierhandbuch                                 WG-Vision - 304 -
  15895.  
  15896.  
  15897.  
  15898.  
  15899.  
  15900.  
  15901.  
  15902. Area
  15903. Area:TRect;
  15904. Koordinaten des Bereichs innerhalb des Rahmens (Clientbe-
  15905. reich). Diesen Wert verwenden die Hintergrundobjekte, um
  15906. sich in ihrer Größe dem Rahmen anzupassen.
  15907.  
  15908. ZoomRect
  15909. ZoomRect:TRect;
  15910. In dieser Variablen wird die Originalgröße und die Original-
  15911. position eines skalierbaren Fensters gespeichert.
  15912.  
  15913. DragMode
  15914. DragMode:byte;
  15915. Bestimmt das Verhalten des Fensters bei Veränderungen.
  15916. DragMode kann folgende Werte annehmen:
  15917.  
  15918. dmNoMove  = 0   Rahmen darf nicht bewegt weren
  15919. dmMove    = 1   Rahmen darf verschoben werden
  15920. dmGrow    = 2   Rahmen darf seine Größe und Position ändern
  15921. dmNoGrow  = 3   Rahmen darf seine Größe nicht ändern
  15922.  
  15923.  
  15924.  
  15925.  
  15926.  
  15927.  
  15928.  
  15929.  
  15930.  
  15931.  
  15932.  
  15933.  
  15934.  
  15935.  
  15936.  
  15937.  
  15938.  
  15939.  
  15940.  
  15941.  
  15942.  
  15943.  
  15944. Programmierhandbuch                                 WG-Vision - 305 -
  15945.  
  15946.  
  15947.  
  15948.  
  15949.  
  15950.  
  15951.  
  15952. 7.3. Unit WDLG.PAS
  15953.  
  15954. 7.3.1. Das Standard-Fenster - TWindow
  15955.  
  15956. Alle Fensterobjekte leiten sich von TWindow ab. Dieses Ob-
  15957. jekt stellt ein komplettes Fenster zur Verfügung, von dem
  15958. der Anwendungsprogrammierer seine eigenen Fenster ableiten
  15959. muß.
  15960.  
  15961. Felder
  15962.  
  15963. List
  15964. List:PGroup;
  15965. Liste der Fensterelemente. Ein WG-Vision-Fenster besteht in
  15966. der Reihenfolge der Implementation aus folgenden Bestandtei-
  15967. le: Untergrund, Rahmen und Hintergrund (eventuell Rollbalken
  15968. und Scroller).
  15969.  
  15970. Undergrd
  15971. Undergrd:PMemory;
  15972. Zeiger auf das Speicherobjekt, welches den Fensteruntergrund
  15973. gespeichert hat (Swapdatei oder EMS).
  15974.  
  15975. Frame
  15976. Frame:PFrame;
  15977. Zeiger auf das Rahmenobjekt.
  15978.  
  15979. Bgrd
  15980. Bgrd:PBackground;
  15981. Zeiger auf das Hintergrundobjekt.
  15982.  
  15983. SBH,SBV
  15984. SBH,SBV:PScrollBar;
  15985. Zeiger auf die Rollbalken.
  15986.  
  15987. ZoomRect
  15988. ZoomRect:TRect;
  15989. Original-Fenstergröße und Position.
  15990.  
  15991.  
  15992.  
  15993.  
  15994. Programmierhandbuch                                 WG-Vision - 306 -
  15995.  
  15996.  
  15997.  
  15998.  
  15999.  
  16000.  
  16001.  
  16002. Title
  16003. Title:str80;
  16004. Paneltext des Fensters.
  16005.  
  16006. Typ
  16007. Typ:byte;
  16008. Rahmentyp des Fensters.
  16009.  
  16010. WinModal
  16011. WinModal:boolean;
  16012. Fenster nicht-Modal ?
  16013.  
  16014. Methoden  (Auswahl)
  16015.  
  16016. Init
  16017. constructor Init(var Bounds:TRect;ATitle:str80;AType:byte);
  16018. Initialisiert ein Fenster mit der Größe Bounds und den Rah-
  16019. mentyp AType.
  16020.  
  16021. Done
  16022. destructor Done; virtual;
  16023. Entfernt die Fenster-Elemente vom Heap.
  16024.  
  16025. SetWindowAttrib
  16026. SetWindowAttrib(Modal:boolean);
  16027. Legt die modalen Eigenschaften eines Fensters fest.
  16028.  
  16029. SetPalette
  16030. procedure SetPalette; virtual;
  16031. Fensterpalette einstellen. Diese Methode kann in einem
  16032. konkreten Anwendungsfall überschrieben werden.
  16033.  
  16034. InitUnderGround, InitFrame, InitBackground,
  16035. InitWindowScroller
  16036. Diese virtuellen Methoden fügen Fensterelemente in List ein.
  16037. Sie können bei Bedarf überschrieben werden.
  16038.  
  16039.  
  16040.  
  16041.  
  16042.  
  16043.  
  16044. Programmierhandbuch                                 WG-Vision - 307 -
  16045.  
  16046.  
  16047.  
  16048.  
  16049.  
  16050.  
  16051.  
  16052. Draw
  16053. procedure Draw; virtual;
  16054. Zeichnet das komplette Fenster auf den Bildschirm.
  16055.  
  16056. DrawClientArea
  16057. procedure DrawClientArea; virtual;
  16058. Leere Methode. Muß im Anwendungsfall überschrieben werden.
  16059. Mit dieser Methode kann der Fensteruntergrund zur Laufzeit
  16060. ohne Manipulation und Neuzeichnen des Hintergrundobjekts
  16061. verändert werden.
  16062.  
  16063. Hide
  16064. procedure Hide; virtual;
  16065. Entfernt das Fenster vom Bildschirm.
  16066.  
  16067. DrawNewFrame
  16068. procedure DrawNewFrame; virtual;
  16069. Zeichnet den Rahmen des Fensters neu.
  16070.  
  16071. HandleEvent
  16072. procedure HandleEvent; virtual;
  16073. Eventhandler des Fensters
  16074.  
  16075.  
  16076.  
  16077.  
  16078.  
  16079.  
  16080.  
  16081.  
  16082.  
  16083.  
  16084.  
  16085.  
  16086.  
  16087.  
  16088.  
  16089.  
  16090.  
  16091.  
  16092.  
  16093.  
  16094. Programmierhandbuch                                 WG-Vision - 308 -
  16095.  
  16096.  
  16097.  
  16098.  
  16099.  
  16100.  
  16101.  
  16102. 7.3.2. Dialogfenster - TDlgWindow
  16103.  
  16104. Dialogfenster leiten sich direkt von TWindow ab und erben
  16105. von ihm alle wichtigen Eigenschaften. Dialogfenster sind im-
  16106. mer modal und nicht skalierbar (läßt sich aber eventuell
  16107. durch Neusetzen von TFrame^.DragMode ändern).
  16108. Sie können eine beliebige Anzahl von aktiven und passiven
  16109. Dialogelementen enthalten, die sie in der Liste DlgList ver-
  16110. walten. Außerdem lassen sich Dialogfenster mit beliebig vie-
  16111. len Child-Fenster ausstatten, wobei jedoch immer nur eins
  16112. aktiv sein darf.
  16113.  
  16114. Felder
  16115.  
  16116. R
  16117. R:TRect;
  16118. Enthält die Größe und Position des Dialogfensters.
  16119.  
  16120. DlgElemente
  16121. DlgElemente:string;
  16122. Diese Zeichenkette enthält die Buchstabencodes aller instal-
  16123. lierten Dialogelemente in der Reihenfolge ihrer Implementa-
  16124. tion (entspricht der Variablen Schalter im Dialogrecord).
  16125.  
  16126. DlgList
  16127. DlgList:PGroup;
  16128. Doppelt verkettete Liste aller im Fenster implementierten
  16129. Dialogelemente.
  16130.  
  16131. Child
  16132. Child:PGroup;
  16133. Enthält einen Zeiger auf das gerade aktive Childfenster. Im
  16134. Normalfall ist Child^.First=nil.
  16135.  
  16136. FocElem
  16137. FocElem:byte;
  16138. Index des gerade fokussierten Dialogelements in der Liste
  16139. DlgList.
  16140.  
  16141.  
  16142.  
  16143.  
  16144. Programmierhandbuch                                 WG-Vision - 309 -
  16145.  
  16146.  
  16147.  
  16148.  
  16149.  
  16150.  
  16151.  
  16152. ChildPresent
  16153. ChildPresent:boolean;
  16154. Wird auf true gesetzt, wenn ein Childfenster aufgeblendet
  16155. ist.
  16156.  
  16157. Methoden  (Auswahl)
  16158.  
  16159. DrawMask
  16160. procedure DrawMask; virtual;
  16161. Zeichnet eine Eingabemaske aus TInputLine-Objekten neu auf
  16162. den Bildschirm.
  16163.  
  16164. InsertChildWindow
  16165. procedure InsertChildWindow(Item:PGroup);
  16166. Fügt ein Child-Fenster in das Dialogfenster ein.
  16167.  
  16168. SetPushButton
  16169. procedure SetPushButton(x,y,xl,yl:integer;
  16170.                         Bez:str25;Kommando:word);
  16171. Drucktaste in die Dialogliste einfügen.
  16172.  
  16173. SetRadioButton
  16174. procedure SetRadioButton(x,y:integer;
  16175.                          Bez:str25;FGruppe:byte);
  16176. Fügt ein Radiobutton der Gruppe FGruppe in die Dialogliste
  16177. des Dialogfensters ein.
  16178.  
  16179. SetCheckButton
  16180. procedure SetCheckButton(x,y:integer;Bez:str25);
  16181. Fügt ein Checkbutton in die Dialogliste des Dialogfensters
  16182. ein.
  16183.  
  16184. SetInputLine
  16185. procedure SetInputLine(x,y,xl:integer;
  16186.                        Bez:str25;MaxLen:byte;Zeich:ZMenge);
  16187. Mit dieser Methode stellen Sie dem Dialogfenster eine frei
  16188. editierbare Eingabezeile für Strings zur Verfügung.
  16189.  
  16190.  
  16191.  
  16192.  
  16193.  
  16194. Programmierhandbuch                                 WG-Vision - 310 -
  16195.  
  16196.  
  16197.  
  16198.  
  16199.  
  16200.  
  16201.  
  16202. SetNumButton
  16203. procedure SetNumButton(x,y,xl:integer;Bez:str25;
  16204.                  MaxLen,TTyp:byte,Min.Max,Step,Format:real);
  16205. Implementierung eines Zählschalters in das Dialogfenster.
  16206.  
  16207. SetListBox
  16208. procedure SetListBox(x,y,xl,yl:integer;Bez:str25;
  16209.                      LScroller:word); virtual;
  16210. Diese virtuelle Methode muß im Anwendungsfall überschrieben
  16211. werden. Sie implementiert eine Listbox in ein Dialogfenster.
  16212.  
  16213. SetGroupFrame
  16214. procedure SetGroupFrame(x,y,xl,yl:integer;Bez:str25;
  16215.                         FrameTyp:word);
  16216. Gruppenfenster mit dem Rahmentyp FrameTyp in ein Dialogfen-
  16217. ster einfügen.
  16218.  
  16219. SetIcon
  16220. procedure SetIcon(x,y:integer;Bez:str25);
  16221. Icon aus der Ressourcendatei mit dem Dateinamen Bez an die
  16222. Position x,y des Dialogfensters einfügen.
  16223.  
  16224. SetStaticText
  16225. procedure SetStaticText(x,y:integer;Bez:string;RelPos:byte);
  16226. Statischen Text in ein Dialogfenster schreiben.
  16227.  
  16228. SetTextPosition
  16229. procedure SetTextPosition(x,y:integer);
  16230. Position des Bezeichners des zuletzt implementierten Dialog-
  16231. elementes verändern.
  16232.  
  16233. ChangePalColor
  16234. procedure ChangePalColor(Eintrag,Color:byte);
  16235. Palettteneintrag des zuletzt implementierten Dialogelements
  16236. verändern.
  16237.  
  16238. SetTextParameters
  16239. procedure SetTextParameters(Fnt,Direct:word;CharSz:byte);
  16240. Textparameter eines statischen Textes ändern.
  16241.  
  16242.  
  16243.  
  16244. Programmierhandbuch                                 WG-Vision - 311 -
  16245.  
  16246.  
  16247.  
  16248.  
  16249.  
  16250.  
  16251.  
  16252. SetDisabled
  16253. procedure SetDisabled;
  16254. Das zuletzt implementierte Dialogelement wird deaktiviert.
  16255.  
  16256. GetFocElem
  16257. function GetFocElem:word;
  16258. Übergibt den Index des gerade fokussierten Elements in der
  16259. Dialogelementeliste
  16260.  
  16261. 7.3.2.1. Dialogelemente
  16262.  
  16263. Hierarchie der Dialogelemente von WG-Vision
  16264.  
  16265. TGroup ─ TButton ─ TPushButton
  16266.                    TRadioButton ─ TCheckButton
  16267.                    TInputLine   ─ TNumButton
  16268.                    TScroller    ─ TListBox
  16269.                    TGroupFrame
  16270.                    TIcon
  16271.                    TStaticText
  16272.  
  16273. Alle Dialogelemente leiten sich von TButton ab. In diesem
  16274. Objekt werden folgende Werte gespeichert (Auswahl):
  16275.  
  16276. TextPos
  16277. TextPos:TRect;
  16278. Rechteckiger Bereich des Bildschirms, in dem der Bezeichner
  16279. positioniert ist.
  16280.  
  16281. dx,dy
  16282. dx,dy:integer;
  16283. Textposition relativ zum Button.
  16284.  
  16285. ShortCut
  16286. ShortCut:char;
  16287. Buchstabe, über den das Dialogelement fokussiert werden
  16288. kann.
  16289.  
  16290.  
  16291.  
  16292.  
  16293.  
  16294. Programmierhandbuch                                 WG-Vision - 312 -
  16295.  
  16296.  
  16297.  
  16298.  
  16299.  
  16300.  
  16301.  
  16302. Focus
  16303. Focus:boolean;
  16304. Focus ist immer dann true, wenn das Dialogelement fokussiert
  16305. ist.
  16306.  
  16307. Enabled
  16308. Enabled:boolean;
  16309. Dialogelement aktiviert (true) oder deaktiviert (false).
  16310.  
  16311.  
  16312.  
  16313.  
  16314.  
  16315.  
  16316.  
  16317.  
  16318.  
  16319.  
  16320.  
  16321.  
  16322.  
  16323.  
  16324.  
  16325.  
  16326.  
  16327.  
  16328.  
  16329.  
  16330.  
  16331.  
  16332.  
  16333.  
  16334.  
  16335.  
  16336.  
  16337.  
  16338.  
  16339.  
  16340.  
  16341.  
  16342.  
  16343.  
  16344. Programmierhandbuch                                 WG-Vision - 313 -
  16345.  
  16346.  
  16347.  
  16348.  
  16349.  
  16350.  
  16351.  
  16352. 8. WG-Vision und der Coprozessor
  16353.  
  16354. Alle Units von WG-Vision unterstützen prinzipiell einen
  16355. arithmetischen Coprozessor. Ist kein Coprozessor vorhanden,
  16356. muß mit {$E+} der Emulator eingebunden werden. Das ge-
  16357. schieht, indem Sie diese Compilerdirektive oberhalb des
  16358. Schlüsselworts program in Ihr Hauptprogramm einfügen.
  16359. In WG-Vision wurde aus diesem Grund der Datentyp real durch-
  16360. gängig durch den Datentyp single ersetzt.
  16361.  
  16362. 8.1. Erweiterte Funktionen des Coprozessors
  16363.  
  16364. Es ist ein offenes Geheimnis, daß Turbo-Pascal den Coprozes-
  16365. sor mehr schlecht als recht auslastet. Besonders bedauerlich
  16366. ist es, daß die Erweiterungen, welche ab dem 80387 verfügbar
  16367. sind, vom Pascal-Compiler völlig ignoriert werden. Das be-
  16368. trifft fast alle "fest verdrahteten" Funktionsaufrufe wie
  16369. Sinus, Cosinus oder Arcustangens. Wenn diese Funktionen di-
  16370. rekt angesprochen werden, erhält man durchschnittlich eine
  16371. weitere Geschwindigkeitssteigerung um den Faktor 3. Damit
  16372. Sie diese Kapazitäten in Ihren Programmen nutzen können,
  16373. wurde die Unit WCProc entwickelt. Sie stellt Ihnen folgende
  16374. Funktionen zur Verfügung:
  16375.  
  16376. function wgSin(x:extended):extended;   Sinus
  16377. function wgCos(x:extended):extended;   Cosinus
  16378. function wgTan(x:extended):extended;   Tangens
  16379. function wgCot(x:extended):extended;   Cotangens
  16380. function wgAtn(x:extended):extended;   Arcus Tangens
  16381. function wgAsn(x:extended):extended;   Arcus Sinus
  16382. function wgAcs(x:extended):extended;   Arcus Cosinus
  16383. function wgExp(x:extended):extended;   Exponentialfunktion
  16384. function wgPow(x,n:extended):extended; Potenzfunktion
  16385. function wgLn(x:extended):extended;    Logarithmus naturalis
  16386. function wgLog10(x:extended):extended; Dekad. Logarithmus
  16387.  
  16388. Diese Funktionen werden direkt vom Coprozessor zur Verfügung
  16389. gestellt (ab 80387).
  16390.  
  16391.  
  16392.  
  16393.  
  16394. Programmierhandbuch                                 WG-Vision - 314 -
  16395.  
  16396.  
  16397.  
  16398.  
  16399.  
  16400.  
  16401.  
  16402. Wenn Sie diese Unit neu kompilieren  möchten, muß das
  16403. Objektmodul FMATH.OBJ für den Compiler ereichbar sein.
  16404.  
  16405. Folgendes kleine Testprogramm wurde auf einem 33 MHz 386'er
  16406. AT mit ITT-Coprozessor abgearbeitet. Die Abarbeitungszeiten
  16407. wurden mit dem Turbo-Profiler ermittelt:
  16408.  
  16409. ...
  16410. for i:=1 to 3600 do x:=ln(Pi/4);      {bzw x:=wgln(Pi/4)}
  16411. for i:=1 to 3600 do x:=sin(Pi/4);     {bzw x:=wgsin(Pi/4)}
  16412. for i:=1 to 3600 do x:=cos(Pi/4);     {bzw x:=wgcos(Pi/4)}
  16413. for i:=1 to 3600 do x:=exp(Pi/4);     {bzw x:=wgexp(Pi/4)}
  16414. ...
  16415.  
  16416. 3.9106 sec ohne Coprozessor
  16417. 0.6778 sec mit Coprozessor
  16418. 0.1290 sec mit der Unit WCProc und Coprozessor
  16419.  
  16420.  
  16421.  
  16422.  
  16423.  
  16424.  
  16425.  
  16426.  
  16427.  
  16428.  
  16429.  
  16430.  
  16431.  
  16432.  
  16433.  
  16434.  
  16435.  
  16436.  
  16437.  
  16438.  
  16439.  
  16440.  
  16441.  
  16442.  
  16443.  
  16444. Programmierhandbuch                                 WG-Vision - 315 -
  16445.  
  16446.  
  16447.  
  16448.  
  16449.  
  16450.  
  16451.  
  16452. 9. Verwendung von Overlays
  16453.  
  16454. Zur effektiven Nutzung des verfügbaren Speichers ist die
  16455. Verwendung von Overlays angebracht. Da die Toolbox selbst
  16456. einen nicht unbeträchtlichen Teil des Hauptspeichers belegt,
  16457. sollte bei der Entwicklung eines Anwendungsprogramms
  16458. Funktionseinheiten konsequent in Units abgelegt werden, die
  16459. sich als Overlays deklarieren lassen. Auf diese Weise können
  16460. Sie mit Pascal mit ein wenig Überlegung und Planung sehr
  16461. große und komplexe Programme entwickeln. Folgendes
  16462. Programmfragment zeigt, wie ein WG-Vision-Programm aussieht,
  16463. wenn es von Overlays gebrauch macht:
  16464.  
  16465. {$I OVERLAY.INC}
  16466. program SBG;
  16467.  
  16468. USES Overlay,     {muß an der ersten Position stehen !}
  16469.      WDecl,
  16470.      SBGDecl,
  16471.      WEMS,
  16472.      WDriver,
  16473.      WApp,
  16474.      WEvent,
  16475.      WViews,
  16476.      WDlg,
  16477.      WUtils,
  16478.      W256PCX,
  16479.      WFileDlg,
  16480.      SBGDlg,
  16481.      SBGIm,
  16482.      WCalc,
  16483.      WPalette,
  16484.      SBGPrint,
  16485.      printer,
  16486.      crt,
  16487.      dos,
  16488.      graph;
  16489.  
  16490.  
  16491.  
  16492.  
  16493.  
  16494. Programmierhandbuch                                 WG-Vision - 316 -
  16495.  
  16496.  
  16497.  
  16498.  
  16499.  
  16500.  
  16501.  
  16502. {$O SBGDlg}        {Overlays}
  16503. {$O SBGIm}
  16504. {$O WUtils}
  16505. {$O WCalc}
  16506. {$O WPalette}
  16507. {$O W256PCX}
  16508.  
  16509. const cmLoad=101;
  16510.       cmSaveAs=102;
  16511.  
  16512.    ...
  16513.  
  16514.    ...
  16515.  
  16516. {Hauptprogramm}
  16517.  
  16518. begin
  16519.   Sprache:=Deutsch;
  16520.   Nummer:=0;
  16521.   OvrInit('SBG.OVR');    {Overlay-Verwaltung initialisieren}
  16522.   if Sprache=Deutsch then MyApp.Init('Astronomische Bildbearbeitung')
  16523.    else MyApp.Init('Astronomical Image Processing');
  16524.   MyApp.Run;
  16525.   MyApp.Done;
  16526. end.
  16527.  
  16528. Prinzipiell kann ein größerer Teil von WG-Vision als
  16529. Overlays verwendet werden. Aufgrund ihrer Verzahnung ist das
  16530. jedoch selten sinnvoll, da die Performance des Programms da-
  16531. durch stark abnimmt. Eigene Objekte, wie im obigen Beispiel
  16532. praktiziert, sollten dagegen in Overlay-Dateien verpackt
  16533. werden, besonders, wenn sie eine funktionelle Einheit bil-
  16534. den.
  16535. Weitere Einzelheiten zur Overlayverwaltung unter Turbo-
  16536. Pascal finden Sie in den Handbüchern der Programmiersprache.
  16537.  
  16538.  
  16539.  
  16540.  
  16541.  
  16542.  
  16543.  
  16544. Programmierhandbuch                                 WG-Vision - 317 -
  16545.  
  16546.  
  16547.  
  16548.  
  16549.  
  16550.  
  16551.  
  16552. Folgende Units von WG-Vision können als Overlays verwendet
  16553. werden:
  16554.  
  16555. WPCX
  16556. W256PCX
  16557. WCALC
  16558. WERROR
  16559. WFONT
  16560. WHELP
  16561. WICNEDIT
  16562. WPALETTE
  16563. WUHR
  16564. WUTILS
  16565.  
  16566.  
  16567.  
  16568.  
  16569.  
  16570.  
  16571.  
  16572.  
  16573.  
  16574.  
  16575.  
  16576.  
  16577.  
  16578.  
  16579.  
  16580.  
  16581.  
  16582.  
  16583.  
  16584.  
  16585.  
  16586.  
  16587.  
  16588.  
  16589.  
  16590.  
  16591.  
  16592.  
  16593.  
  16594. Programmierhandbuch                                 WG-Vision - 318 -
  16595.  
  16596.  
  16597.  
  16598.  
  16599.  
  16600.  
  16601.  
  16602. 10. Tips und Tricks
  16603.  
  16604. 10.1. Wir basteln uns einen Screensaver
  16605.  
  16606. Wenn Sie den Norton-Commander eine zeitlang sich selbst
  16607. überlassen haben, schaltet er seinen Screensaver ein. Wir
  16608. wollen jetzt in der gleichen Weise unsere WG-Vision-Program-
  16609. me mit einem solchen Screensaver ausstatten. Wie Sie gleich
  16610. sehen werden, ist das ganz einfach. Als Pausenbild wollen
  16611. wir die Grafik-Animation verwenden, die in Form des Bei-
  16612. spielprogramms ARTY.PAS den älteren Turbo-Pascal-Versionen
  16613. beigelegt worden sind (z.B. Turbo-Pascal 5.5). Aus diesem
  16614. Programm entfernen wir alle unnötigen Routinen und wandeln
  16615. es in eine Unit um, die als einzige Prozedur DoArt nach
  16616. außen übergibt. Es ist empfehlenswert, diese Unit in einem
  16617. konkreten Anwendungsfall als Overlay zu kompilieren. Sie
  16618. können übrigens in der gleichen Art weitere Units erstellen
  16619. oder weitere Prozeduren in der Art von DoArt in die Unit
  16620. ARTY.PAS einbauen, die andere Pausenanimationen aufblenden.
  16621. Vielleicht schauen Sie sich mal zwecks "Ideenfindung" die
  16622. Screensaver von Windows 3.1 an. Wenn Sie jetzt noch ein
  16623. passendes Dialogfenster zur Einstellung des Screensavers
  16624. programmieren (Art der Animation, Wartezeit bis zur
  16625. Aktivierung), dann haben Sie mit Ihrem Programm fast das
  16626. Niveau von Windows erreicht.
  16627.  
  16628.  
  16629.  
  16630.  
  16631.  
  16632.  
  16633.  
  16634.  
  16635.  
  16636.  
  16637.  
  16638.  
  16639.  
  16640.  
  16641.  
  16642.  
  16643.  
  16644. Programmierhandbuch                                 WG-Vision - 319 -
  16645.  
  16646.  
  16647.  
  16648.  
  16649.  
  16650.  
  16651.  
  16652. Hier der Quelltext der Unit ARTY.PAS:
  16653.  
  16654. UNIT ARTY;
  16655.  
  16656. interface
  16657.  
  16658. uses crt,
  16659.      graph;
  16660.  
  16661. procedure DoArt;
  16662.  
  16663. implementation
  16664.  
  16665. type ColorList=array[1..4] of integer;
  16666. var Line:array[1..100] of record
  16667.                             LX1,LY1: integer;
  16668.                             LX2,LY2: integer;
  16669.                             LColor : ColorList;
  16670.                           end;
  16671.     X1,X2,Y1,Y2,CurrentLine,
  16672.     ColorCount,IncrementCount,
  16673.     DeltaX1,DeltaY1,DeltaX2,DeltaY2,
  16674.     i,MaxDelta:integer;
  16675.     Colors:ColorList;
  16676.     ChangeColors:boolean;
  16677.  
  16678. procedure DoArt;
  16679.  
  16680. procedure AdjustX(var X,DeltaX:integer);
  16681. var TestX:integer;
  16682. begin
  16683.   TestX:=X+DeltaX;
  16684.   if (TestX<1) or (TestX>640) then
  16685.    begin
  16686.      TestX:=X;
  16687.      DeltaX:=-DeltaX;
  16688.    end;
  16689.   X:=TestX;
  16690. end;
  16691.  
  16692.  
  16693.  
  16694. Programmierhandbuch                                 WG-Vision - 320 -
  16695.  
  16696.  
  16697.  
  16698.  
  16699.  
  16700.  
  16701.  
  16702. procedure AdjustY(var Y,DeltaY:integer);
  16703. var TestY:integer;
  16704. begin
  16705.   TestY:=Y+DeltaY;
  16706.   if (TestY<1) or (TestY>480) then
  16707.    begin
  16708.      TestY:=Y;
  16709.      DeltaY:=-DeltaY;
  16710.    end;
  16711.   Y:=TestY;
  16712. end;
  16713.  
  16714. procedure SelectNewColors;
  16715. begin
  16716.   if not ChangeColors then Exit;
  16717.   Colors[1]:=Random(16)+1;
  16718.   Colors[2]:=Random(16)+1;
  16719.   Colors[3]:=Random(16)+1;
  16720.   Colors[4]:=Random(16)+1;
  16721.   ColorCount:=3*(1+Random(5));
  16722. end;
  16723.  
  16724. procedure SelectNewDeltaValues;
  16725. begin
  16726.   DeltaX1 := Random(MaxDelta)-(MaxDelta Div 2);
  16727.   DeltaX2 := Random(MaxDelta)-(MaxDelta Div 2);
  16728.   DeltaY1 := Random(MaxDelta)-(MaxDelta Div 2);
  16729.   DeltaY2 := Random(MaxDelta)-(MaxDelta Div 2);
  16730.   IncrementCount := 2*(1+Random(4));
  16731. end;
  16732.  
  16733.  
  16734.  
  16735.  
  16736.  
  16737.  
  16738.  
  16739.  
  16740.  
  16741.  
  16742.  
  16743.  
  16744. Programmierhandbuch                                 WG-Vision - 321 -
  16745.  
  16746.  
  16747.  
  16748.  
  16749.  
  16750.  
  16751.  
  16752. procedure SaveCurrentLine(CurrentColors:ColorList);
  16753. begin
  16754.   with Line[CurrentLine] do
  16755.    begin
  16756.      LX1:=X1; LY1:=Y1;
  16757.      LX2:=X2; LY2:=Y2;
  16758.      LColor:=CurrentColors;
  16759.    end;
  16760. end;
  16761.  
  16762. procedure Draw(x1,y1,x2,y2,color:word);
  16763. begin
  16764.   SetColor(color);
  16765.   graph.line(x1,y1,x2,y2);
  16766. end;
  16767.  
  16768. procedure Updateline;
  16769. begin
  16770.   Inc(CurrentLine);
  16771.   if CurrentLine>100 then CurrentLine:=1;
  16772.   Dec(ColorCount);
  16773.   Dec(IncrementCount);
  16774. end;
  16775.  
  16776. procedure DrawCurrentLine;
  16777. var c1,c2,c3,c4:integer;
  16778. begin
  16779.   c1:=Colors[1];
  16780.   c2:=Colors[2];
  16781.   c3:=Colors[3];
  16782.   c4:=Colors[4];
  16783.   Draw(X1,Y1,X2,Y2,c1);
  16784.   Draw(640-X1,Y1,640-X2,Y2,c2);
  16785.   Draw(X1,480-Y1,X2,480-Y2,c3);
  16786.   Draw(640-X1,480-Y1,640-X2,480-Y2,c4);
  16787.   SaveCurrentLine(Colors);
  16788. end;
  16789.  
  16790.  
  16791.  
  16792.  
  16793.  
  16794. Programmierhandbuch                                 WG-Vision - 322 -
  16795.  
  16796.  
  16797.  
  16798.  
  16799.  
  16800.  
  16801.  
  16802. procedure EraseCurrentLine;
  16803. begin
  16804.   with Line[CurrentLine] do
  16805.    begin
  16806.      Draw(LX1,LY1,LX2,LY2,0);
  16807.      Draw(640-LX1,LY1,640-LX2,LY2,0);
  16808.      Draw(LX1,480-LY1,LX2,480-LY2,0);
  16809.      Draw(640-LX1,480-LY1,640-LX2,480-LY2,0);
  16810.    end;
  16811. end;
  16812.  
  16813. begin
  16814.   CurrentLine:=1; ColorCount:=0; MaxDelta:=16;
  16815.   IncrementCount:=0; ChangeColors:=true;
  16816.   for i := 1 to 100 do
  16817.    with Line[i] do
  16818.     begin
  16819.       LX1:=320; LX2:=320;
  16820.       LY1:=240; LY2:=240;
  16821.     end;
  16822.    X1:=320; X2:=320; Y1:=240; Y2:=240;
  16823.   ClearViewport; SelectNewColors;
  16824.   repeat
  16825.     EraseCurrentLine;
  16826.     if ColorCount=0 then SelectNewColors;
  16827.     if IncrementCount=0 then SelectNewDeltaValues;
  16828.     AdjustX(X1,DeltaX1); AdjustX(X2,DeltaX2);
  16829.     AdjustY(Y1,DeltaY1); AdjustY(Y2,DeltaY2);
  16830.     if Random(5)=3 then
  16831.      begin
  16832.        x1:=(x1+x2) div 2;
  16833.        y2:=(y1+y2) div 2;
  16834.      end;
  16835.     DrawCurrentLine; Updateline;
  16836.   until keypressed;
  16837. end;
  16838.  
  16839. END.
  16840.  
  16841.  
  16842.  
  16843.  
  16844. Programmierhandbuch                                 WG-Vision - 323 -
  16845.  
  16846.  
  16847.  
  16848.  
  16849.  
  16850.  
  16851.  
  16852. Der Screensaver wird in den Eventhandler der Applikation
  16853. eingebaut. Er soll immer dann aktiviert werden, wenn inner-
  16854. halb der Wartezeit Wait (in Sekunden) weder ein Tastatur-
  16855. noch ein Mausereignis stattgefunden hat. Das bedeutet, wir
  16856. müssen immer dann die Zeit stoppen, wenn Event.What<>evNot-
  16857. hing ist und diesen Zeitpunkt als Nullpunkt verwenden (Zero-
  16858. Time). Danach bestimmen wir die Differenz zwischen der
  16859. aktuellen Zeit (wenn das Programm den Eventhandler durch-
  16860. läuft) und ZeroTime und vergleichen Sie mit der Pausenzeit
  16861. Wait. Überschreitet die Zeitdifferenz den Wert von Wait,
  16862. dann wird der Screensaver aufgeblendet:
  16863.  
  16864. procedure ScreenSaver;
  16865. var Stunde,Minute,Sekunde,HSec:word;
  16866. begin
  16867.   GetTime(Stunde,Minute,Sekunde,HSec);
  16868.   if Event.What<>evNothing then ZeroTime:=Stunde*3600+Minute*60+Sekunde
  16869.    else StopTime:=Stunde*3600+Minute*60+Sekunde;
  16870.   if (StopTime-ZeroTime)>Wait then
  16871.    begin
  16872.      Mouse.HideMouse;
  16873.      DoArt;
  16874.      Draw;
  16875.      Mouse.ShowMouse;
  16876.    end;
  16877. end;
  16878.  
  16879. Wait wird entweder fest im Programm festgelegt (z.B. 5 Minu-
  16880. ten=300 Sekunden) oder über einen Dialog individuell einge-
  16881. stellt. ZeroTime, StopTime und Wait werden am besten als
  16882. Feld des Applikationsobjekts deklariert und im Konstruktor
  16883. initialisiert.
  16884.  
  16885.  
  16886.  
  16887.  
  16888.  
  16889.  
  16890.  
  16891.  
  16892.  
  16893.  
  16894. Programmierhandbuch                                 WG-Vision - 324 -
  16895.  
  16896.  
  16897.  
  16898.  
  16899.  
  16900.  
  16901.  
  16902. Der Eventhandler sieht mit dem Screensaver in etwa folgen-
  16903. dermaßen aus:
  16904.  
  16905. procedure TApplication.HandleEvent;
  16906. begin
  16907.   TProgram.HandleEvent;
  16908.   ScreenSaver;
  16909.   case Event.Command of
  16910.   ...
  16911.  
  16912.   end; {case}
  16913. end;
  16914.  
  16915. Hinweis:
  16916. Wenn Sie auf dem Bildschirm Objekte aufgeblendet haben, die
  16917. nicht irgendwie in der Objektliste des Programms enthalten
  16918. sind (z.B. Bildchen, die gerade auf dem Desktophintergrund
  16919. bearbeitet werden und noch nicht abgespeichert sind), dann
  16920. kann die Draw-Methode allein den ursprünglichen Bildschirm-
  16921. Zustand nicht wieder rekonstruieren. In diesem Fall machen
  16922. Sie einfach von folgender Möglichkeit gebrauch. Retten Sie
  16923. bevor Sie DoArt aufrufen den gesamten Bildschirminhalt in
  16924. den EMS oder auf die Festplatte (TEMS, THardDisk). Nach Be-
  16925. endigung von DoArt wird dann der Untergrund einfach wieder-
  16926. hergestellt. In diesem Fall brauchen Sie die Draw-Methode
  16927. von TApplication überhaupt nicht mehr bemühen. Da eventuell
  16928. vorhandene Fenster nicht neu dargestellt werden müssen, ist
  16929. dieser Weg auch bedeutend schneller.
  16930.  
  16931.  
  16932.  
  16933.  
  16934.  
  16935.  
  16936.  
  16937.  
  16938.  
  16939.  
  16940.  
  16941.  
  16942.  
  16943.  
  16944. Programmierhandbuch                                 WG-Vision - 325 -
  16945.  
  16946.  
  16947.  
  16948.  
  16949.  
  16950.  
  16951.  
  16952. WG-VISION 1.0
  16953.  
  16954. INTERFACEDOKUMENTATION DER UNITS
  16955.  
  16956.  
  16957.  
  16958.  
  16959. (*****************************************************
  16960. *                                                    *
  16961. * WG-VISION 1.0    Globale Deklarationen und grund-  *
  16962. *                  legende Objekte (TRect,TPoint)    *
  16963. *                                                    *
  16964. ******************************************************
  16965. *                                                    *
  16966. *                                                    *
  16967. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  16968. *                                                    *
  16969. *****************************************************)
  16970.  
  16971. {$I COMPILER.INC}
  16972.  
  16973. unit WDecl;
  16974.  
  16975. interface
  16976.  
  16977. const {Grafik-Treiber}
  16978.  
  16979.       EGA     =  3;    { 16 Farben}
  16980.       VGA     =  9;    { 16 Farben}
  16981.       IBM8514 =  6;    {256 Farben}
  16982.       VESA    = 11;    {256 Farben}
  16983.  
  16984.       {Grafik-Modi}
  16985.  
  16986.       M640x350  = 1;
  16987.       M640x480  = 2;
  16988.       M800x600  = 3;
  16989.       M1024x768 = 4;
  16990.  
  16991.  
  16992.  
  16993.  
  16994. Programmierhandbuch                                 WG-Vision - 326 -
  16995.  
  16996.  
  16997.  
  16998.  
  16999.  
  17000.  
  17001.  
  17002.       {Summasketch-Digitizer}
  17003.  
  17004.       XON  = ^Q;       {Übertragungsprotokoll}
  17005.       XOFF = ^S;
  17006.  
  17007.       DGRESET   = #0;         {Rücksetzen}
  17008.       SELFTEST  = #116;       {Selbsttest}
  17009.       SENDRES   = #119;       {Senden der Selbsttest-Resultate}
  17010.       SENDCONF  = #97;        {Konfiguration senden}
  17011.       SENDMODEL = #5;         {Model-Identifikationsstring senden}
  17012.  
  17013.       BCD       = #122#97;    {Ausgabe im ASCI-BCD-Format}
  17014.  
  17015.       POINT     = #66;        {Point-Mode einschalten}
  17016.       Stream    = #64;        {Stream-Mode einschalten}
  17017.       SWSTREAM  = #65;        {Switch-Stream-Mode einschalten}
  17018.  
  17019.       {Report-Rate}
  17020.  
  17021.       RR110     = #81;        {Report-Rate 110 rps}
  17022.       RR50      = #82;        {Report-Rate 50 rps}
  17023.       RR10      = #83;        {Report-Rate 10 rps}
  17024.       RR2       = #84;        {Report-Rate 2 rps}
  17025.  
  17026.       {Auflösung}
  17027.  
  17028.       Res1      = #108;       {Auflösung 1 lpi}
  17029.       Res2      = #110;       {Auflösung 2 lpi}
  17030.       Res4      = #112;       {Auflösung 12 lpi}
  17031.       Res100    = #100;       {Auflösung 100 lpi}
  17032.       Res200    = #101;       {Auflösung 200 lpi}
  17033.       Res400    = #103;       {Auflösung 400 lpi}
  17034.       Res500    = #104;       {Auflösung 500 lpi}
  17035.       Res1000   = #106;       {Auflösung 1000 lpi}
  17036.  
  17037.       {Koordinatensystem}
  17038.  
  17039.       ABSOLUT   = #70;        {absolutes Koordinatensystem}
  17040.       RELATIV   = #69;        {relatives Koordinatensystem}
  17041.  
  17042.  
  17043.  
  17044. Programmierhandbuch                                 WG-Vision - 327 -
  17045.  
  17046.  
  17047.  
  17048.  
  17049.  
  17050.  
  17051.  
  17052.       {Fehler}
  17053.  
  17054.       gr     = 1;   {Index für Grafik-Fehler (GraphResult)}
  17055.       ems    = 2;   {Index für EMS-Fehler}
  17056.       joy    = 3;   {Joystick-Fehler}
  17057.       DS     = 4;   {DOS-Fehler}
  17058.       io     = 5;   {Ein-/Ausgabefehler}
  17059.       mst    = 6;   {schwerwiegende Fehler}
  17060.       pr     = 7;   {Drucker-Fehler}
  17061.  
  17062.       {Joystick-Fehler}
  17063.  
  17064.       joyNoGamePortPresent = 1;
  17065.  
  17066.       {VGA/EGA Standardfarben}
  17067.  
  17068.       Black        = 0;
  17069.       Blue         = 1;
  17070.       Green        = 2;
  17071.       Cyan         = 3;
  17072.       Red          = 4;
  17073.       Magenta      = 5;
  17074.       Brown        = 6;
  17075.       LightGray    = 7;
  17076.       DarkGray     = 8;
  17077.       LightBlue    = 9;
  17078.       LightGreen   = 10;
  17079.       LightCyan    = 11;
  17080.       LightRed     = 12;
  17081.       LightMagenta = 13;
  17082.       Yellow       = 14;
  17083.       White        = 15;
  17084.  
  17085.       LeftText     = 0;      {Text-Ausrichtung}
  17086.       CenterText   = 1;
  17087.       RightText    = 2;
  17088.  
  17089.       HorizDir     = 0;
  17090.       VertDir      = 1;
  17091.  
  17092.  
  17093.  
  17094. Programmierhandbuch                                 WG-Vision - 328 -
  17095.  
  17096.  
  17097.  
  17098.  
  17099.  
  17100.  
  17101.  
  17102.       NormWidth    = 1;      {Linien- und Rahmenstärke}
  17103.       ThickWidth   = 3;
  17104.  
  17105.       DefaultFont   = 0;     {Vektorzeichensätze}
  17106.       TriplexFont   = 1;
  17107.       SmallFont     = 2;
  17108.       SansSerifFont = 3;
  17109.       GothicFont    = 4;
  17110.       ScriptFont    = 5;
  17111.       SimpleFont    = 6;
  17112.       TSCRFont      = 7;
  17113.       LCOMFont      = 8;
  17114.       EuroFont      = 9;
  17115.  
  17116.       Deutsch       = 1;
  17117.       Englisch      = 2;
  17118.  
  17119.       winSingle     = 0;
  17120.       winDouble     = 1;
  17121.       winPanel      = 2;
  17122.       winMenu       = 4;
  17123.       winKey        = 8;
  17124.  
  17125.       palStandard   = 1;
  17126.       palRed        = 2;
  17127.       palGray       = 3;
  17128.       palGreen      = 4;
  17129.  
  17130.       VScrBar       = 1;
  17131.       HScrBar       = 2;
  17132.       DScrBar       = 3;
  17133.  
  17134.  
  17135.  
  17136.  
  17137.  
  17138.  
  17139.  
  17140.  
  17141.  
  17142.  
  17143.  
  17144. Programmierhandbuch                                 WG-Vision - 329 -
  17145.  
  17146.  
  17147.  
  17148.  
  17149.  
  17150.  
  17151.  
  17152.       {Ereignisse}
  17153.  
  17154.       evNothing   =  0;        {kein Ereignis}
  17155.       evMouse     =  1;        {Mausereignis}
  17156.       evKeyboard  =  2;        {Keyboard-Ereignis}
  17157.       evMessage   =  3;        {Botschaft oder Befehlsereignis}
  17158.       evCommand   =  4;        {Befehlsereignis}
  17159.       evBroadcast =  5;        {Rundruf-Ereignis}
  17160.  
  17161.       {Infos}
  17162.  
  17163.       infNothing     =  0;     {keine Info}
  17164.       infMenuAktiv   =  1;     {Info "Menü ist aktiv"}
  17165.       infDeaktivated =  2;     {Fenster deaktiviert}
  17166.  
  17167.       {Kommandos}
  17168.  
  17169.       cmNothing          = 0;  {nichts}
  17170.       cmCloseApplication = 1;  {Programm beenden}
  17171.       cmCloseWindow      = 2;  {Fenster schließen}
  17172.       cmWindowNewSize    = 3;  {Fenster hat sich verändert}
  17173.       cmSelectWindow     = 4;  {Fenster selektiert}
  17174.       cmScrollBarChanged = 5;  {Rollbalken verändert}
  17175.       cmExit             = 7;
  17176.       cmOK               = 8;
  17177.       cmCancel           = 9;
  17178.  
  17179.       cmYes              =10;
  17180.       cmNo               =11;
  17181.  
  17182.       cmUp               =12;
  17183.       cmDown             =13;
  17184.  
  17185.       {Mitteilungen}
  17186.  
  17187.       msgNothing  = 0;         {nichts}
  17188.       msgError    = 1;         {Fehler aufgetreten}
  17189.       msgNewMask  = 2;         {neue Eingabemaske}
  17190.  
  17191.  
  17192.  
  17193.  
  17194. Programmierhandbuch                                 WG-Vision - 330 -
  17195.  
  17196.  
  17197.  
  17198.  
  17199.  
  17200.  
  17201.  
  17202.       {Tasten-Codes}
  17203.  
  17204.       kbF1 = 59;      kbF6  = 64;      kbF11 = 133;
  17205.       kbF2 = 60;      kbF7  = 65;      kbF12 = 134;
  17206.       kbF3 = 61;      kbF8  = 66;
  17207.       kbF4 = 62;      kbF9  = 67;
  17208.       kbF5 = 63;      kbF10 = 68;
  17209.  
  17210.       kbArrowLeft  = 75;    kbHome = 71;     CtrlPgUp = 132;
  17211.       kbArrowRight = 77;    kbPgDn = 81;     CtrlPgDn = 118;
  17212.       kbArrowUp    = 72;    kbPgUp = 73;
  17213.       kbArrowDown  = 80;    kbEnd  = 79;
  17214.       kbInsert     = 82;    kbDel  = 83;
  17215.  
  17216.       altA = 30;   altM = 50;    altY = 21;   altF1  = 104;
  17217.       altB = 48;   altN = 49;    altZ = 44;   altF2  = 105;
  17218.       altC = 46;   altO = 24;                 altF3  = 106;
  17219.       altD = 32;   altP = 25;                 altF4  = 107;
  17220.       altE = 18;   altQ = 16;                 altF5  = 108;
  17221.       altF = 33;   altR = 19;                 altF6  = 109;
  17222.       altG = 34;   altS = 31;                 altF7  = 110;
  17223.       altH = 35;   altT = 20;                 altF8  = 111;
  17224.       altI = 23;   altU = 22;                 altF9  = 112;
  17225.       altJ = 36;   altV = 47;                 altF10 = 113;
  17226.       altK = 37;   altW = 17;                 altF11 = 139;
  17227.       altL = 38;   altX = 45;                 altF12 = 140;
  17228.  
  17229.       alt1 = 120;  ShiftF1  =  84;   ShiftF11 = 135;
  17230.       alt2 = 121;  ShiftF2  =  85;   ShiftF12 = 136;
  17231.       alt3 = 122;  ShiftF3  =  86;
  17232.       alt4 = 123;  ShiftF4  =  87;
  17233.       alt5 = 124;  ShiftF5  =  88;
  17234.       alt6 = 125;  ShiftF6  =  89;
  17235.       alt7 = 126;  ShiftF7  =  90;
  17236.       alt8 = 127;  ShiftF8  =  91;
  17237.       alt9 = 128;  ShiftF9  =  92;
  17238.       alt0 = 129;  ShiftF10 =  93;
  17239.  
  17240.  
  17241.  
  17242.  
  17243.  
  17244. Programmierhandbuch                                 WG-Vision - 331 -
  17245.  
  17246.  
  17247.  
  17248.  
  17249.  
  17250.  
  17251.  
  17252.       CtrlA = ^A;  CtrlM = ^M;   CtrlY = ^Y;   CtrlF1  =  94;
  17253.       CtrlB = ^B;  CtrlN = ^N;   CtrlZ = ^Z;   CtrlF2  =  95;
  17254.       CtrlC = ^C;  CtrlO = ^O;                 CtrlF3  =  96;
  17255.       CtrlD = ^D;  CtrlP = ^P;                 CtrlF4  =  97;
  17256.       CtrlE = ^E;  CtrlQ = ^Q;                 CtrlF5  =  98;
  17257.       CtrlF = ^F;  CtrlR = ^R;                 CtrlF6  =  99;
  17258.       CtrlG = ^G;  CtrlS = ^S;                 CtrlF7  = 100;
  17259.       CtrlH = ^H;  CtrlT = ^T;                 CtrlF8  = 101;
  17260.       CtrlI = ^I;  CtrlU = ^U;                 CtrlF9  = 102;
  17261.       CtrlJ = ^J;  CtrlV = ^V;                 CtrlF10 = 103;
  17262.       CtrlK = ^K;  CtrlW = ^W;                 CtrlF11 = 137;
  17263.       CtrlL = ^L;  CtrlX = ^X;                 CtrlF12 = 138;
  17264.  
  17265.       kbShiftTab   = 15;
  17266.  
  17267.       kbEsc   = #27;
  17268.       kbEnter = #13;
  17269.       kbTab   = #9;
  17270.       kbSpace = #32;
  17271.  
  17272.       {Menge der Scancodes aller Tasten, die sich als Shortcuts eignen}
  17273.  
  17274.       SpecialKey = [16..25,30..38,44..50,59..68,84..113,120..129,135..140];
  17275.  
  17276.       {Zahlen, Komma,Vorzeichen}
  17277.  
  17278.       Ziffern    = ['0'..'9','.','-'];
  17279.  
  17280.       {ASCII-Zeichen}
  17281.  
  17282.       ASCII      = [' '..'■'];
  17283.  
  17284.       {Buchstaben}
  17285.  
  17286.       Character   = ['A'..'Z','a'..'z','Ä','Ö','Ü','ä','ö','ü','ß'];
  17287.  
  17288.  
  17289.  
  17290.  
  17291.  
  17292.  
  17293.  
  17294. Programmierhandbuch                                 WG-Vision - 332 -
  17295.  
  17296.  
  17297.  
  17298.  
  17299.  
  17300.  
  17301.  
  17302. type tMinSet=set of 0..15;         {Kleine Zahlenmenge}
  17303.      tError =record
  17304.                FTyp:byte;
  17305.                FNummer:integer;    {Fehler-Code}
  17306.              end;
  17307.  
  17308. var  SVGA   : boolean;    {Super-VGA mit 256 Farben ?}
  17309.      Fehler : tError;     {Container für Fehler}
  17310.  
  17311.      FrameDeaktivated : boolean;   {Rahmen deaktiviert ?}
  17312.      WListPresent     : boolean;   {Window-Liste in Abarbeitung ?}
  17313.      IconBarPresent   : boolean;   {Iconbar vorhanden ?}
  17314.  
  17315. {Objekt-Deklarationen}
  17316.  
  17317. type  {String-Typen}
  17318.  
  17319.       str8  = string[8];
  17320.       str10 = string[10];
  17321.       str12 = string[12];
  17322.       str25 = string[25];
  17323.       str40 = string[40];
  17324.       str80 = string[80];
  17325.  
  17326.       {Punkt}
  17327.  
  17328.       TPoint=object
  17329.        X,Y:integer;
  17330.       end;
  17331.  
  17332.  
  17333.  
  17334.  
  17335.  
  17336.  
  17337.  
  17338.  
  17339.  
  17340.  
  17341.  
  17342.  
  17343.  
  17344. Programmierhandbuch                                 WG-Vision - 333 -
  17345.  
  17346.  
  17347.  
  17348.  
  17349.  
  17350.  
  17351.  
  17352.       {Rechteck-Objekt}
  17353.  
  17354.       TRect=object
  17355.        A,B:TPoint;
  17356.        procedure Assign(XA,YA,XB,YB:integer); {Koordinatenzuweisung}
  17357.        procedure Copy(R:TRect);               {R in A,B kopieren}
  17358.        procedure Get(var R:TRect);            {A,B in R kopieren}
  17359.        procedure Move(ADX,ADY:integer);       {Verschieben}
  17360.        procedure Grow(ADX,ADY:integer);       {Resize, Punkt A bleibt fest}
  17361.        function Contains(P:TPoint):boolean;   {Punkt P innerhalb TRect ?}
  17362.        function Equals(R:TRect):boolean;      {R=TRect ?}
  17363.       end;
  17364.  
  17365.       {Basis-Objekt}
  17366.  
  17367.       PObject = ^TObject;
  17368.       TObject = object
  17369.        constructor Init;
  17370.        destructor Done; virtual;
  17371.       end;
  17372.  
  17373.  
  17374. var  Path_To_SwapFile : str80;
  17375.      Sprache : byte;
  17376.      WorkArea: TRect;    {Arbeitsbereich des Desktop}
  17377.  
  17378.  
  17379. implementation
  17380.  
  17381.  
  17382.  
  17383.  
  17384.  
  17385.  
  17386.  
  17387.  
  17388.  
  17389.  
  17390.  
  17391.  
  17392.  
  17393.  
  17394. Programmierhandbuch                                 WG-Vision - 334 -
  17395.  
  17396.  
  17397.  
  17398.  
  17399.  
  17400.  
  17401.  
  17402. (*****************************************************
  17403. *                                                    *
  17404. * WG-VISION 1.0    Applicationsobjekt                *
  17405. *                                                    *
  17406. ******************************************************
  17407. *                                                    *
  17408. *                                                    *
  17409. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  17410. *                                                    *
  17411. *****************************************************)
  17412.  
  17413. {$I COMPILER.INC}
  17414.  
  17415. unit WApp;
  17416.  
  17417. interface
  17418.  
  17419. uses WDecl,
  17420.      WDriver,
  17421.      WViews,
  17422.      WDlg,
  17423.      WEvent,
  17424.      WUtils,
  17425.      WEMS,
  17426.      WHelp,
  17427.      WError,
  17428.      Graph,
  17429.      Crt;
  17430.  
  17431.  
  17432. type PDsktpBgrd=^TDsktpBgrd;          {Standard-Hintergrund des Desktop}
  17433.      TDsktpBgrd=object(TBackground)
  17434.        procedure Draw; virtual;
  17435.      end;
  17436.  
  17437.  
  17438.  
  17439.  
  17440.  
  17441.  
  17442.  
  17443.  
  17444. Programmierhandbuch                                 WG-Vision - 335 -
  17445.  
  17446.  
  17447.  
  17448.  
  17449.  
  17450.  
  17451.  
  17452.      PProgram=^TProgram;
  17453.      TProgram=object(TGroup)
  17454.        DeskTop : PDeskTop;       {Desktop}
  17455.        MMenu   : PMainMenu;      {Liste der Hauptmenüeintragungen}
  17456.        Heap    : PHeap;          {Heapverwaltung}
  17457.        EMS     : PEMS;           {EMS-Verwaltung}
  17458.        MPos    : integer;
  17459.        MAnzahl : byte;           {Enthält die Anzahl der Hauptmenüfelder}
  17460.        Aktiv   : boolean;        {Menü aktiv ?}
  17461.        SAktiv  : boolean;        {PD-Menü aktiv ?}
  17462.        SIndex  : byte;
  17463.        WinAnz  : byte;           {Anzahl der Eintragungen in der Windowliste}
  17464.        Modal   : boolean;        {aktives Fenster nicht-modal ?}
  17465.        ifHelp  : boolean;        {mit Hilfe-System ?}
  17466.        HelpFile: string;         {Name der Hilfsdatei}
  17467.        constructor Init(Titel:string);
  17468.        destructor Done; virtual;
  17469.        procedure Draw; virtual;
  17470.        procedure Run;
  17471.        procedure HandleEvent; virtual;
  17472.        procedure InsertDesktop(Item:PGroup);
  17473.        procedure SetDesktopFrame(Titel:string); virtual;
  17474.        procedure SetDesktopBackground; virtual;
  17475.        procedure StatusBar; virtual;
  17476.        procedure MainMenu(Eintrag:str25;Help:byte);
  17477.        procedure SubMenu(Eintrag:str25;Kommando:word;Help,Key:byte;
  17478.                          Akt,Kennz:boolean);
  17479.        procedure NewLine;
  17480.        procedure InitVideoDevice; virtual;
  17481.        procedure InitMenuBar; virtual;
  17482.        procedure LoadMenu(ResName:str80);
  17483.        procedure ClearMenu;
  17484.        procedure DrawMainMenu;
  17485.        procedure SetDialogData; virtual;
  17486.        procedure SetOnlineHelp(HelpDatei:string);
  17487.        procedure MessageBox(Caption:word;PanelText,InfoText:string);
  17488.        procedure HelpBox(FName:string;HelpCtx:word);
  17489.  
  17490.  
  17491.  
  17492.  
  17493.  
  17494. Programmierhandbuch                                 WG-Vision - 336 -
  17495.  
  17496.  
  17497.  
  17498.  
  17499.  
  17500.  
  17501.  
  17502.       Private
  17503.        Delta    : ShortInt;
  17504.        ImgSize  : word;
  17505.        P        : Pointer;
  17506.        AktivNr  : byte;                   {Nr des aktiven Hauptmenüpunktes}
  17507.        SAktivNr : byte;                   {Nr des aktiven Untermenüpunktes}
  17508.        FK       : byte;
  17509.        LfdPtr   : PGroup;
  17510.        SWButton : TRect;
  17511.        procedure DrawSubMenu(Nr:byte);
  17512.        procedure RestoreMenuBackground(Nr:byte);
  17513.      end;
  17514.  
  17515.      PApp=^TApp;
  17516.      TApp=object(TProgram)
  17517.        constructor Init(Titel:string);
  17518.        destructor Done; virtual;
  17519.      end;
  17520.  
  17521.  
  17522. implementation
  17523.  
  17524.  
  17525.  
  17526.  
  17527.  
  17528.  
  17529.  
  17530.  
  17531.  
  17532.  
  17533.  
  17534.  
  17535.  
  17536.  
  17537.  
  17538.  
  17539.  
  17540.  
  17541.  
  17542.  
  17543.  
  17544. Programmierhandbuch                                 WG-Vision - 337 -
  17545.  
  17546.  
  17547.  
  17548.  
  17549.  
  17550.  
  17551.  
  17552. (*****************************************************
  17553. *                                                    *
  17554. * WG-VISION 1.0    Objektverwaltung                  *
  17555. *                                                    *
  17556. ******************************************************
  17557. *                                                    *
  17558. *                                                    *
  17559. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  17560. *                                                    *
  17561. *****************************************************)
  17562.  
  17563. {$I COMPILER.INC}
  17564.  
  17565. unit WViews;
  17566.  
  17567. interface
  17568.  
  17569. uses WDecl,
  17570.      WText,
  17571.      WUtils,
  17572.      WDriver,
  17573.      WEvent,
  17574.      WEMS,
  17575.      Dos,
  17576.      Graph;
  17577.  
  17578. const MaxMainMenu  = 10;
  17579.       MaxSubMenu   = 20;
  17580.  
  17581.       {Speichertypen}
  17582.  
  17583.       memNothing   = 0;
  17584.       memEMS       = 1;
  17585.       memHardDisk  = 2;
  17586.       memHeap      = 3;
  17587.  
  17588.  
  17589.  
  17590.  
  17591.  
  17592.  
  17593.  
  17594. Programmierhandbuch                                 WG-Vision - 338 -
  17595.  
  17596.  
  17597.  
  17598.  
  17599.  
  17600.  
  17601.  
  17602.       {DragMode}
  17603.  
  17604.       dmNoMove   = 0;  {Objekt darf nicht bewegt werden}
  17605.       dmMove     = 1;  {Objekt darf verschoben werden}
  17606.       dmGrow     = 2;  {Objekt darf seine Größe ändern}
  17607.  
  17608.       {Farbpaletten}
  17609.  
  17610.       Palette1 : string = #0#7#0#1#9#15#15#15#15#8#0#15#7;  {Rahmen}
  17611.       Palette2 : string = #15#0#15#8#15#0#0#0#7#7#15#8;     {Standardpalette}
  17612.                                                             {Menü}
  17613.       Palette3 : string = #15#0#7#7#15#0#8;                 {Rollbalken}
  17614.       Palette4 : string = #0#15#7#8#15#0#7#15;              {Push-Button}
  17615.       Palette5 : string = #0#15#8#0#7#8#0#8#15#0#7;         {Radio/Check-}
  17616.                                                    {Button,InputLine,Listbox}
  17617.  
  17618.       palStandard = 1;
  17619.       palRed      = 2;
  17620.       palGray     = 3;
  17621.       palGreen    = 4;
  17622.  
  17623.       Pal : array[1..4] of string =
  17624.               ((#0#7#0#1#9#15#15#15#15#8#0#15#7),    {palStandard}
  17625.                (#0#12#0#4#12#14#15#15#15#8#0#15#7),  {palRed}
  17626.                (#0#7#0#7#15#0#15#15#15#8#0#15#7),    {palGray}
  17627.                (#0#2#0#2#10#1#15#15#15#8#0#15#7));   {palGreen}
  17628.  
  17629.       Gray50 : FillPatternType = ($AA,$55,$AA,$55,$AA,$55,$AA,$55);
  17630.  
  17631. type TPalette=string;
  17632.  
  17633.      PObject=^TObject;
  17634.      TObject=object
  17635.      end;
  17636.  
  17637.      PGroup=^TGroup;
  17638.  
  17639.  
  17640.  
  17641.  
  17642.  
  17643.  
  17644. Programmierhandbuch                                 WG-Vision - 339 -
  17645.  
  17646.  
  17647.  
  17648.  
  17649.  
  17650.  
  17651.  
  17652.      PView=^TView;
  17653.      TView=object(TObject)
  17654.        Prev     : PGroup;
  17655.        Next     : PGroup;
  17656.        Palette  : TPalette;    {Farbpalette}
  17657.        Origin   : TPoint;      {Ursprung (linke obere Ecke)}
  17658.        Size     : TPoint;      {Länge und Breite}
  17659.        RSize    : boolean;     {Fenster bis auf Minimalmaße verkleinerbar}
  17660.        constructor Init(var Bounds:TRect;SetSize:boolean);
  17661.        destructor Done; virtual;
  17662.        procedure SetBounds(var Bounds:TRect); virtual;
  17663.        procedure GetBounds(var Bounds:TRect);
  17664.        procedure ChangeBounds(var Bounds:TRect);
  17665.        procedure GrowTo(X,Y:integer);
  17666.        procedure Locate(var Bounds:TRect);
  17667.        function GetPalColor(Index:byte):byte; virtual;
  17668.      end;
  17669.  
  17670.      TGroup=object(TView)
  17671.        First     : PGroup;
  17672.        Last      : PGroup;
  17673.        Current   : PGroup;
  17674.        CurrNo,
  17675.        AnzElem   : word;
  17676.        constructor Init;
  17677.        destructor Done; virtual;
  17678.        procedure SetArea(Bounds:TRect); virtual;
  17679.        procedure InsertItem(Item:PGroup);
  17680.        procedure DeleteItems;
  17681.        function GetItems(Nr:word):PGroup;
  17682.        procedure UnchainItem(N:PGroup);
  17683.        procedure DelItem(N:PGroup);
  17684.        procedure DelLastItem;
  17685.        procedure Draw; virtual;
  17686.        procedure Hide; virtual;
  17687.        procedure NewItemList; virtual;
  17688.        procedure SwapItems(I:word);
  17689.        procedure SetPos(R:TRect); virtual;
  17690.        procedure SetTextPos(X,Y:integer); virtual;
  17691.  
  17692.  
  17693.  
  17694. Programmierhandbuch                                 WG-Vision - 340 -
  17695.  
  17696.  
  17697.  
  17698.  
  17699.  
  17700.  
  17701.  
  17702.        procedure SetData(var Rec); virtual;
  17703.        procedure GetData(var Rec); virtual;
  17704.        procedure HandleEvent; virtual;
  17705.      Private
  17706.        Flag      : boolean;
  17707.        procedure DisposeItem(N:PGroup);
  17708.        procedure AddElem(N,NextPos:PGroup);
  17709.      end;
  17710.  
  17711.      PLine=^TLine;
  17712.      TLine=object(TGroup)
  17713.        Eintrag:string;
  17714.        function GetDataString:string; virtual;
  17715.      end;
  17716.  
  17717.      PHardDisk = ^THardDisk;    {Zeiger auf die Speicherobjekte}
  17718.      PEMS      = ^TEMS;
  17719.      PHeap     = ^THeap;
  17720.  
  17721.      PMemory=^TMemory;
  17722.      TMemory=object(TGroup)
  17723.        BSize      : longint;    {notwendige Puffergröße in Byte}
  17724.        Error      : byte;       {Fehler-Nr.}
  17725.        HardDisk   : PHardDisk;
  17726.        EMS        : PEMS;
  17727.        Heap       : PHeap;
  17728.        MemoryTyp  : byte;
  17729.        constructor Init(Bounds:TRect);
  17730.        destructor Done; virtual;
  17731.        procedure SetArea(Bounds:TRect); virtual;
  17732.        procedure Draw; virtual;
  17733.        procedure Hide; virtual;
  17734.      Private
  17735.        MaxSize    : word;       {65534 = 2*MaxInt}
  17736.      end;
  17737.  
  17738.  
  17739.  
  17740.  
  17741.  
  17742.  
  17743.  
  17744. Programmierhandbuch                                 WG-Vision - 341 -
  17745.  
  17746.  
  17747.  
  17748.  
  17749.  
  17750.  
  17751.  
  17752.      THardDisk=object(TMemory)
  17753.        Drive      : byte;
  17754.        SwapFile   : PathStr;    {Name der Swapdatei}
  17755.        FreeMemory : longint;    {freie Festplattenkapazität}
  17756.        Part       : word;
  17757.        constructor Init(Bounds:TRect);
  17758.        destructor Done; virtual;
  17759.        procedure Save; virtual;
  17760.        procedure Restore(P:TPoint); virtual;
  17761.      end;
  17762.  
  17763.      TEMS=object(TMemory)
  17764.        Version    : byte;       {EMS-Version}
  17765.        FreeMemory : longint;    {freier EMS-Speicher}
  17766.        Anzeige    : TText;
  17767.        Handle     : word;
  17768.        Part       : word;
  17769.        constructor Init(Bounds:TRect);
  17770.        destructor Done; virtual;
  17771.        procedure Save; virtual;
  17772.        procedure Restore(P:TPoint); virtual;
  17773.        procedure Watch;
  17774.        procedure ShowEMSStatus(X,Y,Color:integer);
  17775.      Private
  17776.        Change : boolean;
  17777.      end;
  17778.  
  17779.      THeap=object(TMemory)
  17780.        FreeMemory   : longint;  {freier Heap}
  17781.        FreeMaxAvail : longint;  {größter freier zusammenhängender}
  17782.                                 {Speicherblock}
  17783.        Anzeige      : TText;
  17784.        Buffer       : Pointer;
  17785.        constructor Init(Bounds:TRect);
  17786.        destructor Done; virtual;
  17787.        procedure Save; virtual;
  17788.        procedure Restore(P:TPoint); virtual;
  17789.        procedure HeapWatch;
  17790.        procedure ShowHeapStatus(X,Y,Color:integer);
  17791.  
  17792.  
  17793.  
  17794. Programmierhandbuch                                 WG-Vision - 342 -
  17795.  
  17796.  
  17797.  
  17798.  
  17799.  
  17800.  
  17801.  
  17802.      Private
  17803.        Change       : boolean;
  17804.      end;
  17805.  
  17806.      PFrame=^TFrame;
  17807.      TFrame=object(TGroup)
  17808.        FTyp     : byte;        {Rahmentyp}
  17809.        Header   : TText;       {Headertext}
  17810.        Area     : TRect;       {Bereich innerhalb des Rahmens}
  17811.        ZoomRect : TRect;       {Speichert die originale Fenstergröße}
  17812.        DragMode : byte;        {Verhalten des Fensters bei Veränderungen}
  17813.        constructor Init(var Bounds,Z:TRect;KopfText:string;Typ:byte);
  17814.        destructor Done; virtual;
  17815.        procedure SetArea(Bounds:TRect); virtual;
  17816.        procedure SetActivAreas(var Bounds:TRect); virtual;
  17817.        procedure Draw; virtual;
  17818.        procedure Hide; virtual;
  17819.        procedure HandleEvent; virtual;
  17820.      Private
  17821.        ActFrame : array[1..17] of TRect;
  17822.        procedure DrawFrame(Typ:byte);
  17823.      end;
  17824.  
  17825.      PBackground=^TBackground;
  17826.      TBackground=object(TGroup)
  17827.        Border : TRect;
  17828.        constructor Init(R:TRect);
  17829.        destructor Done; virtual;
  17830.        procedure SetArea(Bounds:TRect); virtual;
  17831.        procedure Draw; virtual;
  17832.        procedure Hide; virtual;
  17833.      end;
  17834.  
  17835.      PSubMenu=array[1..MaxSubMenu] of ^TSubMenu;
  17836.  
  17837.      PMainMenu=array[1..MaxMainMenu] of ^TMainMenu;
  17838.      TMainMenu=object(TView)
  17839.        Area     : TRect;          {Bereich des PD-Menüs}
  17840.        Item     : str25;          {Eintrag}
  17841.  
  17842.  
  17843.  
  17844. Programmierhandbuch                                 WG-Vision - 343 -
  17845.  
  17846.  
  17847.  
  17848.  
  17849.  
  17850.  
  17851.  
  17852.        BS       : byte;           {Position des Kennbuchstabens}
  17853.        HelpCtx  : word;           {Nummer für Hilfesystem}
  17854.        AnzSMenu : byte;           {Anzahl der PD-Menüeintragungen}
  17855.        SbMenu   : PSubMenu;
  17856.        constructor Init(R:TRect;Bez:str25;Help:byte);
  17857.        destructor Done; virtual;
  17858.      end;
  17859.  
  17860.      TSubMenu=object(TMainMenu)
  17861.        MCommand   : word;      {Aufruf-Kommando}
  17862.        ShortKey   : byte;      {spezielle Aufruftaste}
  17863.        Grayed     : boolean;   {Menüfeld anwählbar}
  17864.        Haken      : boolean;   {zeigt bei Menüschaltern Schalterstellung an}
  17865.        constructor Init(R:TRect;Bez:str25;Kommand:word;Help,Key:byte;
  17866.                         Act,Kennz:boolean);
  17867.        destructor Done; virtual;
  17868.        procedure Aktiviere;
  17869.        procedure DeAktiviere;
  17870.        procedure HookOn;
  17871.        procedure HookOff;
  17872.      end;
  17873.  
  17874.      PDeskTop=^TDeskTop;
  17875.      TDeskTop=object(TGroup)
  17876.        List     : PGroup;       {Desktop-Elemente}
  17877.        Frame    : PFrame;       {Zeiger auf den Rahmen}
  17878.        Bgrd     : PBackground;  {Zeiger auf den Untergrund}
  17879.        WinList  : PGroup;       {Liste der Windows}
  17880.        WinCount : byte;         {Anzahl der geöffneten Fenster}
  17881.        constructor Init;
  17882.        destructor Done; virtual;
  17883.        procedure SetBackground;
  17884.        procedure Draw; virtual;
  17885.      end;
  17886.  
  17887.  
  17888. implementation
  17889.  
  17890.  
  17891.  
  17892.  
  17893.  
  17894. Programmierhandbuch                                 WG-Vision - 344 -
  17895.  
  17896.  
  17897.  
  17898.  
  17899.  
  17900.  
  17901.  
  17902. (*****************************************************
  17903. *                                                    *
  17904. * WG-VISION 1.0    Treiber für Bildschirm, Maus      *
  17905. *                  Joystick und Summagraphics-       *
  17906. *                  Digitizer                         *
  17907. *                                                    *
  17908. ******************************************************
  17909. *                                                    *
  17910. *                                                    *
  17911. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  17912. *                                                    *
  17913. *****************************************************)
  17914.  
  17915. {$I COMPILER.INC}
  17916.  
  17917. unit WDriver;
  17918.  
  17919. interface
  17920.  
  17921. uses WDecl,
  17922.      Dos,
  17923.      Crt,
  17924.      Graph;
  17925.  
  17926. type tDigiData=record            {Datenrecord Summagrafic-Digitizer}
  17927.                  X,Y:word;
  17928.                  Taste:byte;
  17929.                end;
  17930.  
  17931.      TVideoDevice=object(TObject)
  17932.        Treiber  : integer;   {Grafik-Treiber}
  17933.        OrigMode : integer;   {letzter Textmodus}
  17934.        Modus    : integer;   {aktiver Grafik-Modus}
  17935.        Modi     : tMinSet;   {erlaubte Grafik-Modi}
  17936.        XMax     : word;      {maximal mögliche x-Koordinate des Bildschirms}
  17937.        YMax     : word;      {maximal mögliche y-Koordinate des Bildschirms}
  17938.        Colors   : word;      {Anzahl Farben}
  17939.  
  17940.  
  17941.  
  17942.  
  17943.  
  17944. Programmierhandbuch                                 WG-Vision - 345 -
  17945.  
  17946.  
  17947.  
  17948.  
  17949.  
  17950.  
  17951.  
  17952.        constructor Init(Driver,Mode:integer);
  17953.        destructor Done; virtual;
  17954.        function GetXMax:word;
  17955.        function GetYMax:word;
  17956.        function GetAnzColors:word;
  17957.        function GetDriver:string;
  17958.        function GetGrafikMode:integer;
  17959.        procedure ChangeGraficMode(Mode:integer);
  17960.        procedure SetTextMode;
  17961.        procedure SetDirectVideo(Direct:boolean);
  17962.      end;
  17963.  
  17964.      TJoyStickDevice=object(TObject)
  17965.        JoyPresent : boolean;    {Spieleadapter vorhanden ?}
  17966.        JPos       : TPoint;     {absolute Position}
  17967.        Phi        : Single;     {horizontale Auslenkung}
  17968.        Elongation : Single;     {Betrag der Auslenkung}
  17969.        FPush1     : boolean;    {1. Feuertaste gedrückt ?}
  17970.        FPush2     : boolean;    {2. Feuertaste gedrückt ?}
  17971.        procedure Init;
  17972.        procedure JoyStickHandle;      {Joystick-Handler}
  17973.        function IfJoyPresent:boolean; {Spieleadapter vorhanden ?}
  17974.        function Degree:integer;       {Winkel}
  17975.        function Turn:word;            {Betrag der Auslenkung}
  17976.        function GetXValue:integer;    {x-Position}
  17977.        function GetYValue:integer;    {y-Position}
  17978.        function PushOne:boolean;      {erste Feuertaste betätigt}
  17979.        function PushTwo:boolean;      {zweite Feuertaste betätigt}
  17980.      end;
  17981.  
  17982.      TMouseDevice=object(TObject)
  17983.        MousePresent  : boolean;   {Maus installiert ?}
  17984.        FName         : string;    {Dateiname der Mauszeiger-Ressource}
  17985.        Position      : TPoint;    {Position des Mauskursors}
  17986.        DX,Dy         : integer;   {letzte Veränderung}
  17987.        LeftButton    : boolean;   {linke Taste gedrückt}
  17988.        RightButton   : boolean;   {rechte Taste gedrückt}
  17989.        LButtonChange : boolean;   {linke Maustaste verändert ?}
  17990.        RButtonChange : boolean;   {rechte Maustaste verändert ?}
  17991.  
  17992.  
  17993.  
  17994. Programmierhandbuch                                 WG-Vision - 346 -
  17995.  
  17996.  
  17997.  
  17998.  
  17999.  
  18000.  
  18001.  
  18002.        DoubleKlick   : boolean;   {Doppelklick ?}
  18003.        Time          : word;
  18004.        KlickTime     : word;      {Zeitdifferenz für Doppelklick}
  18005.        Area          : TRect;     {Bereichsgrenzen für die Mausbewegung}
  18006.        CursorTyp     : byte;      {Kursortyp}
  18007.        procedure Init;            {Initialisierung}
  18008.        procedure ShowMouse;       {Mauskursor anzeigen}
  18009.        procedure HideMouse;       {Mauskursor löschen}
  18010.        procedure SetMouseArea(X1,Y1,X2,Y2:integer);
  18011.        procedure PutMouse(X,Y:integer);   {Maus auf dem Bildschirm}
  18012.                                           {positionieren}
  18013.        procedure MouseSpeed(XSpeed,YSpeed:integer);  {Mausgeschwindigkeit}
  18014.        function MouseHandler:boolean;     {Maushandler}
  18015.        function GetXPos:integer;          {x-Koordinate des Mauszeigers}
  18016.        function GetYPos:integer;          {y-Koordinate des Mauszeigers}
  18017.        procedure GetPos(var MP:TPoint);   {Koordinaten des Mauszeigers}
  18018.        function LButtonKlick:boolean;     {linke Maustaste geklickt ?}
  18019.        function RButtonKlick:boolean;     {rechte Maustaste geklickt ?}
  18020.        function LButtonDrag:boolean;      {linke Maustaste gedrückt bewegt?}
  18021.        function RButtonDrag:boolean;      {rechte Maustaste gedrückt bewegt?}
  18022.        function LButtonRel:boolean;       {linke Taste losgelassen ?}
  18023.        function RButtonRel:boolean;       {rechte Taste losgelassen ?}
  18024.        function Double:boolean;           {Doppelklick}
  18025.        procedure SetKlickTime(T:byte);    {Zeitdifferenz für Doppelklick}
  18026.        function MMove:boolean;            {Maus nur bewegt}
  18027.        procedure SetCursorTyp(CTyp:byte); {Mauskursor ändern}
  18028.        procedure LoadCursorTyp(F:string); {Mauszeiger aus Ressource laden}
  18029.      Private
  18030.        function GetTicks:word;
  18031.      end;
  18032.  
  18033.      TKeyboardDevice=object(TObject)
  18034.        ATFlag     : boolean;  {AT-Tastatur ?}
  18035.        Delay      : integer;  {Tastatur-Verzögerung}
  18036.        Speed      : integer;  {Wiederholfrequenz}
  18037.        KeyCode    : Char;     {ASCII-Zeichen der Taste}
  18038.        ScanCode   : byte;     {Scancode der Taste}
  18039.        StatusFlag : byte;     {Statusflag der Sondertasten}
  18040.        KeyPush    : boolean;  {Taste gedrückt (true) oder losgelassen ?}
  18041.  
  18042.  
  18043.  
  18044. Programmierhandbuch                                 WG-Vision - 347 -
  18045.  
  18046.  
  18047.  
  18048.  
  18049.  
  18050.  
  18051.  
  18052.        Locking    : boolean;  {Tastatur gesperrt ? (false)}
  18053.        procedure Init;
  18054.        procedure LockKeyboard;          {Tastatur sperren}
  18055.        procedure UnLockKeyboard;        {Tastatur wieder freigeben}
  18056.        procedure ClearKeyboardBuffer;   {Tastaturpuffer löschen}
  18057.        function SetTypmaticRate(Verzoegerung,
  18058.                                 Wiederholfrequenz:integer):boolean;
  18059.        function KeyboardHandler:boolean;
  18060.        function GetKeyCode:Char;        {übergibt Keycode}
  18061.        function GetScanCode:byte;       {übergibt Scancode}
  18062.        function IfKeyPush:boolean;      {Taste heruntergedrückt ?}
  18063.        function IfKeybLock:boolean;     {Tastatur gesperrt ?}
  18064.        function RShiftKey:boolean;      {rechte Shift-Taste gedrückt ?}
  18065.        function LShiftKey:boolean;      {linke Shifttaste gedrückt ?}
  18066.        function CtrlKey:boolean;        {Ctrl-Taste gedrückt ?}
  18067.        function AltKey:boolean;         {Alt-Taste gedrückt ?}
  18068.        function ScrollLock:boolean;     {Scroll-Lock-Taste gedrückt ?}
  18069.        function NumLock:boolean;        {Num-Lock-Taste gedrückt ?}
  18070.        function CapsLock:boolean;       {Caps-Lock-Taste gedrückt ?}
  18071.      end;
  18072.  
  18073.      TSSDigiDevice=object(TObject)
  18074.       COMPort  : byte;                  {serielle Schnittstelle}
  18075.       Buffer   : string[20];            {Puffer zum Zwischenspeicher der}
  18076.                                         {Koordinaten}
  18077.       DigiData : tDigiData;             {Digitizer-Daten}
  18078.       procedure Init(SPort:byte);       {Initialisierung der seriellen}
  18079.                                         {Schnittstelle}
  18080.       procedure SetCommand(cc:string);      {Kommando cc senden}
  18081.       procedure SetStreamMode;              {Stream-Mode einschalten}
  18082.       procedure SetPointMode;               {Point-Mode einschalten}
  18083.       procedure SetSwitchStreamMode;        {Switch-Stream-Mode einschalten}
  18084.       procedure SetResolution(cc:Char);     {Auflösung festlegen}
  18085.       procedure SetReportRate(cc:Char);     {Übertragungsrate festlegen}
  18086.       procedure SetFrameWork(cc:Char);      {Koordinatensystem festlegen}
  18087.       function GetModelIdentifier:string;   {Identifikationsstring empfangen}
  18088.       procedure DigiHandle;                 {Digitizer-Handler}
  18089.       function GetXValue:word;              {y-Wert}
  18090.       function GetYValue:word;              {y-Wert}
  18091.  
  18092.  
  18093.  
  18094. Programmierhandbuch                                 WG-Vision - 348 -
  18095.  
  18096.  
  18097.  
  18098.  
  18099.  
  18100.  
  18101.  
  18102.       function GetTaste:byte;               {Lupen-oder Stifttaste}
  18103.      Private
  18104.       procedure InitComPort(BaudRate:integer;par,stops,Char:byte);
  18105.       procedure SendChar(cc:Char);
  18106.       function ReceiveChar:Char;
  18107.       procedure SelectValue;
  18108.      end;
  18109.  
  18110. var Mouse:TMouseDevice;
  18111.     Keyb :TKeyboardDevice;
  18112.     Video:TVideoDevice;
  18113.     Joy  :TJoyStickDevice;
  18114.  
  18115.  
  18116. implementation
  18117.  
  18118.  
  18119.  
  18120.  
  18121.  
  18122.  
  18123.  
  18124.  
  18125.  
  18126.  
  18127.  
  18128.  
  18129.  
  18130.  
  18131.  
  18132.  
  18133.  
  18134.  
  18135.  
  18136.  
  18137.  
  18138.  
  18139.  
  18140.  
  18141.  
  18142.  
  18143.  
  18144. Programmierhandbuch                                 WG-Vision - 349 -
  18145.  
  18146.  
  18147.  
  18148.  
  18149.  
  18150.  
  18151.  
  18152. (*****************************************************
  18153. *                                                    *
  18154. * WG-VISION 1.0    Fenster- und Dialogobjekte        *
  18155. *                                                    *
  18156. ******************************************************
  18157. *                                                    *
  18158. *                                                    *
  18159. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  18160. *                                                    *
  18161. *****************************************************)
  18162.  
  18163. {$I COMPILER.INC}
  18164.  
  18165. unit WDLG;
  18166.  
  18167. interface
  18168.  
  18169. uses WDecl,
  18170.      WDriver,
  18171.      WEvent,
  18172.      WViews,
  18173.      WUtils,
  18174.      WText,
  18175.      Graph;
  18176.  
  18177.  
  18178. type PScrollBar=^TScrollBar;
  18179.      PIcon=^TIcon;
  18180.  
  18181.      ZMenge=set of Char;
  18182.  
  18183.      PWindow=^TWindow;
  18184.      TWindow=object(TGroup)
  18185.        List      : PGroup;      {Fenster-Elemente}
  18186.        Undergrd  : PMemory;     {Speicher für Fenster-Untergrund}
  18187.        Frame     : PFrame;      {Zeiger auf den Rahmen des Fensters}
  18188.        Bgrd      : PBackground; {Zeiger auf den Fenster-Hintergrund}
  18189.        SBH,SBV   : PScrollBar;  {vertikaler und horizontaler Scrollbalken}
  18190.        ZoomRect  : TRect;       {Original-Fenstergröße}
  18191.  
  18192.  
  18193.  
  18194. Programmierhandbuch                                 WG-Vision - 350 -
  18195.  
  18196.  
  18197.  
  18198.  
  18199.  
  18200.  
  18201.  
  18202.        Title     : str80;       {Fenster-Header}
  18203.        Typ       : byte;        {Rahmentyp}
  18204.        WinModal  : boolean;     {Fenster nicht-modal ?}
  18205.        ChildPresent : boolean;  {Childfenster aktiv ?}
  18206.        constructor Init(var Bounds:TRect;ATitle:str80;AType:byte);
  18207.        destructor Done; virtual;
  18208.        procedure SetWindowAttrib(Modal:boolean);
  18209.        procedure SetPalette; virtual;
  18210.        procedure InitUnderGround; virtual;
  18211.        procedure InitFrame; virtual;
  18212.        procedure InitBackground; virtual;
  18213.        procedure InitWindowScroller; virtual;
  18214.        procedure Draw; virtual;
  18215.        procedure DrawClientArea; virtual;
  18216.        procedure Hide; virtual;
  18217.        procedure NewItemList; virtual;
  18218.        procedure DrawNewFrame; virtual;
  18219.        procedure HandleEvent; virtual;
  18220.      end;
  18221.  
  18222.      PDlgWindow=^TDlgWindow;
  18223.      TDlgWindow=object(TWindow)
  18224.        R            : TRect;
  18225.        DlgElemente  : string;
  18226.        DlgList      : PGroup;   {Liste der Dialogelemente}
  18227.        Child        : PGroup;   {Child-Fenster}
  18228.        FocElem      : word;     {Nr. des fokussierten Elements}
  18229.        DlgInput     : boolean;  {nur passive Dialogelemente ?}
  18230.        constructor Init(var Bounds:TRect;ATitle:str80;AType:byte);
  18231.        destructor Done; virtual;
  18232.        procedure Draw; virtual;
  18233.        procedure DrawMask; virtual;
  18234.        procedure Hide; virtual;
  18235.        procedure SetData(var Rec); virtual;
  18236.        procedure GetDataRec;
  18237.        procedure InsertChildWindow(Item:PGroup);
  18238.        procedure SetPushButton(X,Y,xl,yl:integer;Bez:str25;Kommando:word);
  18239.        procedure SetRadioButton(X,Y:integer;Bez:str25;FGruppe:byte);
  18240.        procedure SetCheckButton(X,Y:integer;Bez:str25);
  18241.  
  18242.  
  18243.  
  18244. Programmierhandbuch                                 WG-Vision - 351 -
  18245.  
  18246.  
  18247.  
  18248.  
  18249.  
  18250.  
  18251.  
  18252.        procedure SetInputLine(X,Y,xl:integer;Bez:str25;MaxLen:byte;Zeich:ZMenge);
  18253.        procedure SetNumButton(X,Y,xl:integer;Bez:str25;MaxLen:byte;
  18254.                               TTyp:byte;Min,Max,Step,Format:Single);
  18255.        procedure SetListBox(X,Y,xl,yl:integer;Bez:str25;
  18256.                             LScroller:word); virtual;
  18257.        procedure SetGroupFrame(X,Y,xl,yl:integer;Bez:str25;FrameTyp:word);
  18258.        procedure SetIcon(X,Y:integer;Bez:str25);
  18259.        procedure SetStaticText(X,Y:integer;Bez:string;RelPos:byte);
  18260.        procedure SetListData(LData:PGroup);
  18261.        procedure SetTextPosition(X,Y:integer);
  18262.        procedure ChangePalColor(Eintrag, Color:byte);
  18263.        procedure DrawLast;
  18264.        procedure SetTextParameters(Fnt,Direct:word;CharSz:byte);
  18265.        procedure SetDisabled;
  18266.        function GetFocElem:word;
  18267.        procedure HandleEvent; virtual;
  18268.      Private
  18269.        RecAdr   : word;
  18270.      end;
  18271.  
  18272.      {Dialogelemente}
  18273.  
  18274.      PButton=^TButton;
  18275.      TButton=object(TGroup)
  18276.        P          : TPoint;
  18277.        TextPos    : TRect;           {Position des Bezeichners}
  18278.        DX,Dy      : integer;         {TextPosition relativ zum Button}
  18279.        Bezeichner : TText;
  18280.        BS         : byte;            {Position Short-Cut}
  18281.        ShortCut   : Char;            {ShortCut}
  18282.        Focus      : boolean;         {Element fokussiert ?}
  18283.        Enabled    : boolean;         {Element aktiv ?}
  18284.        constructor Init(R:TRect;BText:string);
  18285.        destructor Done; virtual;
  18286.        procedure SetPos(R:TRect); virtual;
  18287.        procedure SetTextPos(X,Y:integer); virtual;
  18288.        procedure HandleEvent; virtual;
  18289.        procedure SetEnabled(On:boolean);
  18290.      end;
  18291.  
  18292.  
  18293.  
  18294. Programmierhandbuch                                 WG-Vision - 352 -
  18295.  
  18296.  
  18297.  
  18298.  
  18299.  
  18300.  
  18301.  
  18302.      PPushButton=^TPushButton;
  18303.      TPushButton=object(TButton)
  18304.        Kommando   : word;
  18305.        PushDown   : boolean;         {Schalter heruntergedrückt}
  18306.        KeyIcon    : PIcon;
  18307.        constructor Init(R:TRect;BText:str25;Komm:word);
  18308.        destructor Done; virtual;
  18309.        procedure SetPos(R:TRect); virtual;
  18310.        procedure SetTextPos(X,Y:integer); virtual;
  18311.        procedure Draw; virtual;
  18312.        procedure HandleEvent; virtual;
  18313.      end;
  18314.  
  18315.      PRadioButton=^TRadioButton;
  18316.      TRadioButton=object(TButton)
  18317.        Gruppe     : byte;            {Gruppen-Index}
  18318.        Gesetzt    : boolean;
  18319.        constructor Init(R:TRect;BText:str25;FGruppe:word);
  18320.        destructor Done; virtual;
  18321.        procedure SetPos(R:TRect); virtual;
  18322.        procedure SetTextPos(X,Y:integer); virtual;
  18323.        procedure Draw; virtual;
  18324.        procedure SetData(var Rec); virtual;
  18325.      end;
  18326.  
  18327.      PCheckButton=^TCheckButton;
  18328.      TCheckButton=object(TRadioButton)
  18329.        constructor Init(R:TRect;BText:str25);
  18330.        destructor Done; virtual;
  18331.        procedure Draw; virtual;
  18332.      end;
  18333.  
  18334.      PInputLine=^TInputLine;
  18335.      TInputLine=object(TButton)
  18336.        Data    : string;
  18337.        DataLen : byte;
  18338.        constructor Init(R:TRect;BText:str25);
  18339.        destructor Done; virtual;
  18340.        procedure SetPos(R:TRect); virtual;
  18341.  
  18342.  
  18343.  
  18344. Programmierhandbuch                                 WG-Vision - 353 -
  18345.  
  18346.  
  18347.  
  18348.  
  18349.  
  18350.  
  18351.  
  18352.        procedure SetTextPos(X,Y:integer); virtual;
  18353.        procedure Draw; virtual;
  18354.        procedure DrawData;
  18355.        procedure SetData(var Rec); virtual;
  18356.        procedure HandleEvent; virtual;
  18357.      Private
  18358.        zz         : string;
  18359.        CPos       : integer;     {KursorPosition}
  18360.        MaskSize   : integer;     {Länge der Eingabemaske in Zeichen}
  18361.        k          : byte;
  18362.        FieldAktiv : boolean;
  18363.        Zeichen    : ZMenge;      {erlaubte Zeichen}
  18364.        procedure CursorOn(pp:integer);
  18365.        procedure CursorOff(pp:integer);
  18366.      end;
  18367.  
  18368.      PNumButton=^TNumButton;
  18369.      TNumButton=object(TInputLine)
  18370.       UButton : PPushButton;
  18371.       DButton : PPushButton;
  18372.       Min     : Single;              {Maximalwert}
  18373.       Max     : Single;              {Minimalwert}
  18374.       Step    : Single;              {Schrittweite}
  18375.       Format  : Single;              {Formatierungsanweisung, n.m}
  18376.       constructor Init(R,W:TRect;BText:str25;TTyp:byte;AMin,AMax,
  18377.                        aStep,aFormat:Single);
  18378.       destructor Done; virtual;
  18379.       procedure SetPos(R:TRect); virtual;
  18380.       procedure SetParameters(AMin,AMax,aStep,aFormat:Single);
  18381.       procedure Draw; virtual;
  18382.       procedure HandleEvent; virtual;
  18383.      end;
  18384.  
  18385.  
  18386.  
  18387.  
  18388.  
  18389.  
  18390.  
  18391.  
  18392.  
  18393.  
  18394. Programmierhandbuch                                 WG-Vision - 354 -
  18395.  
  18396.  
  18397.  
  18398.  
  18399.  
  18400.  
  18401.  
  18402.      TScrollBar=object(TView)
  18403.        SBereich  : TRect;          {vom Rollbalken umschlossener Bereich}
  18404.        Direction : byte;           {Richtung des Rollbalkens}
  18405.        Value     : integer;        {Aktuelle Position des Indikators}
  18406.        PgStep    : integer;        {Schrittweiten}
  18407.        WinLength : longint;        {Balkenlänge}
  18408.        Max       : longint;        {Maximalwerte von Value}
  18409.        constructor Init(Bounds:TRect;Richtung:byte);
  18410.        destructor Done; virtual;
  18411.        procedure DrawScrollBar;
  18412.        procedure SetStep(APgStep:integer);
  18413.        procedure SetValue(AValue:integer);
  18414.        procedure SetMaxValue(AMax:integer);
  18415.        procedure SetThumb;
  18416.        procedure HandleEvent; virtual;
  18417.      Private
  18418.        SNr : byte;
  18419.        ActAreaSB : array[1..8] of TRect;  {aktive Bereiche}
  18420.      end;
  18421.  
  18422.      PScroller=^TScroller;
  18423.      TScroller=object(TButton)
  18424.        Border         : TRect;
  18425.        HorizScrollBar : PScrollBar;
  18426.        VertiScrollBar : PScrollBar;
  18427.        Delta          : TPoint;        {relative Position}
  18428.        WDelta         : TPoint;
  18429.        Limit          : TPoint;        {Ausmaße des Datenbereichs in Zeilen}
  18430.                                        {und Spalten}
  18431.        Px,Py          : integer;       {Pixelzahl pro Spalte/Zeile}
  18432.        Zeilen         : word;          {im Fenster}
  18433.        Spalten        : word;          {im Fenster}
  18434.        Liste          : PLine;        {enthält zeilenweise strings}
  18435.        constructor Init(R:TRect;HScroller,VScroller:PScrollBar);
  18436.        destructor Done; virtual;
  18437.        procedure SetArea(Bounds:TRect); virtual;
  18438.        procedure SetLimit(X,Y,Pxx,Pyy:integer);
  18439.        procedure ScrollDraw; virtual;
  18440.        procedure HandleEvent; virtual;
  18441.  
  18442.  
  18443.  
  18444. Programmierhandbuch                                 WG-Vision - 355 -
  18445.  
  18446.  
  18447.  
  18448.  
  18449.  
  18450.  
  18451.  
  18452.        procedure Draw; virtual;         {zeichnet Rollbalken}
  18453.        procedure Hide; virtual;
  18454.        procedure SetPos(R:TRect); virtual;
  18455.      Private
  18456.        RR : TRect;
  18457.      end;
  18458.  
  18459.      PListBox=^TListBox;
  18460.      TListBox=object(TScroller)
  18461.        Data       : string;          {enthält ausgewähltes Listenelement}
  18462.        DataLen    : byte;
  18463.        AktivItem  : word;            {Aktives Element der Liste}
  18464.        ChangeItem : word;            {Auswahlelement Tastatur}
  18465.        constructor Init(R:TRect;BText:str25;HScroller,VScroller:PScrollBar);
  18466.        procedure CreateDataList;
  18467.        procedure ScrollDraw; virtual;
  18468.        procedure Draw; virtual;
  18469.        procedure SetPos(R:TRect); virtual;
  18470.        procedure SetTextPos(X,Y:integer); virtual;
  18471.        procedure HandleEvent; virtual;
  18472.      end;
  18473.  
  18474.      PGroupFrame=^TGroupFrame;
  18475.      TGroupFrame=object(TButton)
  18476.        FrameTyp : word;
  18477.        constructor Init(R:TRect;BText:str25;FTyp:word);
  18478.        destructor Done; virtual;
  18479.        procedure SetPos(R:TRect); virtual;
  18480.        procedure SetTextPos(X,Y:integer); virtual;
  18481.        procedure Draw; virtual;
  18482.      end;
  18483.  
  18484.  
  18485.  
  18486.  
  18487.  
  18488.  
  18489.  
  18490.  
  18491.  
  18492.  
  18493.  
  18494. Programmierhandbuch                                 WG-Vision - 356 -
  18495.  
  18496.  
  18497.  
  18498.  
  18499.  
  18500.  
  18501.  
  18502.      TIcon=object(TButton)
  18503.        F        : file;
  18504.        Nr       : word;
  18505.        FName    : str80;
  18506.        IconSize : word;
  18507.        Anzahl   : integer;
  18508.        constructor Init(R:TRect;IconName:str25);
  18509.        destructor Done; virtual;
  18510.        procedure SetPos(R:TRect); virtual;
  18511.        procedure Draw; virtual;
  18512.      end;
  18513.  
  18514.      PStaticText=^TStaticText;
  18515.      TStaticText=object(TButton)
  18516.        Pos      : byte;
  18517.        Line     : string;
  18518.        constructor Init(R:TRect;InfoString:string);
  18519.        destructor Done; virtual;
  18520.        procedure SetPos(R:TRect); virtual;
  18521.        procedure Draw; virtual;
  18522.      end;
  18523.  
  18524.  
  18525. implementation
  18526.  
  18527.  
  18528.  
  18529.  
  18530.  
  18531.  
  18532.  
  18533.  
  18534.  
  18535.  
  18536.  
  18537.  
  18538.  
  18539.  
  18540.  
  18541.  
  18542.  
  18543.  
  18544. Programmierhandbuch                                 WG-Vision - 357 -
  18545.  
  18546.  
  18547.  
  18548.  
  18549.  
  18550.  
  18551.  
  18552. (*****************************************************
  18553. *                                                    *
  18554. * WG-VISION 1.0    Event-Verwaltungsroutinen         *
  18555. *                                                    *
  18556. ******************************************************
  18557. *                                                    *
  18558. *                                                    *
  18559. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  18560. *                                                    *
  18561. *****************************************************)
  18562.  
  18563. {$I COMPILER.INC}
  18564.  
  18565. unit WEvent;
  18566.  
  18567. interface
  18568.  
  18569. uses WDecl,
  18570.      WDriver;
  18571.  
  18572.  
  18573. type PEvent=^TEvent;
  18574.      TEvent=record
  18575.        What    : byte;
  18576.        Command : word;
  18577.        Message : word;
  18578.        Info    : word;
  18579.          case word of
  18580.           0 : (InfoPtr:Pointer);
  18581.           1 : (InfoLong:longint);
  18582.           2 : (InfoWord:word);
  18583.           3 : (InfoByte:byte);
  18584.           4 : (InfoChar:Char);
  18585.           5 : (InfoString:string);
  18586.      end;
  18587.  
  18588.  
  18589. var Event:TEvent;
  18590.  
  18591.  
  18592.  
  18593.  
  18594. Programmierhandbuch                                 WG-Vision - 358 -
  18595.  
  18596.  
  18597.  
  18598.  
  18599.  
  18600.  
  18601.  
  18602. procedure GetEvent;
  18603. procedure ClearEvent;
  18604. procedure ClearMessage;
  18605. function CheckScanCode(SC:byte):Char;
  18606.  
  18607.  
  18608. implementation
  18609.  
  18610.  
  18611.  
  18612.  
  18613.  
  18614.  
  18615.  
  18616.  
  18617.  
  18618.  
  18619.  
  18620.  
  18621.  
  18622.  
  18623.  
  18624.  
  18625.  
  18626.  
  18627.  
  18628.  
  18629.  
  18630.  
  18631.  
  18632.  
  18633.  
  18634.  
  18635.  
  18636.  
  18637.  
  18638.  
  18639.  
  18640.  
  18641.  
  18642.  
  18643.  
  18644. Programmierhandbuch                                 WG-Vision - 359 -
  18645.  
  18646.  
  18647.  
  18648.  
  18649.  
  18650.  
  18651.  
  18652. (*****************************************************
  18653. *                                                    *
  18654. * WG-VISION 1.0    Fehlermeldungen Deutsch/Englisch  *
  18655. *                                                    *
  18656. ******************************************************
  18657. *                                                    *
  18658. *                                                    *
  18659. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  18660. *                                                    *
  18661. *****************************************************)
  18662.  
  18663. {$I COMPILER.INC}
  18664.  
  18665. unit WError;
  18666.  
  18667. interface
  18668.  
  18669. uses WDecl;
  18670.  
  18671. procedure ErrorMessage(Nr:tError;var PText,EText:string;var MTyp:byte);
  18672.  
  18673. implementation
  18674.  
  18675.  
  18676.  
  18677.  
  18678.  
  18679.  
  18680.  
  18681.  
  18682.  
  18683.  
  18684.  
  18685.  
  18686.  
  18687.  
  18688.  
  18689.  
  18690.  
  18691.  
  18692.  
  18693.  
  18694. Programmierhandbuch                                 WG-Vision - 360 -
  18695.  
  18696.  
  18697.  
  18698.  
  18699.  
  18700.  
  18701.  
  18702. (*****************************************************
  18703. *                                                    *
  18704. * WG-VISION 1.0    Textausgabe und Texthandling      *
  18705. *                                                    *
  18706. ******************************************************
  18707. *                                                    *
  18708. *                                                    *
  18709. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  18710. *                                                    *
  18711. *****************************************************)
  18712.  
  18713. {$I COMPILER.INC}
  18714.  
  18715. unit WText;
  18716.  
  18717. interface
  18718.  
  18719. uses WDecl,
  18720.      WDriver,
  18721.      Crt,
  18722.      Graph;
  18723.  
  18724.  
  18725. type GraficFont = (Thin8,Thin14,Thin16,Brdwy19,Wndw19,Sans19,VGAF);
  18726.  
  18727.      TText=object
  18728.        R         : TRect;
  18729.        Font      : word;    {Zeichensatz}
  18730.        Direction : word;    {Richtung}
  18731.        CharSize  : byte;    {Buchstabengröße}
  18732.        TxtHeight : word;    {Texthöhe}
  18733.        TxtWidth  : word;    {Breite des Textes}
  18734.        Zeile     : string;  {auszugebender Text}
  18735.        constructor Init;
  18736.        destructor Done;
  18737.        procedure SetFont(FFont,FDirection:word);
  18738.        procedure SetCharSize(FCharSize:byte);
  18739.        procedure SetClipFrame(T:TRect);
  18740.        procedure SetDefaultText;
  18741.  
  18742.  
  18743.  
  18744. Programmierhandbuch                                 WG-Vision - 361 -
  18745.  
  18746.  
  18747.  
  18748.  
  18749.  
  18750.  
  18751.  
  18752.        procedure LText(X,Y:integer;z:string);
  18753.        procedure RText(X,Y:integer;z:string);
  18754.        procedure CText(X,Y:integer;z:string);
  18755.      end;
  18756.  
  18757. var pitch      : word;
  18758.     BColor     : word;
  18759.     Color      : word;
  18760.     CharHeight : word;
  18761.     CharLength : word;
  18762.     Font       : GraficFont;
  18763.  
  18764. procedure SetFont(NewFont:GraficFont);
  18765. procedure WriteText(X,Y:integer;st:string);
  18766. procedure SetFontColor(bg,vg:byte);
  18767.  
  18768.  
  18769. implementation
  18770.  
  18771.  
  18772.  
  18773.  
  18774.  
  18775.  
  18776.  
  18777.  
  18778.  
  18779.  
  18780.  
  18781.  
  18782.  
  18783.  
  18784.  
  18785.  
  18786.  
  18787.  
  18788.  
  18789.  
  18790.  
  18791.  
  18792.  
  18793.  
  18794. Programmierhandbuch                                 WG-Vision - 362 -
  18795.  
  18796.  
  18797.  
  18798.  
  18799.  
  18800.  
  18801.  
  18802. (*****************************************************
  18803. *                                                    *
  18804. * WG-VISION 1.0    Expanded Memory Verwaltung        *
  18805. *                                                    *
  18806. ******************************************************
  18807. *                                                    *
  18808. *                                                    *
  18809. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  18810. *                                                    *
  18811. *****************************************************)
  18812.  
  18813. {$I COMPILER.INC}
  18814.  
  18815. unit WEMS;
  18816.  
  18817. interface
  18818.  
  18819. uses Crt,
  18820.      Dos;
  18821.  
  18822. var EMS_Installed:boolean;        {EMS-Speicher verfügbar ?}
  18823.     EMM_Version:string[3];        {EMS Versionsnummer}
  18824.     Error:word;                   {Fehler-Nummer}
  18825.     PageFrame:word;               {Segmentadresse des PageFrame}
  18826.     Pages:array[0..3] of word;    {Segmentadressen der physikalischen Seiten}
  18827.  
  18828. function HexString(Number:word):string;
  18829. function GetUnallocatedPages:word;
  18830. function GetFreePages:word;
  18831. function GetPageFrameAddress:word;
  18832. procedure MapPages(NumberPages,P1,P2,P3,P4:word;var Handle:word);
  18833. procedure ReMapPages(P1,P2,P3,P4,Handle:word);
  18834. function AllocatePages(NumberPages:word):word;
  18835. procedure DeAllocatePages(Handle:word);
  18836. procedure MapHandlePages(Handle:word;PhysicalPage,LogicalPage:byte);
  18837. function GetHandleCount:word;
  18838. function GetHandlePages(var Handle:word):word;
  18839.  
  18840. implementation
  18841.  
  18842.  
  18843.  
  18844. Programmierhandbuch                                 WG-Vision - 363 -
  18845.  
  18846.  
  18847.  
  18848.  
  18849.  
  18850.  
  18851.  
  18852. (*****************************************************
  18853. *                                                    *
  18854. * WG-VISION 1.0    Allgemeine Hilfsfunktionen        *
  18855. *                                                    *
  18856. ******************************************************
  18857. *                                                    *
  18858. *                                                    *
  18859. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  18860. *                                                    *
  18861. *****************************************************)
  18862.  
  18863. {$I COMPILER.INC}
  18864.  
  18865. unit WUTILS;
  18866.  
  18867. interface
  18868.  
  18869. uses WDecl,
  18870.      WDriver,
  18871.      Crt,
  18872.      Dos,
  18873.      Graph;
  18874.  
  18875.  
  18876. procedure FillBar(X1,Y1,X2,Y2:integer;Farbe1,Farbe2,Style:byte);
  18877. procedure FBar(X1,Y1,X2,Y2:integer;Farbe:byte);
  18878. procedure D3Frame(X1,Y1,X2,Y2:integer;C1,C2:byte);
  18879. procedure Beep(Dauer:integer);
  18880. function Exists(FName:string):boolean;
  18881. procedure DrawImage(X,Y:integer;FName:string);
  18882. function Trim(S:string):string;
  18883.  
  18884. implementation
  18885.  
  18886.  
  18887.  
  18888.  
  18889.  
  18890.  
  18891.  
  18892.  
  18893.  
  18894. Programmierhandbuch                                 WG-Vision - 364 -
  18895.  
  18896.  
  18897.  
  18898.  
  18899.  
  18900.  
  18901.  
  18902. (*****************************************************
  18903. *                                                    *
  18904. * WG-VISION 1.0    Zusatzzeichensätze im Grafikmodus *
  18905. *                  ROM-Zeichensätze                  *
  18906. *                  BGI-Vektorzeichensätze
  18907. *                                                    *
  18908. ******************************************************
  18909. *                                                    *
  18910. *                                                    *
  18911. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  18912. *                                                    *
  18913. *****************************************************)
  18914.  
  18915. {$I COMPILER.INC}
  18916.  
  18917. unit WFont;
  18918.  
  18919. interface
  18920.  
  18921. uses WDecl,
  18922.      Dos,
  18923.      Crt,
  18924.      Graph;
  18925.  
  18926.  
  18927. const DefaultFont   = 0;  {Pixel-Zeichensatz, entspricht ROM8x8 oder ROM8x16}
  18928.       TriplexFont   = 1;  {Vektor-Zeichensätze}
  18929.       SmallFont     = 2;
  18930.       SansSerifFont = 3;
  18931.       GothicFont    = 4;
  18932.       ScriptFont    = 5;
  18933.       SimpleFont    = 6;
  18934.       TSCRFont      = 7;
  18935.       LCOMFont      = 8;
  18936.       EuroFont      = 9;
  18937.       BoldFont      =10;
  18938.  
  18939.  
  18940.  
  18941.  
  18942.  
  18943.  
  18944. Programmierhandbuch                                 WG-Vision - 365 -
  18945.  
  18946.  
  18947.  
  18948.  
  18949.  
  18950.  
  18951.  
  18952.       Underline = 1;   {Schriftattribute für ROM-Zeichensätze}
  18953.       Bold      = 2;
  18954.       Small     = 3;
  18955.  
  18956. type FontType=record                    {Zeichensatzblock aus einer}
  18957.                 Name    : string[10];   {WG-Vision-Fontressource}
  18958.                 Points  : Char;
  18959.                 Data    : array[1..4096] of Char;
  18960.               end;
  18961.  
  18962.  
  18963.      PPixelFont=^TPixelFont;
  18964.      TPixelFont=object(TObject)
  18965.        Font      : FontType;          {User-Zeichensatz}
  18966.        ROMFont   : byte;              {Funktionsnummer des ROM-ZS}
  18967.        CharSize  : byte;              {Zeichenhöhe}
  18968.        constructor SetFont(F:string); {Zeichensatz installieren}
  18969.        destructor Done; virtual;      {Rücksetzen auf 8x8}
  18970.                                       {Standardzeichensatz}
  18971.        function GetFontName:string;   {Name des gerade aktiven Pixelfonts}
  18972.        procedure SetFontStyle(Style:byte);
  18973.      end;
  18974.  
  18975.      PVectorFont=^TVectorFont;
  18976.      TVectorFont=object(TObject)
  18977.        Font       : word;             {Nummer des aktiven Vektorfonts}
  18978.        Direction  : word;             {Ausrichtung}
  18979.        CharSize   : TPoint;           {Buchstabengröße, z,n}
  18980.        constructor SetVectorFont(F:word);  {Zeichensatz setzen}
  18981.        destructor Done; virtual;           {Default-Zeichensatz setzen}
  18982.        procedure SetCharSize(z,N:word);    {Zeichengröße definieren}
  18983.        procedure SetDirection(Dir:word);   {Ausgaberichtung festlegen}
  18984.      end;
  18985.  
  18986.  
  18987. implementation
  18988.  
  18989.  
  18990.  
  18991.  
  18992.  
  18993.  
  18994. Programmierhandbuch                                 WG-Vision - 366 -
  18995.  
  18996.  
  18997.  
  18998.  
  18999.  
  19000.  
  19001.  
  19002. (*****************************************************
  19003. *                                                    *
  19004. * WG-VISION 1.0    Kontextsensitives Hilfesystem     *
  19005. *                                                    *
  19006. ******************************************************
  19007. *                                                    *
  19008. *                                                    *
  19009. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  19010. *                                                    *
  19011. *****************************************************)
  19012.  
  19013. {$I COMPILER.INC}
  19014.  
  19015. unit WHelp;
  19016.  
  19017. interface
  19018.  
  19019. uses WDecl,
  19020.      WDriver,
  19021.      WViews,
  19022.      WDlg,
  19023.      WText,
  19024.      Graph;
  19025.  
  19026. type PHelpScroller=^THelpScroller;
  19027.      THelpScroller=object(TScroller)
  19028.        procedure CreateData(HelpDatei:string;HelpCtx:word);
  19029.        procedure ScrollDraw; virtual;
  19030.      end;
  19031.  
  19032.  
  19033.  
  19034.  
  19035.  
  19036.  
  19037.  
  19038.  
  19039.  
  19040.  
  19041.  
  19042.  
  19043.  
  19044. Programmierhandbuch                                 WG-Vision - 367 -
  19045.  
  19046.  
  19047.  
  19048.  
  19049.  
  19050.  
  19051.  
  19052.      PHelpWindow=^THelpWindow;
  19053.      THelpWindow=object(TWindow)
  19054.        HelpIndex:word;
  19055.        HelpDatei:string;
  19056.        Scroller:PHelpScroller;
  19057.        constructor Init(Datei:string;Hi:word;var Bounds:TRect;
  19058.                         ATitle:str80;AType:byte);
  19059.        procedure InitWindowScroller; virtual;
  19060.        destructor Done; virtual;
  19061.      end;
  19062.  
  19063. implementation
  19064.  
  19065.  
  19066.  
  19067.  
  19068.  
  19069.  
  19070.  
  19071.  
  19072.  
  19073.  
  19074.  
  19075.  
  19076.  
  19077.  
  19078.  
  19079.  
  19080.  
  19081.  
  19082.  
  19083.  
  19084.  
  19085.  
  19086.  
  19087.  
  19088.  
  19089.  
  19090.  
  19091.  
  19092.  
  19093.  
  19094. Programmierhandbuch                                 WG-Vision - 368 -
  19095.  
  19096.  
  19097.  
  19098.  
  19099.  
  19100.  
  19101.  
  19102. (*****************************************************
  19103. *                                                    *
  19104. * WG-VISION 1.0    Lesen und Schreiben von 16-       *
  19105. *                  farbigen PCX-Bildern              *
  19106. *                                                    *
  19107. *                  Nur für Standard-VGA 640x480x16 ! *
  19108. *                                                    *
  19109. ******************************************************
  19110. *                                                    *
  19111. *                                                    *
  19112. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  19113. *                                                    *
  19114. *****************************************************)
  19115.  
  19116. {$I COMPILER.INC}
  19117.  
  19118. unit WPCX;
  19119.  
  19120. interface
  19121.  
  19122. uses WDecl,
  19123.      Dos;
  19124.  
  19125. type TPCXImage=object
  19126.        T        : TRect;
  19127.        DX,Dy    : integer;
  19128.        FileName : PathStr;
  19129.        procedure Init(R:TRect;DName:PathStr);
  19130.        procedure LoadPCXImage(AddY:word);
  19131.      end;
  19132.  
  19133. function SavePCXImage(MinX,MinY,MaxX,MaxY:integer;Name:PathStr):integer;
  19134.  
  19135. implementation
  19136.  
  19137.  
  19138.  
  19139.  
  19140.  
  19141.  
  19142.  
  19143.  
  19144. Programmierhandbuch                                 WG-Vision - 369 -
  19145.  
  19146.  
  19147.  
  19148.  
  19149.  
  19150.  
  19151.  
  19152. (*****************************************************
  19153. *                                                    *
  19154. * WG-VISION 1.0    Speichern und Laden von 256-      *
  19155. *                  farbigen PCX-Bildern              *
  19156. *                                                    *
  19157. ******************************************************
  19158. * Verwendung nur in den VESA-Modi der Toolbox        *
  19159. ******************************************************
  19160. *                                                    *
  19161. *                                                    *
  19162. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  19163. *                                                    *
  19164. *****************************************************)
  19165.  
  19166.  
  19167. {$I COMPILER.INC}
  19168.  
  19169. unit W256PCX;
  19170.  
  19171. interface
  19172.  
  19173. uses WPalette,
  19174.      Dos,
  19175.      Graph;
  19176.  
  19177.  
  19178. type PCXheader = record
  19179.                    Creator : byte;    {10=Kennzeichen für PCX}
  19180.                    Version : byte;    {5=Version 3.0}
  19181.                    Encoding : byte;   {1=Runlength-Codierung}
  19182.                    Bits : byte;       {Bits pro Pixel}
  19183.                    xmin : word;       {Position Original-Bild}
  19184.                    ymin : word;
  19185.                    xmax : word;
  19186.                    ymax : word;
  19187.                    HRes : word;       {horizontale Auflösung}
  19188.                    VRes : word;       {vertikale Auflösung}
  19189.                    Palette16 : array[0..15, 0..2] of byte; {16 Farben-}
  19190.                                                            {Palette}
  19191.  
  19192.  
  19193.  
  19194. Programmierhandbuch                                 WG-Vision - 370 -
  19195.  
  19196.  
  19197.  
  19198.  
  19199.  
  19200.  
  19201.  
  19202.                    VMode : byte;                 {reserviert}
  19203.                    Planes : byte;                {Zahl der Ebenen}
  19204.                    BytePerLine : word;           {Bytes pro Zeile}
  19205.                    PaletteInfo : word;           {1=Farbe, 2=Schwarz/Weiß}
  19206.                    Dummy : array[0..57] of byte; {reserviert}
  19207.                  end;
  19208.  
  19209. type PictLine = record
  19210.                   Columns : word;
  19211.                   Lines   : word;
  19212.                   Pixels  : array[1..1280] of byte;
  19213.                 end;
  19214.  
  19215. procedure SavePCXImage(X1,Y1,X2,Y2:integer;Palette:tPalType;Name:string;
  19216.                        var Error:integer);
  19217. procedure LoadPCXImage(X1,Y1:integer;Name:string;var Error:integer);
  19218. function GetPCXErrorMsg(Error:word) : string;      { 530 <= Fehler <= 534 }
  19219.  
  19220.  
  19221. implementation
  19222.  
  19223.  
  19224.  
  19225.  
  19226.  
  19227.  
  19228.  
  19229.  
  19230.  
  19231.  
  19232.  
  19233.  
  19234.  
  19235.  
  19236.  
  19237.  
  19238.  
  19239.  
  19240.  
  19241.  
  19242.  
  19243.  
  19244. Programmierhandbuch                                 WG-Vision - 371 -
  19245.  
  19246.  
  19247.  
  19248.  
  19249.  
  19250.  
  19251.  
  19252. (*****************************************************
  19253. *                                                    *
  19254. * WG-VISION 1.0    Erweiterte Funktionen des         *
  19255. *                  Coprozessors 80387                *
  19256. *                                                    *
  19257. ******************************************************
  19258. *                                                    *
  19259. *                                                    *
  19260. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  19261. *                                                    *
  19262. *****************************************************)
  19263.  
  19264. {$I COMPILER.INC}
  19265.  
  19266. unit WCProc;
  19267.  
  19268. interface
  19269.  
  19270. function wgSin(X:Extended):Extended;
  19271. function wgCos(X:Extended):Extended;
  19272. function wgTan(X:Extended):Extended;
  19273. function wgCot(X:Extended):Extended;
  19274. function wgAtn(X:Extended):Extended;
  19275. function wgAsn(X:Extended):Extended;
  19276. function wgAcs(X:Extended):Extended;
  19277. function wgExp(X:Extended):Extended;
  19278. function wgPow(X,N:Extended):Extended;
  19279. function wgLog(X:Extended):Extended;
  19280. function wgLog10(X:Extended):Extended;
  19281.  
  19282.  
  19283. implementation
  19284.  
  19285.  
  19286.  
  19287.  
  19288.  
  19289.  
  19290.  
  19291.  
  19292.  
  19293.  
  19294. Programmierhandbuch                                 WG-Vision - 372 -
  19295.  
  19296.  
  19297.  
  19298.  
  19299.  
  19300.  
  19301.  
  19302. (*****************************************************
  19303. *                                                    *
  19304. * WG-VISION 1.0    Datei Ein- und Ausgabedialog      *
  19305. *                                                    *
  19306. ******************************************************
  19307. *                                                    *
  19308. *                                                    *
  19309. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  19310. *                                                    *
  19311. *****************************************************)
  19312.  
  19313. {$I COMPILER.INC}
  19314.  
  19315. unit WFileDlg;
  19316.  
  19317. interface
  19318.  
  19319. uses WDecl,
  19320.      WDlg,
  19321.      WViews,
  19322.      WEvent,
  19323.      WDriver,
  19324.      WUtils,
  19325.      Dos,
  19326.      Graph;
  19327.  
  19328. const msgLoadFile = 10;
  19329.       msgSaveFile = 11;
  19330.  
  19331. type PInputDialog=^TInputDialog;
  19332.      TInputDialog=object(TDlgWindow)
  19333.       Pfad     : PathStr;    {Originalpfad}
  19334.       Klick    : boolean;
  19335.       constructor Init(ATitle:str80;FMask:str12);
  19336.       destructor Done; virtual;
  19337.       procedure SetFileMask; virtual;
  19338.       procedure InitBackground; virtual;
  19339.       procedure SetPalette; virtual;
  19340.       procedure SetDateiListBox(X,Y,xl,yl:integer;Bez:str25;LScroller:word);
  19341.  
  19342.  
  19343.  
  19344. Programmierhandbuch                                 WG-Vision - 373 -
  19345.  
  19346.  
  19347.  
  19348.  
  19349.  
  19350.  
  19351.  
  19352.       procedure HandleEvent; virtual;
  19353.      end;
  19354.  
  19355.      POutputDialog=^TOutputDialog;
  19356.      TOutputDialog=object(TDlgWindow)
  19357.       constructor Init(ATitle:str80);
  19358.       procedure InitBackground; virtual;
  19359.       procedure SetPalette; virtual;
  19360.       procedure HandleEvent; virtual;
  19361.      end;
  19362.  
  19363.      PDateiListBox=^TDateiListBox;
  19364.      TDateiListBox=object(TListBox)
  19365.       procedure CreateDataList;
  19366.      end;
  19367.  
  19368.      PIDlgBgrd=^TIDlgBgrd;
  19369.      TIDlgBgrd=object(TBackground)
  19370.       procedure Draw; virtual;
  19371.      end;
  19372.  
  19373.      PODlgBgrd=^TODlgBgrd;
  19374.      TODlgBgrd=object(TBackground)
  19375.       procedure Draw; virtual;
  19376.      end;
  19377.  
  19378. var FileMask : str12;
  19379.  
  19380.  
  19381. implementation
  19382.  
  19383.  
  19384.  
  19385.  
  19386.  
  19387.  
  19388.  
  19389.  
  19390.  
  19391.  
  19392.  
  19393.  
  19394. Programmierhandbuch                                 WG-Vision - 374 -
  19395.  
  19396.  
  19397.  
  19398.  
  19399.  
  19400.  
  19401.  
  19402. (*****************************************************
  19403. *                                                    *
  19404. * WG-VISION 1.0    Druck-Dialoge, TLinePrint-Objekt  *
  19405. *                                                    *
  19406. ******************************************************
  19407. *                                                    *
  19408. *                                                    *
  19409. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  19410. *                                                    *
  19411. *****************************************************)
  19412.  
  19413. {$I COMPILER.INC}
  19414.  
  19415. unit WPrint;
  19416.  
  19417. interface
  19418.  
  19419. uses WDecl,
  19420.      WDlg,
  19421.      WViews,
  19422.      WUtils,
  19423.      WEvent,
  19424.      Printer,
  19425.      Graph,
  19426.      Crt,
  19427.      Dos;
  19428.  
  19429.  
  19430. type tDrOptData=record
  19431.                    Schalter  : string[12];
  19432.                    Header    : string[60];
  19433.                    LRand     : string[2];
  19434.                    RRand     : string[2];
  19435.                    ORand     : string[2];
  19436.                 end;
  19437.  
  19438.  
  19439.  
  19440.  
  19441.  
  19442.  
  19443.  
  19444. Programmierhandbuch                                 WG-Vision - 375 -
  19445.  
  19446.  
  19447.  
  19448.  
  19449.  
  19450.  
  19451.  
  19452.      tOptionData=record
  19453.                    Schalter  : string[8];
  19454.                    VonSeite  : string[3];
  19455.                    BisSeite  : string[3];
  19456.                  end;
  19457.  
  19458.      PLinePrint=^TLinePrint;
  19459.      TLinePrint=object
  19460.       AnzLines       : byte;     {Zeilen pro Seite}
  19461.       RLinks,RRechts : byte;     {rechter und linker Rand}
  19462.       ORand          : byte;     {oberer Rand = Abstand zur Kopfzeile}
  19463.       Breite         : byte;
  19464.       Zaehler        : word;     {Zeilenzähler}
  19465.       SZaehler       : word;     {Zeilenzähler in der Seite}
  19466.       Seite          : word;
  19467.       FromPage       : word;
  19468.       ToPage         : word;
  19469.       WNumber        : boolean;  {Zeilen-Nummerierung ja/nein}
  19470.       SetLine        : boolean;
  19471.       SetDate        : boolean;
  19472.       Kopfzeile      : string;
  19473.       Datum          : string;
  19474.       constructor Init(KZeile:string);
  19475.       destructor Done; virtual;
  19476.       function PrinterOk:boolean;
  19477.       procedure Print(Line:string);
  19478.       procedure SetLineNumberPrint(Yes:boolean);
  19479.       procedure SetSatzSpiegel(RL,RR,RO,ALines:byte);
  19480.       procedure SetParameters; virtual;
  19481.       procedure DefineHeaderText(KZeile:string);
  19482.       procedure Eject;
  19483.      end;
  19484.  
  19485.      PDruckBgrd=^TDruckBgrd;
  19486.      TDruckBgrd=object(TBackground)
  19487.       procedure Draw; virtual;
  19488.      end;
  19489.  
  19490.  
  19491.  
  19492.  
  19493.  
  19494. Programmierhandbuch                                 WG-Vision - 376 -
  19495.  
  19496.  
  19497.  
  19498.  
  19499.  
  19500.  
  19501.  
  19502.      POptionBgrd=^TOptionBgrd;
  19503.      TOptionBgrd=object(TBackground)
  19504.       procedure Draw; virtual;
  19505.      end;
  19506.  
  19507.      PDruckOptionen=^TDruckOptionen;
  19508.      TDruckOptionen=object(TDlgWindow)
  19509.       Original:tDrOptData;
  19510.       constructor Init;
  19511.       procedure InitBackground; virtual;
  19512.       procedure HandleEvent; virtual;
  19513.       procedure CM_SetOptionen;
  19514.      end;
  19515.  
  19516.     PPrintOptionWindow=^TPrintOptionWindow;
  19517.     TPrintOptionWindow=object(TDlgWindow)
  19518.      Original:tOptionData;
  19519.      constructor Init(X,Y:integer);
  19520.      procedure InitBackground; virtual;
  19521.      procedure HandleEvent; virtual;
  19522.     end;
  19523.  
  19524. var OptData:tDrOptData;
  19525.     Druckdata:tOptionData;
  19526.  
  19527. implementation
  19528.  
  19529.  
  19530.  
  19531.  
  19532.  
  19533.  
  19534.  
  19535.  
  19536.  
  19537.  
  19538.  
  19539.  
  19540.  
  19541.  
  19542.  
  19543.  
  19544. Programmierhandbuch                                 WG-Vision - 377 -
  19545.  
  19546.  
  19547.  
  19548.  
  19549.  
  19550.  
  19551.  
  19552. (*****************************************************
  19553. *                                                    *
  19554. * WG-VISION 1.0    ICON-Editor (16x16 und 32x32)     *
  19555. *                                                    *
  19556. ******************************************************
  19557. *                                                    *
  19558. *                                                    *
  19559. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  19560. *                                                    *
  19561. *****************************************************)
  19562.  
  19563. {$I COMPILER.INC}
  19564.  
  19565. unit WICNEDIT;
  19566.  
  19567. interface
  19568.  
  19569. uses WDecl,
  19570.      WViews,
  19571.      WDlg,
  19572.      WUtils,
  19573.      WEvent,
  19574.      WDriver,
  19575.      WFileDlg,
  19576.      Dos,
  19577.      Graph;
  19578.  
  19579.  
  19580. type PIconEdit=^TIconEdit;
  19581.      TIconEdit=object(TDlgWindow)
  19582.       IcnFName:PathStr; {Name der Icondatei}
  19583.       IcnDat:file;
  19584.       IcnSize:word;
  19585.       IcnAnz,IcnNr:byte;
  19586.       ITyp:byte;
  19587.       VG,HG:byte;       {aktive Vorder- und Hintergrundfarbe}
  19588.       InWork:boolean;   {Icon in Arbeit}
  19589.       constructor Init(X,Y:integer;IconFile:PathStr;IconTyp:byte);
  19590.       procedure InitBackground; virtual;
  19591.  
  19592.  
  19593.  
  19594. Programmierhandbuch                                 WG-Vision - 378 -
  19595.  
  19596.  
  19597.  
  19598.  
  19599.  
  19600.  
  19601.  
  19602.       procedure CM_SaveAs;
  19603.       procedure CM_Load;
  19604.       procedure HandleEvent; virtual;
  19605.      end;
  19606.  
  19607.      PIconEditBgrd=^TIconEditBgrd;
  19608.      TIconEditBgrd=object(TBackground)
  19609.       Great:boolean;
  19610.       constructor Init(R:TRect;ITyp:byte);
  19611.       procedure Draw; virtual;
  19612.      end;
  19613.  
  19614. var Icn16Puffer:array[1..16,1..16] of byte;
  19615.     Icn32Puffer:array[1..32,1..32] of byte;
  19616.  
  19617.  
  19618. implementation
  19619.  
  19620.  
  19621.  
  19622.  
  19623.  
  19624.  
  19625.  
  19626.  
  19627.  
  19628.  
  19629.  
  19630.  
  19631.  
  19632.  
  19633.  
  19634.  
  19635.  
  19636.  
  19637.  
  19638.  
  19639.  
  19640.  
  19641.  
  19642.  
  19643.  
  19644. Programmierhandbuch                                 WG-Vision - 379 -
  19645.  
  19646.  
  19647.  
  19648.  
  19649.  
  19650.  
  19651.  
  19652. (*****************************************************
  19653. *                                                    *
  19654. * WG-VISION 1.0    Taschenrechner                    *
  19655. *                                                    *
  19656. ******************************************************
  19657. *                                                    *
  19658. *                                                    *
  19659. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  19660. *                                                    *
  19661. *****************************************************)
  19662.  
  19663. {$I COMPILER.INC}
  19664.  
  19665. unit WCalc;
  19666.  
  19667. interface
  19668.  
  19669. uses WDecl,
  19670.      WEvent,
  19671.      WDriver,
  19672.      WViews,
  19673.      WDlg,
  19674.      Graph;
  19675.  
  19676. type tCalcState=(calcOK,calcValid,calcError);
  19677.  
  19678.      PCalculator=^TCalculator;
  19679.      TCalculator=object(TDlgWindow)
  19680.       Status:tCalcState;
  19681.       Zahl:string[15];
  19682.       Sign:Char;                               {Vorzeichen}
  19683.       Operator:Char;
  19684.       Operand:Single;
  19685.       constructor Init;
  19686.       procedure SetPalette; virtual;
  19687.       procedure InitBackground; virtual;
  19688.       procedure Berechne(Key:Char);
  19689.       procedure ClearDisplay;
  19690.  
  19691.  
  19692.  
  19693.  
  19694. Programmierhandbuch                                 WG-Vision - 380 -
  19695.  
  19696.  
  19697.  
  19698.  
  19699.  
  19700.  
  19701.  
  19702.       procedure DrawDisplay;
  19703.       procedure Draw; virtual;
  19704.       procedure HandleEvent; virtual;
  19705.      end;
  19706.  
  19707.      PCalcBackground=^TCalcBackground;
  19708.      TCalcBackground=object(TBackground)
  19709.       procedure Draw; virtual;
  19710.      end;
  19711.  
  19712.  
  19713. implementation
  19714.  
  19715.  
  19716.  
  19717.  
  19718.  
  19719.  
  19720.  
  19721.  
  19722.  
  19723.  
  19724.  
  19725.  
  19726.  
  19727.  
  19728.  
  19729.  
  19730.  
  19731.  
  19732.  
  19733.  
  19734.  
  19735.  
  19736.  
  19737.  
  19738.  
  19739.  
  19740.  
  19741.  
  19742.  
  19743.  
  19744. Programmierhandbuch                                 WG-Vision - 381 -
  19745.  
  19746.  
  19747.  
  19748.  
  19749.  
  19750.  
  19751.  
  19752. (*****************************************************
  19753. *                                                    *
  19754. * WG-VISION 1.0       Digitaluhr                     *
  19755. *                                                    *
  19756. ******************************************************
  19757. *                                                    *
  19758. *                                                    *
  19759. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  19760. *                                                    *
  19761. *****************************************************)
  19762.  
  19763. {$I COMPILER.INC}
  19764.  
  19765. unit WUhr;
  19766.  
  19767. interface
  19768.  
  19769. uses WDecl,
  19770.      WViews,
  19771.      WDlg,
  19772.      WDriver,
  19773.      Dos,
  19774.      Graph;
  19775.  
  19776. type PDigitalUhr=^TDigitalUhr;
  19777.      TDigitalUhr=object(TWindow)
  19778.       constructor Init(X,Y:integer);
  19779.       procedure SetPalette; virtual;
  19780.       procedure InitBackground; virtual;
  19781.       procedure HandleEvent; virtual;
  19782.      end;
  19783.  
  19784.  
  19785.  
  19786.  
  19787.  
  19788.  
  19789.  
  19790.  
  19791.  
  19792.  
  19793.  
  19794. Programmierhandbuch                                 WG-Vision - 382 -
  19795.  
  19796.  
  19797.  
  19798.  
  19799.  
  19800.  
  19801.  
  19802.      PUhrBgrd=^TUhrBgrd;
  19803.      TUhrBgrd=object(TBackground)
  19804.       Stunde  : word;
  19805.       Minute  : word;
  19806.       Sekunde : word;
  19807.       procedure Draw; virtual;
  19808.      end;
  19809.  
  19810. implementation
  19811.  
  19812.  
  19813.  
  19814.  
  19815.  
  19816.  
  19817.  
  19818.  
  19819.  
  19820.  
  19821.  
  19822.  
  19823.  
  19824.  
  19825.  
  19826.  
  19827.  
  19828.  
  19829.  
  19830.  
  19831.  
  19832.  
  19833.  
  19834.  
  19835.  
  19836.  
  19837.  
  19838.  
  19839.  
  19840.  
  19841.  
  19842.  
  19843.  
  19844. Programmierhandbuch                                 WG-Vision - 383 -
  19845.  
  19846.  
  19847.  
  19848.  
  19849.  
  19850.  
  19851.  
  19852. (*****************************************************
  19853. *                                                    *
  19854. * WG-VISION 1.0    Palettenmanipulation und          *
  19855. *                  Paletteneditor für die 256-       *
  19856. *                  farbigen VESA-Modi                *
  19857. *                                                    *
  19858. ******************************************************
  19859. *                                                    *
  19860. *                                                    *
  19861. * (c) 1992/93 Dipl.Phys. Mathias Scholz              *
  19862. *                                                    *
  19863. *****************************************************)
  19864.  
  19865. {$I COMPILER.INC}
  19866.  
  19867. unit WPalette;
  19868.  
  19869. interface
  19870.  
  19871. uses WDecl,
  19872.      WDriver,
  19873.      WViews,
  19874.      WDlg,
  19875.      WUtils,
  19876.      WEvent,
  19877.      WFileDlg,
  19878.      Crt,
  19879.      Dos,
  19880.      Graph;
  19881.  
  19882.  
  19883. type tRGB=record
  19884.            R,G,B:byte;
  19885.           end;
  19886.  
  19887.      tPalType=array[0..255] of tRGB;
  19888.  
  19889.  
  19890.  
  19891.  
  19892.  
  19893.  
  19894. Programmierhandbuch                                 WG-Vision - 384 -
  19895.  
  19896.  
  19897.  
  19898.  
  19899.  
  19900.  
  19901.  
  19902.      PPalette=^TPalette;
  19903.      TPalette=object
  19904.       F    : file;                      {Palettendatei}
  19905.       LUT  : tPalType;                  {Look-Up Table}
  19906.       ALUT : tPalType;                  {angepaßte Palette für PCX-Bilder}
  19907.       CLUT : array[1..10] of tPalType;
  19908.       procedure SetPaletteColor(Nr,Rot,Gruen,Blau:byte);
  19909.       procedure GetPaletteColor(var Nr,Rot,Gruen,Blau:byte);
  19910.       procedure GetPalette;
  19911.       procedure SetPalette;
  19912.       procedure AdaptPalette;
  19913.       procedure SetNewPalette(NLUT:tPalType);
  19914.       procedure LoadPalette(FName:PathStr);
  19915.       procedure SavePalette(FName:PathStr);
  19916.       procedure RotatePalette(Typ,Direction:byte);
  19917.       procedure RotatePart(Direction,Von,Bis:byte);
  19918.       procedure SetVerlauf(Nr1,Rot1,Gruen1,Blau1,Nr2,Rot2,Gruen2,Blau2:byte);
  19919.       procedure TransformRGBtoHSV(R,G,B:byte;var H,S,V:Single);
  19920.       procedure TransformHSVtoRGB(H,S,V:Single;var R,G,B:byte);
  19921.       procedure TransformtoGrayScale(Nr,Number:byte);
  19922.       procedure StretchScale(Minimalwert,Maximalwert,Delta:byte;
  19923.                              Positiv:boolean);
  19924.       procedure StretchPolynom(Minimalwert,Maximalwert:byte;
  19925.                                Degree:Single;Positiv:boolean);
  19926.       procedure StretchColor(Minimalwert,Maximalwert:integer);
  19927.       procedure Isophote(Delta,Brightness:byte;Positiv:boolean);
  19928.       procedure Aequidensiten(Delta,Abstand:byte;Positiv:boolean);
  19929.      end;
  19930.  
  19931.      PGrayBar=^TGrayBar;
  19932.      TGrayBar=object(TWindow)
  19933.       Pal:TPalette;
  19934.       constructor Init(X,Y:integer);
  19935.       procedure InitBackground; virtual;
  19936.      end;
  19937.  
  19938.  
  19939.  
  19940.  
  19941.  
  19942.  
  19943.  
  19944. Programmierhandbuch                                 WG-Vision - 385 -
  19945.  
  19946.  
  19947.  
  19948.  
  19949.  
  19950.  
  19951.  
  19952.      PPalWorkShop=^TPalWorkShop;
  19953.      TPalWorkShop=object(TDlgWindow)
  19954.       Pal:TPalette;
  19955.       KlickArea:TRect;
  19956.       LastColor:byte;
  19957.       Hu,Sa,Va:Single;                {aktueller HSV-Wert}
  19958.       rgbRed,rgbGreen,rgbBlue:byte;   {aktueller RGB-Wert}
  19959.       constructor Init(X,Y:integer);
  19960.       procedure InitBackground; virtual;
  19961.       procedure CM_SaveAs;
  19962.       procedure CM_Load;
  19963.       procedure HandleEvent; virtual;
  19964.      end;
  19965.  
  19966.      PScale=^TScale;
  19967.      TScale=object(TDlgWindow)
  19968.       Pal:TPalette;
  19969.       StretchMode:byte;
  19970.       constructor Init(X,Y:integer;What:byte);
  19971.       procedure InitBackground; virtual;
  19972.       procedure HandleEvent; virtual;
  19973.      end;
  19974.  
  19975.      PColorBar=^TColorBar;
  19976.      TColorBar=object(TBackground)
  19977.       procedure Draw; virtual;
  19978.      end;
  19979.  
  19980.      PPWorkShopBgrd=^TPWorkShopBgrd;
  19981.      TPWorkShopBgrd=object(TBackground)
  19982.       procedure Draw; virtual;
  19983.      end;
  19984.  
  19985.  
  19986.  
  19987.  
  19988.  
  19989.  
  19990.  
  19991.  
  19992.  
  19993.  
  19994. Programmierhandbuch                                 WG-Vision - 386 -
  19995.  
  19996.  
  19997.  
  19998.  
  19999.  
  20000.  
  20001.  
  20002.      PScaleBgrd=^TScaleBgrd;
  20003.      TScaleBgrd=object(TBackground)
  20004.       procedure Draw; virtual;
  20005.      end;
  20006.  
  20007. var StretchL,StretchR:byte;
  20008.     PExponent:Single;
  20009.     PositivMode:boolean;
  20010.  
  20011.  
  20012. implementation
  20013.