home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1991 / 01 / pm_kurs / scroll3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-26  |  45.2 KB  |  1,298 lines

  1. /*****************************************************/
  2. /*                                                   */
  3. /*                 SCROLL3.c                         */
  4. /*                                                   */
  5. /*             (C) 1990 J. Heid & toolbox            */
  6. /*                                                   */
  7. /*  3. Version zur Demonstration des Scrollbars      */
  8. /*                                                   */
  9. /*  - Demonstriert, wie man mit Scrollbars einen     */
  10. /*    Text beliebiger Groesse anzeigen kann.         */
  11. /*  - Der Text wird mit DosGetResource geladen.      */
  12. /*    In unserem Fall enthaelt die Text-Resource-    */
  13. /*    Datei "PANTHER.asc" das Gedicht "Der Panther"  */
  14. /*    von Rainer Maria Rilke.                        */
  15. /*  - Das Fenster wird mit WinScrollWindow gescrollt.*/
  16. /*  - Unter OS/2 1.2 sind die Scrollbars variabel    */
  17. /*    lang - trotzdem kann der Quellcode unveraendert*/
  18. /*    auch unter 1.1 compiliert werden.              */
  19. /*  - Die Scrollbars sind nicht permanent vorhanden, */
  20. /*    sondern werden nur dann erzeugt, wenn der Text */
  21. /*    nicht ganz in das Fenster passt.               */
  22. /*  - Der Actionbar bietet den Eintrag               */
  23. /*    "Exit und Info".                               */
  24. /*  - Als Akzeleratortasten sind wirksam:            */
  25. /*      F3     : beendet das Programm                */
  26. /*      Ctrl-I : zeigt Informationen zum Programm    */
  27. /*  - Die Windowprozedur ClientWndProc behandelt     */
  28. /*    explizit die folgenden 7 Events:               */
  29. /*        WM_CREATE,   WM_SIZE,     WM_PAINT,        */
  30. /*        WM_COMMAND,  WM_VSCROLL,  WM_HSCROLL,      */
  31. /*        WM_CHAR.                                   */
  32. /*                                                   */
  33. /*                                                   */
  34. /*  Funktionen:                                      */
  35. /*  -----------                                      */
  36. /*  SCROLL3.c besteht aus 8 Funktionen, die sich     */
  37. /*  in ff. Weise aufrufen:                           */
  38. /*                                                   */
  39. /*          1 main                                   */
  40. /*          2 |  WndCreate                           */
  41. /*                                                   */
  42. /*          3 ClientWindowProc                       */
  43. /*          4 |  AusgabeBox                          */
  44. /*          5 |  SaveLineInfo                        */
  45. /*          6 |  |  AusgabeBox  { 4 }                */
  46. /*          7 |  |  FrageBox                         */
  47. /*          8 |  SaveLineInfo   { 5 }                */
  48. /*          9 |  GetOS2Version                       */
  49. /*         10 |  PaintWin                            */
  50. /*         11 |  AusgabeBox     { 4 }                */
  51. /*                                                   */
  52. /*                                                   */
  53. /*                                                   */
  54. /*  Benoetigte Dateien:                              */
  55. /*  -------------------                              */
  56. /*    SCROLL3.c      - Quellcode-Datei               */
  57. /*    SCROLL3.h      - Header-Datei                  */
  58. /*    SCROLL3.def    - Modul-Definitions-Datei       */
  59. /*    SCROLL3.mak    - Make-Datei                    */
  60. /*    SCROLL3.rc     - Resource-Datei                */
  61. /*    PANTHER.asc    - Text-Resource-Datei           */
  62. /*                                                   */
  63. /*                                                   */
  64. /*****************************************************/
  65.  
  66. #define INCL_WIN
  67. #define INCL_GPI
  68. #define INCL_DOS   // sonst wird DosGetResource beim
  69.                    // Linken nicht gefunden
  70. #include <os2.h>   // PM-Include-Datei
  71.  
  72. #include <stdio.h>
  73. #include <string.h>
  74. #include <stdlib.h>
  75.  
  76. #include "scroll3.h"   // Symbol. Konstanten fuer
  77.                        //   scroll3.c und scroll3.rc
  78.  
  79. #define  BEGIN_V_RANGE     0   // Standardwerte fuer
  80. #define  BEGIN_H_RANGE     0   //  den Scrollbereich
  81. #define  EINRUECKUNG       3   // linker Rand
  82.  
  83.  
  84. /*****************************************************/
  85. /* Funktions-Prototypen                              */
  86. /*****************************************************/
  87. int     cdecl    main(             VOID );
  88. BOOL             WndCreate(        VOID );
  89. MRESULT EXPENTRY ClientWindowProc( HWND   hwnd,
  90.                                    USHORT msg,
  91.                                    MPARAM mp1,
  92.                                    MPARAM mp2 );
  93. VOID             PaintWin(         HWND hwnd);
  94. VOID             AusgabeBox(       VOID );
  95. BOOL             FrageBox(         VOID );
  96. int              SaveLineInfo(     HWND  hwnd,
  97.                                    SHORT sLineNo,
  98.                                    SHORT sLineLength,
  99.                                    PCHAR pText );
  100. BOOL             GetOS2Version(    VOID );
  101.  
  102.  
  103.  
  104. /*****************************************************/
  105. /* globale Variablen                                 */
  106. /*****************************************************/
  107. HAB   hab;                     // Programmanker
  108. CHAR  szClientClass[] = "KlasseScroll3";   // Name der
  109.                                //         Fensterklasse
  110. HWND  hwndFrame;      // Handle fuer das Frame-Fenster
  111. HWND  hwndClient;     // Handle fuer den Client-Bereich
  112.  
  113. SHORT sVStart = BEGIN_V_RANGE, // Scrollbereichsgrenzen
  114.       sVEnd,                   // und Sliderpositionen
  115.       sVPos  ;                 // fuer den vertikalen
  116. SHORT sHStart = BEGIN_H_RANGE, // und horizontalen
  117.       sHEnd  ,                 // Scrollbar
  118.       sHPos  ;
  119. BOOL  bVScroll = FALSE;        // TRUE, wenn der senkr.
  120.                                //   Scroll existiert.
  121. BOOL  bHScroll = FALSE;        // TRUE, wenn der waagr.
  122.                                //   Scroll existiert.
  123.  
  124. SHORT cxChar,        // Groessen des aktuellen Fonts
  125.       cxCaps,        //  ( benoetigte Teile der
  126.       cyChar,        //    FONTMETRICS-Struktur )
  127.       cyDesc;
  128.  
  129. CHAR  szQuelldatei[255]; // Name der Resource-Datei
  130.                          // fuer den Text
  131. CHAR  szBoxText[255];  // enthalten Text und Titel fuer
  132. PSZ   szBoxTitel;      // die Ausgabe in der Messagebox
  133.  
  134. BOOL  bPixelweise = FALSE;  // TRUE, wenn horizontal
  135.                             // pixelweise zu scrollen
  136. SHORT cxClient,        // Ausdehnung des Clientbereichs
  137.       cyClient ;
  138.  
  139. SHORT sLongestRow = 0;    // Nummer der laengsten Zeile
  140. SHORT sTextCols = 0;      // Anzahl der Spalten im Text
  141. SHORT sTextRows = 0;      // Anzahl der Zeilen im Text
  142. PCHAR pResource ;         // Zeiger auf Textresource
  143. ULONG ulSegSize ;         // Laenge der Textresource
  144.  
  145.      // ist TRUE, wenn die aktuelle OS/2-Version
  146.      //       groessenveraenderbare Slider unterstuetzt
  147. BOOL bSliderResizable = FALSE;
  148.  
  149. USHORT usMajorVersion;    // 10: OS/2 1.1 und OS/2 1.2
  150. USHORT usMinorVersion;    // 10: OS/2 1.1 ,
  151.                           // 20: OS/2 1.2
  152.  
  153.  
  154. int    rc;                // Hilfsvariablen zum Pruefen
  155. BOOL   brc;               //   der Rueckgabewerte der
  156. SHORT  src;               //   API-Funktionen
  157. USHORT usrc;
  158.  
  159.  
  160. typedef struct TEXTPOINTER // Zeilenweise Informationen
  161. {                          // zu dem Text aus der
  162.   SHORT sLineNumber;       // Textresourcedatei:
  163.   SHORT sLineLength;       // Zeilennummer, -laenge
  164.   PCHAR pTextplace;        // und Zeiger auf Zeilen-
  165. } TEXTPOINTER;             // anfang
  166. TEXTPOINTER *apstructText;
  167.  
  168.  
  169.  
  170. // Formatstrings fuer die Meldungen per szBoxText
  171. static CHAR * apchFormatTable [] =
  172. {
  173.   /* 0 */
  174.   "Abbruch in WM_CREATE. \
  175.   \n\nDie Textresource konnte nicht geladen werden. \
  176.   \n\nRueckgabewert von DosGetResource: %d.",
  177.  
  178.   /* 1 */   // horizontal pixelweise scrollen..........
  179.   "Das Programm gibt den Text aus, der in der \
  180.   \nResource-Datei \"%s\" steht. \
  181.   \n\nDer Text besteht aus %d Zeilen. \
  182.   \nDie laengste Zeile (Index %d) hat %d Pixel. \
  183.   \n\nInnerhalb dieses Textes kann per Maus und \
  184.   \nTastatur gescrollt werden." ,
  185.  
  186.   /* 2 */   // horizontal zeichenweise scrollen........
  187.   "Das Programm gibt den Text aus, der in der \
  188.   \nResource-Datei \"%s\" steht. \
  189.   \n\nDer Text besteht aus %d Zeilen. \
  190.   \nDie laengste Zeile (Index %d) hat %d Zeichen. \
  191.   \n\nInnerhalb dieses Textes kann per Maus und \
  192.   \nTastatur gescrollt werden." ,
  193.  
  194.   /* 3 */
  195.   "Man konnte mit malloc nicht genug Speicher \
  196.   \nfuer die Struktur apstructText besorgen. \
  197.   \n\nDas Programm terminiert deshalb. \
  198.   \n\nDer Text hatte eine Laenge von %d Zeichen."
  199. };
  200.  
  201.  
  202.  
  203. /*-------  Start der main-Funktion  -----------------*/
  204. /*                                                   */
  205. /* - initialisiert und terminiert                    */
  206. /* - enthaelt Message-Loop                           */
  207. /*                                                   */
  208. /* - globale Variable:                               */
  209. /*    definiert: hab.                                */
  210. /*    referiert: hwndFrame.                          */
  211. /* - ruft: WndCreate()                               */
  212. /*                                                   */
  213. /*---------------------------------------------------*/
  214. int cdecl main ( VOID )
  215. {
  216.   HMQ   hmq;          // Handle fuer die Message-Queue
  217.   QMSG  qmsg;         // Message in der Message-Queue
  218.  
  219.   hab = WinInitialize( 0 );         // Initialisiere PM
  220.   hmq = WinCreateMsgQueue( hab, 0 );// Erzeuge
  221.                                     //    Message-Queue
  222.  
  223.  
  224.  
  225.   if ( hmq != (HMQ)NULL )
  226.   {
  227.     if ( WndCreate() == TRUE )
  228.     {
  229.       /***********************************************/
  230.       /* "Message-processing-Loop":                  */
  231.       /* Empfaengt und verteilt Messages aus der     */
  232.       /* Message-Queue der Anwendung, bis WinGetMsg  */
  233.       /* FALSE zurueckgibt: dies geschieht dann, wenn*/
  234.       /* WinGetMsg eine WM_QUIT-Message erhielt.     */
  235.       /***********************************************/
  236.       while( WinGetMsg( hab, (PQMSG)&qmsg,
  237.                         (HWND)NULL, 0, 0 )
  238.             )
  239.         WinDispatchMsg( hab, (PQMSG)&qmsg );
  240.  
  241.       WinDestroyWindow( hwndFrame );
  242.     }
  243.     WinDestroyMsgQueue( hmq );
  244.   }
  245.   WinTerminate( hab );
  246.  
  247.   return 0;
  248. }
  249. /*-------  Ende der main-Funktion  ------------------*/
  250.  
  251.  
  252.  
  253.  
  254. /*-------  Start der WndCreate-Funktion -------------*/
  255. /*                                                   */
  256. /* - registriert die Fensterklasse des Client.       */
  257. /* - erzeugt das Standardfenster.                    */
  258. /*                                                   */
  259. /* - globale Variable:                               */
  260. /*    definiert: hwndClient, hwndFrame.              */
  261. /*    referiert: hab, szClientClass, hwndFrame.      */
  262. /* - aufgerufen von: main()                          */
  263. /* - Return: - TRUE,  wenn alles klappt              */
  264. /*           - FALSE, wenn etwas schiefging.         */
  265. /*                    Dann bricht main() ab.         */
  266. /*---------------------------------------------------*/
  267. BOOL WndCreate( VOID )
  268. {
  269.   static CHAR  szTitleBar [40] ;
  270.   ULONG  flCreateFrame; // Flaggen fuer die Erzeugung
  271.                         //         der Frame-Controls
  272.  
  273.   // usrc = Stringlaenge ohne ASCII-Null..............
  274.   //      = 0, wenn Fehler auftaucht !
  275.   usrc = WinLoadString ( hab,
  276.                          (HMODULE)NULL,
  277.                          IDS_TITLE,
  278.                          sizeof (szTitleBar),
  279.                          (PSZ)szTitleBar) ;
  280.   if ( usrc == 0 ) return FALSE;
  281.  
  282.   // usrc = Stringlaenge ohne ASCII-Null..............
  283.   //      = 0, wenn Fehler auftaucht !
  284.   usrc = WinLoadString ( hab,
  285.                          (HMODULE)NULL,
  286.                          IDS_FILE,
  287.                          sizeof (szQuelldatei),
  288.                          (PSZ)szQuelldatei ) ;
  289.   if ( usrc == 0 ) return FALSE;
  290.  
  291.  
  292.   // Ordne die ClientWndProc einer Klasse zu...........
  293.   brc = WinRegisterClass(
  294.           hab,              // Programmanker
  295.           szClientClass,    // Name der Fensterklasse
  296.           ClientWindowProc, // Adr. der Fensterprozedur
  297.           CS_SIZEREDRAW,    // Klassen-Style
  298.           0                 // keine Extra-Bytes
  299.                             //    reservieren
  300.           );
  301.  
  302.   // wenn WinRegisterClass nicht erfolgreich...........
  303.   if ( brc == FALSE ) return FALSE;
  304.  
  305.   // Standardfenster erzeugen: mit Actionbar und mit
  306.   //   Akzeleratortabelle, aber ohne Scrollbars wie in
  307.   //   SCROLL2.c (dort existieren die Scrollbars immer)
  308.   flCreateFrame = FCF_STANDARD & ~FCF_ICON;
  309.  
  310.   // Erzeugen eines Standardfensters...................
  311.   hwndFrame = WinCreateStdWindow(
  312.  
  313.            HWND_DESKTOP,   // Handle des Vaterfensters
  314.            WS_VISIBLE,     // Style des Frame-Fensters
  315.            (PULONG)&flCreateFrame,
  316.            szClientClass,  // Client-Fenster-Klasse
  317.            szTitleBar,     // Titel-Erweiterung
  318.            0L,             // Style des Client-Fensters
  319.            (HMODULE)NULL,// Resourcen sind in EXE-Datei
  320.            ID_RESOURCE,    // Bezeichner fuer Resourcen
  321.            (PHWND)&hwndClient // Zeiger auf den Handle
  322.                               //    des Client-Fensters
  323.            );
  324.  
  325.   // wenn WinCreateStdWindow nicht erfolgreich.........
  326.   if ( hwndFrame == (HWND)NULL ) return FALSE;
  327.  
  328.   return TRUE;
  329.  
  330. }
  331. /*-------  Ende der WndCreate-Funktion --------------*/
  332.  
  333.  
  334.  
  335. /*-------  Start der Window-Prozedur des Client -----*/
  336. /*                                                   */
  337. /* - behandelt die Reaktionen des Clientfensters     */
  338. /* - explizit behandelte Events:                     */
  339. /*    WM_CREATE,  WM_SIZE,    WM_PAINT, WM_COMMAND,  */
  340. /*    WM_VSCROLL, WM_HSCROLL, WM_CHAR.               */
  341. /*                                                   */
  342. /* - globale Variable:                               */
  343. /*    definiert: ...                                 */
  344. /*    referiert: ...                                 */
  345. /*                                                   */
  346. /* - aufgerufen von: Presentation Manager            */
  347. /* - ruft: in WM_CREATE:  SaveLineInfo, AusgabeBox,  */
  348. /*                        GetOS2Version              */
  349. /*         in WM_PAINT:   PaintWin                   */
  350. /*         in WM_COMMAND: AusgabeBox                 */
  351. /*---------------------------------------------------*/
  352. MRESULT EXPENTRY ClientWindowProc( HWND hwnd,
  353.                                    USHORT msg,
  354.                                    MPARAM mp1,
  355.                                    MPARAM mp2 )
  356. {
  357.   HPS    hps;              // Presentation-Space-Handle
  358.   FONTMETRICS fm;          // Struktur mit Attributen
  359.                            //   des aktuellen Fonts
  360.   static HWND hwndVScroll; // Handle fuer den
  361.                            //   vertikalen Scrollbar
  362.   static HWND hwndHScroll; // Handle fuer den
  363.                            //   horizontalen Scrollbar
  364.   SHORT  sVDelta,          // durch WM_VSCROLL und
  365.          sHDelta;          //   WM_HSCROLL vorgesehene
  366.                            //   Aenderung von sVPos
  367.                            //   und sHPos
  368.  
  369.   SEL           selResource ; // static, wenn man die
  370.                               // Resource in WM_DESTROY
  371.                               // explizit zerstoert.
  372.   PCHAR         pText ;
  373.   PCHAR         pTextLauf, pTextAnfang ;
  374.   SHORT         sLineLength;
  375.   static SHORT  sNumLines = 0;
  376.   static SHORT  sLineNo = 0;
  377.   static int    firstWM_SIZE = 1;
  378.  
  379.   USHORT usVKey;    // Komponente der WM_CHAR-Message
  380.   USHORT command;   // Command-Wert bei WM_COMMAND =
  381.                     // ID des gewaehlten Menueeintrags
  382.  
  383.  
  384.   switch( msg )
  385.   {
  386.  
  387.     case WM_CREATE:
  388.       /***********************************************/
  389.       /* - laedt die Textresourcen:                  */
  390.       /*     ist das nicht moeglich, wird das        */
  391.       /*     Programm abgebrochen!                   */
  392.       /* - speichert die Textwerte:                  */
  393.       /*   Gesamtgroesse und Anfangsadresse in       */
  394.       /*     ulSegSize und pResource,                */
  395.       /*   Zeilennummer, Zeilenlaenge und den Zeiger */
  396.       /*     auf den Zeilenanfang in apstructText.   */
  397.       /* - bestimmt die Attribute des aktuellen      */
  398.       /*   Fonts: die davon benoetigten Teile werden */
  399.       /*   in den globalen Variablen cxChar,         */
  400.       /*   cxCaps, cyChar und cyDesc abgelegt.       */
  401.       /***********************************************/
  402.  
  403.       // Laden der Textresource .......................
  404.       //   usrc ist 0, wenn successful !
  405.       usrc = DosGetResource ( (HMODULE)NULL,
  406.                               IDT_TEXT,
  407.                               IDT_GEDICHT,
  408.                               &selResource );
  409.       if ( usrc != 0 )
  410.       {
  411.         sprintf( szBoxText, apchFormatTable[0], usrc);
  412.         szBoxTitel = "Programmabbruch";
  413.         AusgabeBox();
  414.  
  415.         return (MRESULT)TRUE;
  416.       }
  417.  
  418.  
  419.       // Bestimme Groesse und Adresse der Resource ....
  420.       usrc = DosSizeSeg (selResource, &ulSegSize) ;
  421.       if ( usrc != 0 )
  422.         return (MRESULT)TRUE;
  423.  
  424.       pResource = MAKEP (selResource, 0) ;
  425.  
  426.  
  427.       // Bestimme die Anzahl der Zeilen in der
  428.       //   Textresource-Datei .........................
  429.       //   ( 1. Durchlauf )   .........................
  430.       pText = pResource ;
  431.  
  432.       //while ( pText - pResource < (USHORT)ulSegSize )
  433.       while ( pText - pResource < (int)ulSegSize )
  434.       {
  435.         if (*pText == '\r')
  436.           sNumLines ++ ;
  437.  
  438.         pText++ ;
  439.       }
  440.       sTextRows = sNumLines + 1;
  441.  
  442.  
  443.       // Bestimme Zeilennummer, Zeilenlaenge und den
  444.       //   Zeiger auf den Zeilenanfang .............
  445.       //   ( 2. Durchlauf ) ........................
  446.  
  447.       pTextLauf   = pResource ;
  448.       pTextAnfang = pResource ;
  449.       sLineLength = 0 ;
  450.  
  451.       //while (pTextLauf - pResource < (USHORT)ulSegSize)
  452.       while (pTextLauf - pResource < (int)ulSegSize)
  453.       {
  454.         if (*pTextLauf == '\r')
  455.         {
  456.           rc = SaveLineInfo( hwnd,
  457.                              sLineNo,
  458.                              max( 0, sLineLength-2 ),
  459.                              pTextAnfang );
  460.           if ( rc == -1 )
  461.             return (MRESULT)TRUE;
  462.  
  463.           sLineNo ++ ;
  464.           pTextAnfang = pTextLauf + 2;
  465.  
  466.           sLineLength = 0 ;
  467.         }
  468.  
  469.         pTextLauf++ ;
  470.         sLineLength ++ ;
  471.       }
  472.  
  473.       rc = SaveLineInfo( hwnd,
  474.                          sLineNo,
  475.                          max( 0, sLineLength-2 ),
  476.                          pTextAnfang );
  477.       if ( rc == -1 )
  478.         return (MRESULT)TRUE;
  479.  
  480.  
  481.       // Bestimme Fontinformationen...................
  482.       hps = WinGetPS( HWND_DESKTOP );
  483.         brc = GpiQueryFontMetrics( hps,
  484.                                    (LONG)sizeof( fm ),
  485.                                    &fm );
  486.       WinReleasePS( hps );
  487.  
  488.       cxChar = (SHORT) fm.lAveCharWidth;
  489.       cxCaps = (SHORT) fm.lEmInc;
  490.       cyChar = (SHORT) fm.lMaxBaselineExt;
  491.       cyDesc = (SHORT) fm.lMaxDescender;
  492.  
  493.  
  494.  
  495.       // Bestimme die OS/2-Version....................
  496.       brc = GetOS2Version ();
  497.       if (!brc)  return (MRESULT)TRUE;
  498.  
  499.       // Kann der Scrollbar-Slider in dieser Version
  500.       // von OS/2 seine Groesse veraendern?
  501.       bSliderResizable = ( usMajorVersion >= 10 &&
  502.                            usMinorVersion >= 20    )
  503.                          ||
  504.                          ( usMajorVersion >= 20 );
  505.  
  506.       return 0;
  507.  
  508.  
  509.     case WM_SIZE:
  510.       /***********************************************/
  511.       /* - bestimmt die Ausdehnung des Client        */
  512.       /* - bestimmt fuer den vertikalen Scrollbar    */
  513.       /*   sVEnd und sVPos in Abhaengigkeit von      */
  514.       /*   der Client-Hoehe und der Font-Groesse.    */
  515.       /* - Analog wird beim horizontalen Scrollbar   */
  516.       /*   vorgegangen.                              */
  517.       /* - Damit werden die Slider-Position und      */
  518.       /*   der Slider-Bereich festgelegt.            */
  519.       /* - Wenn der Text nicht in den Client passt,  */
  520.       /*   wird ein Scrollbar erzeugt.               */
  521.       /*   Ist ein Scrollbar vorhanden und der Text  */
  522.       /*   passt nach der Groessenaenderung in das   */
  523.       /*   Fenster, wird der Scrollbar zerstoert.    */
  524.       /*   Dieses Vorgehen ersetzt das Dis/Enablen.  */
  525.       /***********************************************/
  526.       cxClient = SHORT1FROMMP (mp2) ;
  527.       cyClient = SHORT2FROMMP (mp2) ;
  528.  
  529.       // bestimme hwndFrame, wenn WM_SIZE das erstemal
  530.       // vom Client verarbeitet wird ..................
  531.       if ( firstWM_SIZE )
  532.       {
  533.         hwndFrame = WinQueryWindow( hwnd,
  534.                                     QW_PARENT,
  535.                                     FALSE );
  536.         firstWM_SIZE = 0;
  537.       }
  538.  
  539.  
  540.       // Auswirkung auf den senkrechten Scrollbar:
  541.       // bVScroll ist TRUE, wenn der Scroll existiert.
  542.       // ..............................................
  543.       {
  544.         SHORT sStyleF  = FCF_VERTSCROLL;  // Style des
  545.                                           //   Frame
  546.         ULONG lStyleScroll; // Style des zu erzeugenden
  547.                             //   Scrollbars
  548.  
  549.         sVEnd   = max ( sVStart,
  550.                         sTextRows  -  cyClient / cyChar
  551.                                    +  sVStart) ;
  552.         sVPos   = min ( sVPos, sVEnd );
  553.  
  554.         hwndVScroll = WinWindowFromID(hwndFrame,
  555.                                       FID_VERTSCROLL);
  556.         bVScroll = WinIsWindow( hab, hwndVScroll );
  557.  
  558.         // Erzeugen eines senkrechten Scrollbars,
  559.         //   falls dieser noch nicht existiert und
  560.         //   falls der Text laenger als das Fenster ist
  561.         if (  sVEnd-sVStart > 0  &&  !bVScroll  )
  562.         {
  563.           if (bSliderResizable)
  564.             lStyleScroll = SBS_VERT | SBS_THUMBSIZE;
  565.           else
  566.             lStyleScroll = SBS_VERT;
  567.  
  568.           hwndVScroll = WinCreateWindow(
  569.                             hwndFrame,
  570.                             WC_SCROLLBAR,
  571.                             NULL,
  572.                             lStyleScroll,
  573.                             0, 0, 0, 0,
  574.                             hwndFrame,
  575.                             HWND_TOP,
  576.                             FID_VERTSCROLL,
  577.                             NULL,
  578.                             NULL );
  579.  
  580.           bVScroll = WinIsWindow( hab, hwndVScroll );
  581.  
  582.           if ( bVScroll )
  583.             brc = (BOOL) SHORT1FROMMR (
  584.               WinSendMsg( hwndFrame,
  585.                           WM_UPDATEFRAME,
  586.                           MPFROMSHORT( sStyleF ),
  587.                           (MPARAM)0L )
  588.                                        );
  589.         }
  590.  
  591.         // Loeschen eines senkrechten Scrollbars,
  592.         //   falls dieser existiert und falls der Text
  593.         //   der Laenge nach ganz(!) in das Fenster
  594.         //   passt ....................................
  595.         else if (  sVEnd-sVStart == 0  &&  bVScroll  )
  596.         {
  597.           brc = WinDestroyWindow( hwndVScroll );
  598.  
  599.           bVScroll = WinIsWindow( hab, hwndVScroll );
  600.  
  601.           if ( !bVScroll )
  602.           {
  603.             hwndVScroll = 0L;  // noetig, da als static
  604.                                // in WM_VSCROLL benutzt
  605.  
  606.             brc = (BOOL) SHORT1FROMMR (
  607.               WinSendMsg( hwndFrame,
  608.                           WM_UPDATEFRAME,
  609.                           MPFROMSHORT( sStyleF ),
  610.                           (MPARAM)0L )
  611.                                        );
  612.           }
  613.         }
  614.  
  615.         if ( bVScroll )
  616.         {
  617.           // Setze Scrollbereich und Position..........
  618.           WinSendMsg( hwndVScroll,
  619.                       SBM_SETSCROLLBAR,
  620.                       MPFROMSHORT( sVPos ),
  621.                       MPFROM2SHORT( sVStart, sVEnd ) );
  622.  
  623.           // Setze Slidergroesse.......................
  624.           if (bSliderResizable)
  625.             WinSendMsg (hwndVScroll,
  626.                         SBM_SETTHUMBSIZE,
  627.                         MPFROM2SHORT( cyClient/cyChar,
  628.                                       sTextRows ),
  629.                         0L);
  630.         }
  631.  
  632.       }  // Ende senkrechter Scrollbar
  633.  
  634.  
  635.       // Auswirkung auf den waagrechten Scrollbar:
  636.       // bHScroll ist TRUE, wenn der Scroll existiert.
  637.       // ..............................................
  638.       {
  639.         SHORT sStyleF  = FCF_HORZSCROLL;  // Style des
  640.                                           //   Frame
  641.         ULONG lStyleScroll; // Style des zu erzeugenden
  642.                             //   Scrollbars
  643.  
  644.         if ( bPixelweise )
  645.         {
  646.           sHEnd   = max ( sHStart,
  647.                           sTextCols
  648.                             - cxClient
  649.                             + sHStart
  650.                             + EINRUECKUNG * cxCaps );
  651.         }
  652.         else
  653.         {
  654.           sHEnd   = max ( sHStart,
  655.                           sTextCols - (cxClient/cxCaps)
  656.                                     + sHStart
  657.                                     + EINRUECKUNG  );
  658.         }
  659.         sHPos   = min ( sHPos, sHEnd );
  660.  
  661.         hwndHScroll = WinWindowFromID( hwndFrame,
  662.                                        FID_HORZSCROLL );
  663.         bHScroll = WinIsWindow( hab, hwndHScroll );
  664.  
  665.         // Erzeugen eines waagrechten Scrollbars, falls
  666.         //   dieser noch nicht existiert und falls der
  667.         //   Text breiter als das Fenster ist ........
  668.         if (  sHEnd-sHStart > 0  &&  !bHScroll  )
  669.         {
  670.           if (bSliderResizable)
  671.             lStyleScroll = SBS_HORZ | SBS_THUMBSIZE;
  672.           else
  673.             lStyleScroll = SBS_HORZ;
  674.  
  675.           hwndHScroll = WinCreateWindow(
  676.                             hwndFrame,
  677.                             WC_SCROLLBAR,
  678.                             NULL,
  679.                             lStyleScroll,
  680.                             0, 0, 0, 0,
  681.                             hwndFrame,
  682.                             HWND_TOP,
  683.                             FID_HORZSCROLL,
  684.                             NULL,
  685.                             NULL );
  686.  
  687.           bHScroll = WinIsWindow( hab, hwndHScroll );
  688.  
  689.           if ( bHScroll )
  690.             brc = (BOOL) SHORT1FROMMR (
  691.               WinSendMsg( hwndFrame,
  692.                           WM_UPDATEFRAME,
  693.                           MPFROMSHORT( sStyleF ),
  694.                           (MPARAM)0L )
  695.                                        );
  696.         }
  697.  
  698.         // Loeschen eines waagrechten Scrollbars, falls
  699.         //   dieser existiert und falls der Text der
  700.         //   Breite nach ganz(!) in das Fenster passt
  701.         else if (  sHEnd-sHStart == 0  &&  bHScroll  )
  702.         {
  703.           brc = WinDestroyWindow( hwndHScroll );
  704.  
  705.           bHScroll = WinIsWindow( hab, hwndHScroll );
  706.  
  707.           if ( !bHScroll )
  708.           {
  709.             hwndHScroll = 0L;  // noetig, da als static
  710.                                // in WM_HSCROLL benutzt
  711.  
  712.             brc = (BOOL) SHORT1FROMMR (
  713.               WinSendMsg( hwndFrame,
  714.                           WM_UPDATEFRAME,
  715.                           MPFROMSHORT( sStyleF ),
  716.                           (MPARAM)0L )
  717.                                        );
  718.           }
  719.         }
  720.  
  721.         if ( bHScroll )
  722.         {
  723.           // Setze Scrollbereich und Position..........
  724.           WinSendMsg( hwndHScroll,
  725.                       SBM_SETSCROLLBAR,
  726.                       MPFROMSHORT( sHPos ),
  727.                       MPFROM2SHORT( sHStart, sHEnd ) );
  728.  
  729.           // Setze Slidergroesse.......................
  730.           if (bSliderResizable)
  731.           {
  732.             USHORT usFensterbreite;
  733.  
  734.             if ( bPixelweise )
  735.             {
  736.               usFensterbreite = cxClient;
  737.             }
  738.             else
  739.             {
  740.               usFensterbreite = cxClient/cxCaps;
  741.             }
  742.  
  743.             WinSendMsg (hwndHScroll,
  744.                         SBM_SETTHUMBSIZE,
  745.                         MPFROM2SHORT (usFensterbreite,
  746.                                       sTextCols),
  747.                         0L);
  748.           }
  749.         }
  750.  
  751.       }  // Ende waagrechter Scrollbar
  752.  
  753.       return 0 ;
  754.  
  755.  
  756.  
  757.     case WM_PAINT:
  758.       /***********************************************/
  759.       /* hier wird der Inhalt des Clients gezeichnet */
  760.       /***********************************************/
  761.         PaintWin ( hwnd );
  762.       return 0;
  763.  
  764.  
  765.     case WM_CHAR:
  766.       /***********************************************/
  767.       /* damit reagiert der Scrollbar auch auf       */
  768.       /*   Eingaben von der Tastatur                 */
  769.       /* - die VK-Werte sind definiert in PMWIN.h !  */
  770.       /***********************************************/
  771.       usVKey = (USHORT) CHARMSG(&msg)->vkey;
  772.       switch ( usVKey )
  773.       {
  774.         case VK_UP:
  775.         case VK_DOWN:
  776.         case VK_PAGEUP:
  777.         case VK_PAGEDOWN:
  778.           if ( WinIsWindow( hab, hwndVScroll ) )
  779.           {
  780.             return WinSendMsg( hwndVScroll,
  781.                                msg,
  782.                                mp1,
  783.                                mp2 );
  784.           }
  785.           break;
  786.         case VK_LEFT:
  787.         case VK_RIGHT:
  788.           if ( WinIsWindow( hab, hwndHScroll ) )
  789.           {
  790.             return WinSendMsg( hwndHScroll,
  791.                                msg,
  792.                                mp1,
  793.                                mp2 );
  794.           }
  795.           break;
  796.       }
  797.       break;
  798.  
  799.  
  800.     case WM_COMMAND:
  801.       /***********************************************/
  802.       /* Bearbeiten der Menue-Selektion:             */
  803.       /*  - Die ersten 2 Byte des Message-Parameters */
  804.       /*    mp1 enthalten den "command"-Wert, also   */
  805.       /*    den Wert des Bezeichners fuer den        */
  806.       /*    ausgewaehlten Menueeintrag.              */
  807.       /*  - Wenn im "Exit und Info"-Submenue der     */
  808.       /*    Eintrag "Exit" gewaehlt wird, schickt    */
  809.       /*    sich die Anwendung eine WM_QUIT-Message. */
  810.       /*  - Bei "Resume" tut sie gar nichts.         */
  811.       /*  - Bei "Programm-Information" wird in einer */
  812.       /*    Messagebox der Zweck des Programms       */
  813.       /*    erklaert und der geladene Text kurz      */
  814.       /*    beschrieben.                             */
  815.       /***********************************************/
  816.  
  817.       command = COMMANDMSG(&msg)->cmd;
  818.  
  819.       switch( command )
  820.       {
  821.         case IDM_ABOUT:
  822.           if ( bPixelweise )
  823.           {
  824.             sprintf( szBoxText, apchFormatTable[1],
  825.                      szQuelldatei, sTextRows,
  826.                      sLongestRow, sTextCols);
  827.           }
  828.           else
  829.           {
  830.             sprintf( szBoxText, apchFormatTable[2],
  831.                      szQuelldatei, sTextRows,
  832.                      sLongestRow, sTextCols);
  833.           }
  834.           szBoxTitel = "Programminformation";
  835.           AusgabeBox();
  836.           break;
  837.  
  838.         case IDM_EXITPROG:
  839.           WinPostMsg( hwnd,
  840.                       WM_QUIT,
  841.                       (MPARAM)0,
  842.                       (MPARAM)0 );
  843.           break;
  844.       }
  845.       break;
  846.  
  847.  
  848.     case WM_VSCROLL:
  849.       /***********************************************/
  850.       /* - hier werden alle Faelle einer Message des */
  851.       /*   vertikalen Scrollbars behandelt.          */
  852.       /* - je nachdem, was der Benutzer mit der Maus */
  853.       /*   im Scrollbar macht, nehmen die hoeheren   */
  854.       /*   beiden Bytes des 2. Messageparameters     */
  855.       /*   verschiedene Werte an.                    */
  856.       /* - Das Programm muss entsprechend auf diese  */
  857.       /*   Informationen reagieren, indem es evtl.   */
  858.       /*   sVPos veraendert, den Slider neu setzt    */
  859.       /*   und ein WM_PAINT generiert: dann wird der */
  860.       /*   Text entsprechend dem neuen sVPos im      */
  861.       /*   Client neu gezeichnet.                    */
  862.       /***********************************************/
  863.       switch( SHORT2FROMMP(mp2) )
  864.       {
  865.          case SB_LINEUP:
  866.             sVDelta = -1;
  867.             break;
  868.          case SB_PAGEUP:
  869.             sVDelta = - cyClient / cyChar;
  870.             break;
  871.          case SB_LINEDOWN:
  872.             sVDelta = 1;
  873.             break;
  874.          case SB_PAGEDOWN:
  875.             sVDelta = cyClient / cyChar;
  876.             break;
  877.          case SB_SLIDERTRACK:
  878.             sVDelta = SHORT1FROMMP(mp2) - sVPos;
  879.             break;
  880.          default:
  881.             return (MRESULT)0;
  882.       }
  883.  
  884.       // es gilt:  sVStart <= sVPos+sVDelta <= sVEnd
  885.       if ( sVPos+sVDelta < sVStart )
  886.          sVDelta = sVStart - sVPos;
  887.       else if ( sVPos+sVDelta > sVEnd )
  888.          sVDelta = sVEnd - sVPos;
  889.  
  890.       if ( sVDelta != 0 )
  891.       {
  892.         sVPos += sVDelta;
  893.         src = WinScrollWindow( hwnd,
  894.                                0,
  895.                                cyChar * sVDelta,
  896.                                NULL, NULL, NULL, NULL,
  897.                                SW_INVALIDATERGN );
  898.         WinSendMsg( hwndVScroll,
  899.                     SBM_SETPOS,
  900.                     MPFROMSHORT( sVPos ),
  901.                     MPFROMSHORT( 0 ) );
  902.  
  903.         brc = WinUpdateWindow( hwnd );
  904.       }
  905.  
  906.       break;
  907.  
  908.  
  909.     case WM_HSCROLL:
  910.       /***********************************************/
  911.       /* - hier werden alle Faelle einer Message des */
  912.       /*   horizontalen Scrollbars behandelt.        */
  913.       /* - je nachdem, was der Benutzer mit der Maus */
  914.       /*   im Scrollbar macht, nehmen die hoeheren   */
  915.       /*   beiden Bytes des 2. Messageparameters     */
  916.       /*   verschiedene Werte an.                    */
  917.       /* - Das Programm muss entsprechend auf diese  */
  918.       /*   Informationen reagieren, indem es evtl.   */
  919.       /*   sHPos veraendert, den Slider neu setzt    */
  920.       /*   und ein WM_PAINT generiert: dann wird der */
  921.       /*   Text entsprechend dem neuen sHPos im      */
  922.       /*   Client neu gezeichnet.                    */
  923.       /***********************************************/
  924.       switch( SHORT2FROMMP(mp2) )
  925.       {
  926.          case SB_LINELEFT:
  927.             sHDelta = -1;
  928.             break;
  929.          case SB_PAGELEFT:
  930.             if ( bPixelweise )
  931.             {
  932.               sHDelta = -cxClient;
  933.             }
  934.             else
  935.             {
  936.               sHDelta = - cxClient / cxCaps;
  937.             }
  938.             break;
  939.          case SB_LINERIGHT:
  940.             sHDelta = 1;
  941.             break;
  942.          case SB_PAGERIGHT:
  943.             if ( bPixelweise )
  944.             {
  945.               sHDelta = cxClient;
  946.             }
  947.             else
  948.             {
  949.              sHDelta = cxClient / cxCaps;
  950.             }
  951.             break;
  952.          case SB_SLIDERPOSITION:
  953.             sHDelta = SHORT1FROMMP(mp2) - sHPos;
  954.             break;
  955.          default:
  956.             return (MRESULT)0;
  957.       }
  958.  
  959.       // es gilt:  sHStart <= sHPos+sHDelta <= sHEnd
  960.       if ( sHPos+sHDelta < sHStart )
  961.          sHDelta = sHStart - sHPos;
  962.       else if ( sHPos+sHDelta > sHEnd )
  963.          sHDelta = sHEnd - sHPos;
  964.  
  965.       if ( sHDelta != 0 )
  966.       {
  967.         sHPos += sHDelta;
  968.  
  969.         if ( bPixelweise )
  970.         {
  971.           src = WinScrollWindow( hwnd,
  972.                                  - sHDelta,
  973.                                  0,
  974.                                  NULL, NULL,
  975.                                  NULL, NULL,
  976.                                  SW_INVALIDATERGN );
  977.         }
  978.         else
  979.         {
  980.           src = WinScrollWindow( hwnd,
  981.                                  - sHDelta * cxCaps,
  982.                                  0,
  983.                                  NULL, NULL,
  984.                                  NULL, NULL,
  985.                                  SW_INVALIDATERGN );
  986.         }
  987.  
  988.         WinSendMsg( hwndHScroll,
  989.                     SBM_SETPOS,
  990.                     MPFROMSHORT( sHPos ),
  991.                     MPFROMSHORT( 0 ) );
  992.  
  993.         brc = WinUpdateWindow( hwnd );
  994.       }
  995.  
  996.       break;
  997.  
  998.  
  999.     default:         // default fuer switch( msg )
  1000.       return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  1001.   }
  1002.  
  1003.   return FALSE;
  1004. }
  1005. /*-------  Ende der Window-Prozedur des Client  -----*/
  1006.  
  1007.  
  1008.  
  1009.  
  1010.  
  1011.  
  1012. /*---------  Start der PaintWin-Funktion ------------*/
  1013. /*                                                   */
  1014. /* - schreibt mit GpiCharStringAt den Text aus der   */
  1015. /*   Textresource-Datei in den Client-Bereich.       */
  1016. /*                                                   */
  1017. /* - Formalparameter:                                */
  1018. /*     hwnd   Clientbereich, in den geschrieben wird */
  1019. /*                                                   */
  1020. /* - globale Variable:                               */
  1021. /*    referiert: sVPos, sTextRows, cyClient, cyChar, */
  1022. /*               sHPos, cxCaps, cyDesc.              */
  1023. /*                                                   */
  1024. /* - aufgerufen von: ClientWindowProc, WM_PAINT      */
  1025. /*---------------------------------------------------*/
  1026. VOID PaintWin( HWND hwnd )
  1027. {
  1028.   HPS     hps;     // Handle cache-PS
  1029.   RECTL   rectl;   // Struktur Rechteck-Koordinaten:
  1030.                    //   erhaelt Koordinaten des Client
  1031.   POINTL  ptl;
  1032.   int     i,
  1033.           sVPaintBeg,
  1034.           sVPaintEnd;
  1035.  
  1036.   // Erzeuge einen Presentation Space..................
  1037.   hps = WinBeginPaint( hwnd, NULL, &rectl );
  1038.  
  1039.     brc = GpiErase( hps );
  1040.  
  1041.     sVPaintBeg = sVPos +
  1042.                  (cyClient-(SHORT)rectl.yTop) / cyChar;
  1043.     sVPaintEnd = min ( sTextRows - 1,
  1044.                        sVPos +
  1045.                        (cyClient-(SHORT)rectl.yBottom)
  1046.                            / cyChar
  1047.                      );
  1048.  
  1049.     for ( i = sVPaintBeg; i <= sVPaintEnd; i++ )
  1050.     {
  1051.       if ( bPixelweise )
  1052.       {
  1053.         ptl.x =  EINRUECKUNG * cxCaps  -  sHPos;
  1054.       }
  1055.       else
  1056.       {
  1057.         ptl.x =  ( EINRUECKUNG - sHPos ) * cxCaps;
  1058.       }
  1059.       ptl.y =  cyClient  -  (i + 1 - sVPos) * cyChar
  1060.                          +  cyDesc;
  1061.  
  1062.       GpiCharStringAt( hps,
  1063.                        &ptl,
  1064.                        (LONG)(apstructText+i)->sLineLength,
  1065.                        (apstructText+i)->pTextplace
  1066.                      );
  1067.     }
  1068.  
  1069.   brc = WinEndPaint( hps );   // Paint ist erledigt
  1070.  
  1071. }
  1072. /*----------  Ende der PaintWin-Funktion  -----------*/
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080.  
  1081.  
  1082.  
  1083.  
  1084. /*------  Start der AusgabeBox-Funktion -------------*/
  1085. /*                                                   */
  1086. /* - Gibt in einer beweglichen, applikationsmodalen  */
  1087. /*   Messagebox den Text und den Titel aus, der      */
  1088. /*   zu diesem Zeitpunkt in den globalen Variablen   */
  1089. /*   szBoxText und szBoxTitel steht.                 */
  1090. /*                                                   */
  1091. /* - globale Variable:                               */
  1092. /*    referiert: szBoxTitel, szBoxText               */
  1093. /*                                                   */
  1094. /* - aufgerufen von:                                 */
  1095. /*       ClientWindowProc ( Programm-Information ),  */
  1096. /*       SaveLineInfo                                */
  1097. /*---------------------------------------------------*/
  1098. VOID AusgabeBox ( VOID )
  1099. {
  1100.    WinMessageBox ( HWND_DESKTOP,
  1101.                    hwndClient,
  1102.                    (PSZ) szBoxText,
  1103.                    (PSZ) szBoxTitel,     // Titel
  1104.                    (USHORT)NULL,
  1105.                    MB_MOVEABLE
  1106.                   );
  1107. }
  1108. /*-------  Ende der AusgabeBox-Funktion -------------*/
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117. /*--------  Start der FrageBox-Funktion -------------*/
  1118. /*                                                   */
  1119. /* - Stellt in einer beweglichen, applikationsmodalen*/
  1120. /*   Messagebox die Frage, ob in horizontaler        */
  1121. /*   Richtung pixelweise gescrollt werden soll.      */
  1122. /*   Die Antwort "YES" ist der Standardfall, weil    */
  1123. /*   dann alles sauber ohne Rundungsfehler laeuft!   */
  1124. /*                                                   */
  1125. /* - globale Variable:                               */
  1126. /*    definiert: szBoxTitel, szBoxText               */
  1127. /*    referiert: szBoxTitel, szBoxText               */
  1128. /*                                                   */
  1129. /* - aufgerufen von:                                 */
  1130. /*       SaveLineInfo                                */
  1131. /*---------------------------------------------------*/
  1132. BOOL FrageBox ( VOID )
  1133. {
  1134.   szBoxTitel = "Wie soll horizontal gescrollt werden?";
  1135.   strcpy( szBoxText, "Wenn Sie horizontal pixelweise \
  1136.                       \nscrollen moechten, \
  1137.                       \nwaehlen Sie bitte \"YES\" :");
  1138.  
  1139.   usrc = WinMessageBox ( HWND_DESKTOP,
  1140.                          hwndClient,
  1141.                          (PSZ) szBoxText,
  1142.                          (PSZ) szBoxTitel,
  1143.                          (USHORT)NULL,
  1144.                          MB_MOVEABLE | MB_YESNO
  1145.                         );
  1146.   if ( usrc == MBID_YES ) return TRUE;
  1147.   else return FALSE;
  1148. }
  1149. /*---------  Ende der FrageBox-Funktion -------------*/
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155. /*--------  Start der SaveLineInfo-Funktion  --------*/
  1156. /*                                                   */
  1157. /* - fuellt die apstructText-Struktur mit den        */
  1158. /*   Informationen zu jeder Zeile, die beim Lesen    */
  1159. /*   der Textresource gefunden wird.                 */
  1160. /* - die globale Variable sTextRows wird nur initial */
  1161. /*   zum Beschaffen von Speicherplatz benoetigt.     */
  1162. /*                                                   */
  1163. /* - Formalparameter:                                */
  1164. /*      hwnd           Handle des Clientfensters     */
  1165. /*      sLineNo        Zeilennummer                  */
  1166. /*      sLineLength    Zeilenlaenge                  */
  1167. /*      pText          Zeiger auf Zeilenanfang       */
  1168. /*                                                   */
  1169. /* - globale Variable:                               */
  1170. /*    definiert: sTextCols, apstructText, szBoxText, */
  1171. /*               szBoxTitel,                         */
  1172. /*    referiert: sTextCols, sTextRows, apstructText, */
  1173. /*               apchFormatTable                     */
  1174. /*                                                   */
  1175. /* - aufgerufen von: ClientWindowProc in WM_CREATE   */
  1176. /* - ruft: AusgabeBox,                               */
  1177. /*         FrageBox                                  */
  1178. /*---------------------------------------------------*/
  1179. int SaveLineInfo( HWND  hwnd,
  1180.                   SHORT sLineNo,
  1181.                   SHORT sLineLength,
  1182.                   PCHAR pText )
  1183. {
  1184.   static int initial = 1;
  1185.   HPS    hps;
  1186.   CHAR   szTmp[255];   // max. Zeilenlaenge!
  1187.   SHORT  scx;          // Breite der Textbox
  1188.   POINTL aptlTextBox[TXTBOX_COUNT];
  1189.                        // Array von Punkten, die die
  1190.                        // Eckkoordinaten der TextBox
  1191.                        // enthalten
  1192.  
  1193.   if ( initial )
  1194.   {
  1195.     // erzeuge Speicher fuer ein Array mit sTextRows
  1196.     //   Elementen der TEXTPOINTER-Struktur............
  1197.     apstructText = (TEXTPOINTER *) malloc (
  1198.                      sTextRows * sizeof(TEXTPOINTER) );
  1199.     if ( apstructText == NULL )
  1200.     {
  1201.       sprintf( szBoxText,
  1202.                apchFormatTable[3],
  1203.                sTextRows );
  1204.       szBoxTitel = "Programmabsturz";
  1205.       AusgabeBox();
  1206.       return -1;
  1207.     }
  1208.  
  1209.     bPixelweise = FrageBox();
  1210.  
  1211.     initial = 0;
  1212.   }
  1213.  
  1214.   if ( !bPixelweise )
  1215.   {
  1216.     if ( sLineLength > sTextCols )
  1217.     {
  1218.       sTextCols   = sLineLength;
  1219.       sLongestRow = sLineNo;
  1220.     }
  1221.   }
  1222.   else
  1223.   {
  1224.     // Casting nur fuer Small-Model noetig, da sonst
  1225.     //    warnings kommen! ( im Large-Model nicht
  1226.     //    noetig, aber auch nicht schaedlich)
  1227.     memcpy(szTmp, (void *)pText, sLineLength );
  1228.     szTmp[sLineLength] = '\0';
  1229.  
  1230.     hps = WinGetPS( hwnd );
  1231.       brc = GpiQueryTextBox ( hps,
  1232.                               (LONG)sLineLength,
  1233.                               szTmp,
  1234.                               TXTBOX_COUNT,
  1235.                               aptlTextBox );
  1236.     WinReleasePS( hps );
  1237.  
  1238.     scx = (SHORT) (aptlTextBox[TXTBOX_BOTTOMRIGHT].x
  1239.                    - aptlTextBox[TXTBOX_BOTTOMLEFT].x);
  1240.  
  1241.     if ( scx > sTextCols )
  1242.     {
  1243.       sTextCols = scx;
  1244.       sLongestRow = sLineNo;
  1245.     }
  1246.   }
  1247.  
  1248.  
  1249.   // Fuelle das Array anhand der aktuellen Argumente
  1250.   (apstructText + sLineNo)->sLineNumber = sLineNo;
  1251.   (apstructText + sLineNo)->sLineLength = sLineLength;
  1252.   (apstructText + sLineNo)->pTextplace  = pText;
  1253.  
  1254.   return 0;
  1255. }
  1256. /*--------  Ende der SaveLineInfo-Funktion  ---------*/
  1257.  
  1258.  
  1259.  
  1260.  
  1261.  
  1262. /*--------  Start der GetOS2Version-Funktion  -------*/
  1263. /*                                                   */
  1264. /*  - speichert die Haupt- und Unternummer           */
  1265. /*    der OS/2-Version in die entsprechenden         */
  1266. /*    globalen Variablen usMinorVersion und          */
  1267. /*    usMajorVersion.                                */
  1268. /*  - usMajorVersion: = 10: OS/2 1.x                 */
  1269. /*                    = 20: OS/2 2.x                 */
  1270. /*  - usMinorVersion: = 10: OS/2 1.1, 2.1, ...       */
  1271. /*                    = 20: OS/2 1.2, 2.1, ...       */
  1272. /*                                                   */
  1273. /*                                                   */
  1274. /* - globale Variable:                               */
  1275. /*    definiert: usMajorVersion, usMinorVersion      */
  1276. /*    referiert: -                                   */
  1277. /*                                                   */
  1278. /* - aufgerufen von: ClientWindowProc in WM_CREATE   */
  1279. /* - ruft: -                                         */
  1280. /*---------------------------------------------------*/
  1281. BOOL GetOS2Version ( VOID )
  1282. {
  1283.   USHORT usVersion;
  1284.  
  1285.   usrc = DosGetVersion (&usVersion);
  1286.   if (usrc) return FALSE;
  1287.  
  1288.   usMajorVersion = (USHORT) HIBYTE(usVersion);
  1289.   usMinorVersion = (USHORT) LOBYTE(usVersion);
  1290.  
  1291.   return TRUE;
  1292. }
  1293. /*--------  Ende der GetOS2Version-Funktion  --------*/
  1294.  
  1295.  
  1296. /*-----------   Ende SCROLL3-Programm   -------------*/
  1297. /*---------------------------------------------------*/
  1298.