home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1990 / 09 / grdlagen / scroll1.c next >
Encoding:
C/C++ Source or Header  |  1990-06-10  |  35.9 KB  |  1,015 lines

  1. /**********************************************************/
  2. /*                                                        */
  3. /*                      SCROLL1.c                         */
  4. /*                                                        */
  5. /*           (C) 1990 J. Heid & toolbox                   */
  6. /*                                                   */
  7. /*  1. Version zur Demonstration des Scrollbars      */
  8. /*                                                   */
  9. /*  - Demonstriert, wie man Scrollbars in ein        */
  10. /*    PM-Programm einbaut.                           */
  11. /*  - Zeigt die Messages, die beim Klicken im        */
  12. /*    Scrollbar entstehen:                           */
  13. /*    Ausgabe im Client oder, falls dieser zu        */
  14. /*      klein ist, innerhalb einer applikations-     */
  15. /*      modalen Messagebox.                          */
  16. /*  - Zusaetzlich werden von dem fiktiven Text die   */
  17. /*    berechneten Zeilennummern ausgegeben: damit    */
  18. /*    hat man eine Kontrolle, dass das Scrollen      */
  19. /*    richtig funktioniert.                          */
  20. /*  - Als Kommandoargumente kann man eingeben:       */
  21. /*    - die Zeilen- und Spaltenzahl eines fiktiven   */
  22. /*      Textes und                                   */
  23. /*    - die Startindizes des horizontalen und        */
  24. /*      vertikalen Scrollbars.                       */
  25. /*  - Der Actionbar bietet den Eintrag               */
  26. /*    "Exit und Info".                               */
  27. /*  - Als Akzeleratortaste ist wirksam:              */
  28. /*      F3    : beendet das Programm                 */
  29. /*  - Die Windowprozedur ClientWndProc behandelt     */
  30. /*    explizit die folgenden 7 Events:               */
  31. /*        WM_CREATE,   WM_SIZE,     WM_PAINT,        */
  32. /*        WM_COMMAND,  WM_VSCROLL,  WM_HSCROLL,      */
  33. /*        WM_CHAR.                                   */
  34. /*                                                   */
  35. /*                                                   */
  36. /*  Aufruf:  scroll1  [ 50 100 [ 10 10 ] ]           */
  37. /*    - die 4 Argumente sind optional                */
  38. /*    - Argument 1 und 2: Zahl der Textzeilen und    */
  39. /*                        Textspalten                */
  40. /*    - Argument 3 und 4: Index der ersten Textzeile */
  41. /*                        und Textspalte zum         */
  42. /*                        Ausdruck des Beginns       */
  43. /*                        des Scrollbereiches        */
  44. /*                                                   */
  45. /*                                                   */
  46. /*  Funktionen:                                      */
  47. /*  -----------                                      */
  48. /*  SCROLL1.c besteht aus 7 Funktionen, die sich     */
  49. /*  in ff. Weise aufrufen:                           */
  50. /*            main                                   */
  51. /*            |   LiesKommandoArg                    */
  52. /*            |   WndCreate                          */
  53. /*            |   |   AusgabeBox                     */
  54. /*                                                   */
  55. /*            ClientWindowProc                       */
  56. /*            |   PaintWin                           */
  57. /*            |   |   DisplayScroll                  */
  58. /*            |   |   |   AusgabeBox                 */
  59. /*            |   AusgabeBox                         */
  60. /*                                                   */
  61. /*                                                   */
  62. /*  Benoetigte Dateien:                              */
  63. /*  -------------------                              */
  64. /*    SCROLL1.c      - Quellcode-Datei               */
  65. /*    SCROLL1.rc     - Resource-Datei                */
  66. /*    SCROLL1.h      - Header-Datei                  */
  67. /*    SCROLL1.def    - Modul-Definitions-Datei       */
  68. /*    SCROLL1.mak    - Make-Datei                    */
  69. /*                                                   */
  70. /*****************************************************/
  71.  
  72.  
  73. #define INCL_WIN
  74. #define INCL_GPI
  75. #include <os2.h>       // PM-Include-Datei
  76.  
  77. #include <stdio.h>
  78. #include <string.h>
  79. #include <stdlib.h>
  80.  
  81. #include "scroll1.h"   // Symbol. Konstanten fuer
  82.                        //   scroll1.c und scroll1.rc
  83.  
  84.  
  85. #define  STANDARD_COLS   200   // Text mit 200 Spalten
  86. #define  STANDARD_ROWS   100   // Text mit 100 Zeilen
  87. #define  BEGIN_V_RANGE     0   // Standardwerte fuer
  88. #define  BEGIN_H_RANGE     0   //  den Scrollbereich
  89.  
  90.  
  91. /*****************************************************/
  92. /* Funktions-Prototypen                              */
  93. /*****************************************************/
  94. int     cdecl    main( int, char ** );
  95. BOOL             WndCreate( VOID );
  96. MRESULT EXPENTRY ClientWindowProc( HWND   hwnd,
  97.                                    USHORT msg,
  98.                                    MPARAM mp1,
  99.                                    MPARAM mp2 );
  100. void             PaintWin( HWND hwnd);
  101. void             DisplayScroll( HPS hps,
  102.                                 PRECTL pRectl );
  103. void             AusgabeBox ( VOID );
  104. void             LiesKommandoArg( int argc,
  105.                                   char *argv[] );
  106.  
  107.  
  108.  
  109.  
  110. /*****************************************************/
  111. /* globale Variablen                                 */
  112. /*****************************************************/
  113. HAB  hab;                  // Programmanker
  114. CHAR szClientClass[] = "KlasseScroll1";
  115.                            // Name der Fensterklasse
  116. HWND hwndFrame;      // Handle fuer das Frame-Fenster
  117. HWND hwndClient;     // Handle fuer den Client-Bereich
  118.                      //        des Fensters
  119.  
  120. SHORT sVStart,       // - sVStart und sVEnd bestimmen
  121.       sVEnd  ,       //   den Scrollbereich.
  122.       sVPos  ;       //   (analog sHStart und sHEnd).
  123. SHORT sHStart,       // - Dieser ist ebenso wie PAGEUP
  124.       sHEnd  ,       //   abhaengig von der
  125.       sHPos  ;       //   Fenstergroesse!
  126.                      // - sVStart und sHStart haben als
  127.                      //   Standardwerte BEGIN_V_RANGE
  128.                      //   und BEGIN_H_RANGE (aenderbar
  129.                      //   durch Kommandoarg. 3 + 4 )
  130.  
  131. SHORT cxChar,        // Groessen des akt. Fonts
  132.       cxCaps,        //  ( benoetigte Teile der
  133.       cyChar,        //    FONTMETRICS-Struktur )
  134.       cyDesc;
  135.  
  136. CHAR  szBoxText[255]; // enthalten Text und Titel fuer
  137. PSZ   szBoxTitel;     // die Ausgabe in der Messagebox
  138.                       // oder im Client
  139. BOOL  bVertScroll = FALSE;  // Flagge, welcher
  140. BOOL  bHorzScroll = FALSE;  // Scrollbar geklickt wurde
  141. SHORT cxClient,      // Ausdehnung des Clientbereichs
  142.       cyClient ;
  143.  
  144. SHORT sTextCols;     // Anzahl der Spalten im Text
  145. SHORT sTextRows;     // Anzahl der Zeilen im Text
  146.                      // Standardwerte sind
  147.                      //   STANDARD_COLS und
  148.                      //   STANDARD_COLS (aenderbar
  149.                      //   durch Kommandoarg. 1 + 2 )
  150.  
  151.  
  152. // Formatstrings fuer die Meldungen per szBoxText
  153. static CHAR * apchFormatTable [] =
  154. {
  155.   // ---  0  ---
  156.     "Das Programm zeigt die Messages fuer die \
  157.     Scrollbars an! \
  158.   \nEs nimmt anhand der Kommandoargumente an:\
  159.   \n - der Text, in dem man scrollt, hat\
  160.   \n    %d Zeilen und %d Spalten und \
  161.   \n - die Scrollbereichs-Startwerte sind\
  162.   \n    %d (V) und %d (H).",
  163.   // ---  1  ---
  164.     "Vertikale Ausdehnung=(%d,%d)  Position=%d",
  165.   // ---  2  ---
  166.     "Horizontale Ausdehnung=(%d,%d)  Position=%d",
  167.   // ---  3  ---
  168.     "Vertikale Ausdehnung=(%d,%d)  Position=%d \
  169.   \nText: Zeilen/Spaltenzahl %d / %d",
  170.   // ---  4  ---
  171.     "Horizontale Ausdehnung=(%d,%d)  Position=%d \
  172.   \nText: Zeilen/Spaltenzahl %d / %d",
  173.   // ---  5  ---
  174.     "Das Programm simuliert das Scrollen in einem \
  175.   \nText mit %d Zeilen und %d Spalten.",
  176.   // ---  6  ---
  177.     "Scrollen in einem Text\
  178.  mit %d Zeilen und %d Spalten und\
  179.  mit den Startwerten %d (V) und %d (H).\
  180.   \nStartwerte duerfen nicht negativ sein!",
  181.   // ---  7  ---
  182.     "Das Programm simuliert das Scrollen in einem Text\
  183.  mit %d Zeilen und %d Spalten und\
  184.   \n mit den Startwerten %d (V) und %d (H).",
  185.   // ---  8  ---
  186.     "Es wurden nicht genau 2 bzw. 4 Argumente uebergeben.\
  187.  Deshalb wird die Zeilenzahl auf %d und \
  188.  die Spaltenzahl auf %d gesetzt.",
  189. };
  190.  
  191.  
  192.  
  193. /*-------  Start der main-Funktion  -----------------*/
  194. /*                                                   */
  195. /* - initialisiert und terminiert                    */
  196. /* - liest evtl. vorhandene Kommandoargumente        */
  197. /* - enthaelt Message-Loop                           */
  198. /*                                                   */
  199. /* - globale Variable:                               */
  200. /*    definiert: hab.                                */
  201. /*    referiert: hwndFrame.                          */
  202. /* - ruft: WndCreate(), LiesKommandoArg()            */
  203. /*                                                   */
  204. /*---------------------------------------------------*/
  205. int cdecl main (argc, argv)
  206.   int argc;
  207.   char *argv[];
  208. {
  209.   HMQ   hmq;          // Handle fuer die Message-Queue
  210.   QMSG  qmsg;         // Message in der Message-Queue
  211.  
  212.   LiesKommandoArg(argc, argv);
  213.  
  214.   hab = WinInitialize( NULL );      // Initialisiere PM
  215.   hmq = WinCreateMsgQueue( hab, 0 );// Erzeuge
  216.                                     //    Message-Queue
  217.  
  218.   if ( hmq != (HMQ)NULL )
  219.   {
  220.     if ( WndCreate() == TRUE )
  221.     {
  222.       /***********************************************/
  223.       /* "Message-processing-Loop":                  */
  224.       /* Empfaengt und verteilt Messages aus der     */
  225.       /* Message-Queue der Anwendung, bis WinGetMsg  */
  226.       /* FALSE zurueckgibt: dies geschieht dann, wenn*/
  227.       /* WinGetMsg eine WM_QUIT-Message erhielt.     */
  228.       /***********************************************/
  229.       while( WinGetMsg( hab, (PQMSG)&qmsg,
  230.                         (HWND)NULL, 0, 0 )
  231.             )
  232.         WinDispatchMsg( hab, (PQMSG)&qmsg );
  233.  
  234.       WinDestroyWindow( hwndFrame );
  235.     }
  236.     WinDestroyMsgQueue( hmq );
  237.   }
  238.   WinTerminate( hab );
  239.  
  240.   return 0;
  241. }
  242. /*-------  Ende der main-Funktion  ------------------*/
  243.  
  244.  
  245.  
  246.  
  247. /*-------  Start der WndCreate-Funktion -------------*/
  248. /*                                                   */
  249. /* - registriert die Fensterklasse des Client.       */
  250. /* - erzeugt das Standardfenster.                    */
  251. /* - gibt ganz am Anfang in einer Messagebox die     */
  252. /*   Groesse des fiktiven Textes und die Untergrenzen*/
  253. /*   der Scrollbereiche aus.                         */
  254. /*                                                   */
  255. /* - globale Variable:                               */
  256. /*    definiert: hwndClient, hwndFrame.              */
  257. /*    referiert: hab, szClientClass, hwndFrame.      */
  258. /* - aufgerufen von: main()                          */
  259. /* - Return: - TRUE,  wenn alles klappt              */
  260. /*           - FALSE, wenn etwas schiefging. Dann    */
  261. /*                    bricht main() Verarbeitung ab. */
  262. /*---------------------------------------------------*/
  263. BOOL WndCreate( VOID )
  264. {
  265.   ULONG flCreateFrame;  // Flaggen fuer die Erzeugung
  266.                         //         der Controls
  267.   BOOL  brc;            // Hilfsvariable zum Abpruefen
  268.                         //    des Rueckgabewertes von
  269.                         //    API-Funktionen
  270.  
  271.            // Ordne die ClientWndProc einer Klasse zu
  272.   brc = WinRegisterClass(
  273.           hab,              // Programmanker
  274.           szClientClass,    // Name der Fensterklasse
  275.           ClientWindowProc, // Adr. der Fensterprozedur
  276.           CS_SIZEREDRAW,    // Klassen-Style
  277.           0                 // keine Extra-Bytes
  278.                             //    reservieren
  279.           );
  280.  
  281.            // wenn WinRegisterClass nicht erfolgreich
  282.   if ( brc == FALSE ) return ( FALSE );
  283.  
  284.            // nun Standardfenster auch mit Actionbar
  285.            //     und Akzeleratortabelle als Resource
  286.   flCreateFrame = FCF_STANDARD & ~FCF_ICON |
  287.                   FCF_VERTSCROLL | FCF_HORZSCROLL;
  288.  
  289.            // Erzeugen eines Standardfensters
  290.   hwndFrame = WinCreateStdWindow(
  291.  
  292.            HWND_DESKTOP,   // Handle des Vaterfensters
  293.            WS_VISIBLE,     // Style des Frame-Fensters
  294.            (PULONG)&flCreateFrame,
  295.            szClientClass,  // Client-Fenster-Klasse
  296.            " - Scrollbar-Demo",   // Titel-Erweiterung
  297.            0L,             // Style des Client-Fensters
  298.            NULL,         // Resourcen sind in EXE-Datei
  299.            ID_RESOURCE,    // Bezeichner fuer Resourcen
  300.            (PHWND)&hwndClient // Zeiger auf den Handle
  301.                               //    des Client-Fensters
  302.            );
  303.  
  304.                // WinCreateStdWindow nicht erfolgreich
  305.   if ( hwndFrame == (HWND)NULL ) return ( FALSE );
  306.  
  307.  
  308.   AusgabeBox();
  309.  
  310.   return ( TRUE );
  311.  
  312. }
  313. /*-------  Ende der WndCreate-Funktion --------------*/
  314.  
  315.  
  316.  
  317. /*-------  Start der Window-Prozedur des Client -----*/
  318. /*                                                   */
  319. /* - behandelt die Reaktionen des Clientfensters     */
  320. /* - explizit behandelte Events:                     */
  321. /*     WM_CREATE,  WM_SIZE,   WM_PAINT,  WM_COMMAND, */
  322. /*     WM_VSCROLL, WM_HSCROLL, WM_CHAR.              */
  323. /*                                                   */
  324. /* - globale Variable:                               */
  325. /*    definiert: ...                                 */
  326. /*    referiert: ...                                 */
  327. /*                                                   */
  328. /* - aufgerufen von: Presentation Manager            */
  329. /* - ruft: in WM_PAINT:   PaintWin                   */
  330. /*         in WM_COMMAND: AusgabeBox                 */
  331. /*---------------------------------------------------*/
  332. MRESULT EXPENTRY ClientWindowProc( HWND hwnd,
  333.                                    USHORT msg,
  334.                                    MPARAM mp1,
  335.                                    MPARAM mp2 )
  336. {
  337.   HPS    hps;              // Presentation-Space-Handle
  338.   FONTMETRICS fm;          // Struktur mit Attributen
  339.                            //          des akt. Fonts
  340.   static HWND hwndVScroll; // Handle fuer den
  341.                            //   vertikalen Scrollbar
  342.   static HWND hwndHScroll; // Handle fuer den
  343.                            //   horizontalen Scrollbar
  344.   SHORT  sVPosOld,
  345.          sHPosOld;
  346.  
  347.   USHORT usVKey;    // Komponente der WM_CHAR-Message
  348.   USHORT command;   // Command-Wert bei WM_COMMAND
  349.                     // ID des gewaehlten Menueeintrags
  350.  
  351.  
  352.   switch( msg )
  353.   {
  354.  
  355.     case WM_CREATE:
  356.       /***********************************************/
  357.       /* - bestimmt die Handles der beiden Scrolls:  */
  358.       /*   ist das nicht moeglich, wird die          */
  359.       /*   Verarbeitung abgebrochen!                 */
  360.       /* - bestimmt die Attribute des aktuellen      */
  361.       /*   Fonts: die davon benoetigten Teile werden */
  362.       /*   in den globalen Variablen cxChar,         */
  363.       /*   cxCaps, cyChar und cyDesc abgelegt.       */
  364.       /***********************************************/
  365.  
  366.       hwndVScroll =
  367.           WinWindowFromID( WinQueryWindow( hwnd,
  368.                                            QW_PARENT,
  369.                                            FALSE ),
  370.                            FID_VERTSCROLL );
  371.  
  372.       hwndHScroll =
  373.           WinWindowFromID( WinQueryWindow( hwnd,
  374.                                            QW_PARENT,
  375.                                            FALSE ),
  376.                            FID_HORZSCROLL );
  377.  
  378.  
  379.       if (  hwndVScroll == (HWND)NULL  ||
  380.             hwndHScroll == (HWND)NULL     )
  381.         return ( (MRESULT)TRUE );
  382.  
  383.       hps = WinGetPS( HWND_DESKTOP );
  384.         GpiQueryFontMetrics( hps,
  385.                              (LONG)sizeof( fm ),
  386.                              &fm );
  387.       WinReleasePS( hps );
  388.  
  389.  
  390.       cxChar = (SHORT) fm.lAveCharWidth;
  391.       cxCaps = (SHORT) fm.lEmInc;
  392.       cyChar = (SHORT) fm.lMaxBaselineExt;
  393.       cyDesc = (SHORT) fm.lMaxDescender;
  394.  
  395.       return 0;
  396.  
  397.  
  398.     case WM_SIZE:
  399.       /***********************************************/
  400.       /* - bestimmt die Ausdehnung des Client        */
  401.       /* - bestimmt fuer den vertikalen Scrollbar    */
  402.       /*   sVEnd und sVPos in Abhaengigkeit von      */
  403.       /*   Client-Hoehe und Font-Groesse.            */
  404.       /* - Damit werden die Slider-Position und      */
  405.       /*   der Slider-Bereich festgelegt.            */
  406.       /* - Ist der Text kleiner als der Client, wird */
  407.       /*   der Scrollbar disabled und unmgekehrt.    */
  408.       /* - Analog wird beim horizontalen Scrollbar   */
  409.       /*   vorgegangen.                              */
  410.       /***********************************************/
  411.       cxClient = SHORT1FROMMP (mp2) ;
  412.       cyClient = SHORT2FROMMP (mp2) ;
  413.  
  414.       sVEnd   = max ( sVStart,
  415.                       sTextRows  -  cyClient / cyChar
  416.                                  +  sVStart) ;
  417.       sVPos   = min ( sVPos, sVEnd );
  418.  
  419.       WinSendMsg( hwndVScroll,
  420.                   SBM_SETSCROLLBAR,
  421.                   MPFROMSHORT( sVPos ),
  422.                   MPFROM2SHORT( sVStart, sVEnd ) );
  423.       WinEnableWindow( hwndVScroll,
  424.                        ( sVEnd - sVStart ) ?
  425.                         TRUE : FALSE
  426.                      );
  427.  
  428.  
  429.       sHEnd   = max ( sHStart,
  430.                       sTextCols  -  (cxClient / cxCaps)
  431.                                  +  sHStart );
  432.       sHPos   = min ( sHPos, sHEnd );
  433.  
  434.       WinSendMsg( hwndHScroll,
  435.                   SBM_SETSCROLLBAR,
  436.                   MPFROMSHORT( sHPos ),
  437.                   MPFROM2SHORT( sHStart, sHEnd ) );
  438.       WinEnableWindow( hwndHScroll,
  439.                        ( sHEnd - sHStart ) ?
  440.                          TRUE : FALSE
  441.                      );
  442.       return 0 ;
  443.  
  444.  
  445.     case WM_PAINT:
  446.       /***********************************************/
  447.       /* hier wird der Inhalt des Clients gezeichnet */
  448.       /***********************************************/
  449.       PaintWin ( hwnd );
  450.       return 0;
  451.  
  452.  
  453.     case WM_CHAR:
  454.       /***********************************************/
  455.       /* damit reagiert der Scrollbar auch auf       */
  456.       /*   Eingaben von der Tastatur                 */
  457.       /***********************************************/
  458.       // die VK-Werte sind definiert in PMWIN.h !
  459.       usVKey = (USHORT) CHARMSG(&msg)->vkey;
  460.       if (  usVKey == VK_UP       ||
  461.             usVKey == VK_DOWN     ||
  462.             usVKey == VK_PAGEUP   ||
  463.             usVKey == VK_PAGEDOWN  )
  464.          return(  WinSendMsg( hwndVScroll,
  465.                               msg,
  466.                               mp1,
  467.                               mp2)  );
  468.       else if (  usVKey == VK_LEFT  ||
  469.                  usVKey == VK_RIGHT   )
  470.          return(  WinSendMsg( hwndHScroll,
  471.                               msg,
  472.                               mp1,
  473.                               mp2)  );
  474.       else
  475.         break;
  476.  
  477.  
  478.     case WM_COMMAND:
  479.       /***********************************************/
  480.       /* Bearbeiten der Menue-Selektion:             */
  481.       /*  - Die ersten 2 Byte des Message-Parameters */
  482.       /*    mp1 enthalten den "command"-Wert, also   */
  483.       /*    den Wert des Bezeichners fuer den        */
  484.       /*    ausgewaehlten Menueeintrag.              */
  485.       /*  - Wenn im "Exit und Info"-Submenue der     */
  486.       /*    Eintrag "Exit" gewaehlt wird, schickt    */
  487.       /*    sich die Anwendung eine WM_QUIT-Message. */
  488.       /*  - Bei "Resume" tut sie gar nichts.         */
  489.       /*  - Bei "Programm-Information" wird in einer */
  490.       /*    Messagebox der Zweck des Programms       */
  491.       /*    erklaert.                                */
  492.       /***********************************************/
  493.  
  494.       command = COMMANDMSG(&msg)->cmd;
  495.  
  496.       switch( command )
  497.       {
  498.         case IDM_ABOUT:
  499.           sprintf( szBoxText, apchFormatTable[0],
  500.                    sTextRows, sTextCols,
  501.                    sVStart, sHStart );
  502.           szBoxTitel = "Programmzweck";      // Titel !
  503.  
  504.           AusgabeBox();
  505.           break;
  506.  
  507.         case IDM_EXITPROG:
  508.           WinPostMsg( hwnd,
  509.                       WM_QUIT,
  510.                       (MPARAM)0,
  511.                       (MPARAM)0 );
  512.           break;
  513.       }
  514.       break;
  515.  
  516.  
  517.     case WM_VSCROLL:
  518.       /***********************************************/
  519.       /* - hier werden alle Faelle einer Message des */
  520.       /*   vertikalen Scrollbars behandelt.          */
  521.       /* - je nachdem, was der Benutzer mit der Maus */
  522.       /*   im Scrollbar macht, nehmen die hoeheren   */
  523.       /*   beiden Bytes des 2. Messageparameters     */
  524.       /*   verschiedene Werte an.                    */
  525.       /* - Das Programm muss entsprechend auf diese  */
  526.       /*   Informationen reagieren, indem es evtl.   */
  527.       /*   sVPos veraendert, den Slider neu setzt    */
  528.       /*   und ein WM_PAINT generiert: dort wird der */
  529.       /*   Text entsprechend dem neuen sVPos neu     */
  530.       /*   ausgegeben.                               */
  531.       /***********************************************/
  532.       sVPosOld = sVPos;
  533.       switch( SHORT2FROMMP(mp2) )
  534.       {
  535.          case SB_LINEUP:
  536.             szBoxTitel = "SB_LINEUP";
  537.             sVPos--;
  538.             break;
  539.          case SB_PAGEUP:
  540.             szBoxTitel = "SB_PAGEUP";
  541.             sVPos -= cyClient / cyChar;
  542.             break;
  543.          case SB_LINEDOWN:
  544.             szBoxTitel = "SB_LINEDOWN";
  545.             sVPos++;
  546.             break;
  547.          case SB_PAGEDOWN:
  548.             szBoxTitel = "SB_PAGEDOWN";
  549.             sVPos += cyClient / cyChar;
  550.             break;
  551.          case SB_SLIDERTRACK:
  552.             szBoxTitel = "SB_SLIDERTRACK";
  553.             sVPos = SHORT1FROMMP(mp2);
  554.             break;
  555.          case SB_SLIDERPOSITION:
  556.             szBoxTitel = "SB_SLIDERPOSITION";
  557.             sVPos = SHORT1FROMMP(mp2);
  558.             break;
  559.          case SB_ENDSCROLL:
  560.             return (MRESULT)0;
  561.          default:
  562.             szBoxTitel = "default";
  563.             return (MRESULT)0;
  564.       }
  565.  
  566.       // es gilt:   sVStart  <=  sVPos  <=  sVEnd
  567.       // Identisch mit:
  568.       //    sVPos = max(sVStart, min(sVPos,sVEnd));
  569.       // ist:
  570.       if ( sVPos < sVStart )
  571.          sVPos = sVStart;
  572.       else if ( sVPos > sVEnd )
  573.          sVPos = sVEnd;
  574.  
  575.       if ( sVPosOld != sVPos )
  576.       {
  577.         WinSendMsg( hwndVScroll,
  578.                     SBM_SETPOS,
  579.                     MPFROMSHORT( sVPos ),
  580.                     MPFROMSHORT( 0 ) );
  581.         bVertScroll = TRUE;
  582.         WinInvalidateRect( hwnd, NULL, FALSE );
  583.       }
  584.  
  585.       break;
  586.  
  587.  
  588.     case WM_HSCROLL:
  589.       /***********************************************/
  590.       /* - hier werden alle Faelle einer Message des */
  591.       /*   horizontalen Scrollbars behandelt.        */
  592.       /* - je nachdem, was der Benutzer mit der Maus */
  593.       /*   im Scrollbar macht, nehmen die hoeheren   */
  594.       /*   beiden Bytes des 2. Messageparameters     */
  595.       /*   verschiedene Werte an.                    */
  596.       /* - Das Programm muss entsprechend auf diese  */
  597.       /*   Informationen reagieren, indem es evtl.   */
  598.       /*   sHPos veraendert, den Slider neu setzt    */
  599.       /*   und ein WM_PAINT generiert: dort wird der */
  600.       /*   Text entsprechend dem neuen sHPos neu     */
  601.       /*   ausgegeben.                               */
  602.       /***********************************************/
  603.       sHPosOld = sHPos;
  604.       switch( SHORT2FROMMP(mp2) )
  605.       {
  606.          case SB_LINELEFT:
  607.             szBoxTitel = "SB_LINELEFT";
  608.             sHPos--;
  609.             break;
  610.          case SB_PAGELEFT:
  611.             szBoxTitel = "SB_PAGELEFT";
  612.             sHPos -= cxClient / cxCaps;
  613.             break;
  614.          case SB_LINERIGHT:
  615.             szBoxTitel = "SB_LINERIGHT";
  616.             sHPos++;
  617.             break;
  618.          case SB_PAGERIGHT:
  619.             szBoxTitel = "SB_PAGERIGHT";
  620.             sHPos += cxClient / cxCaps;
  621.             break;
  622.          case SB_SLIDERPOSITION:
  623.             szBoxTitel = "SB_SLIDERPOSITION";
  624.             sHPos = SHORT1FROMMP(mp2);
  625.             break;
  626.          case SB_ENDSCROLL:
  627.             return (MRESULT)0;
  628.          default:
  629.             szBoxTitel = "default";
  630.             return (MRESULT)0;
  631.       }
  632.  
  633.       // es gilt:   sHStart  <=  sHPos  <=  sHEnd
  634.       // Identisch mit:
  635.       //    sHPos = max(sHStart, min(sHPos,sHEnd));
  636.       // ist:
  637.       if ( sHPos < sHStart )
  638.         sHPos = sHStart;
  639.       else if ( sHPos > sHEnd )
  640.         sHPos = sHEnd;
  641.  
  642.       if ( sHPosOld != sHPos )
  643.       {
  644.         WinSendMsg( hwndHScroll,
  645.                     SBM_SETPOS,
  646.                     MPFROMSHORT( sHPos ),
  647.                     MPFROMSHORT( 0 ) );
  648.         bHorzScroll = TRUE;
  649.         WinInvalidateRect( hwnd, NULL, FALSE );
  650.       }
  651.  
  652.       break;
  653.  
  654.  
  655.     default:         // default fuer switch( msg )
  656.       return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  657.   }
  658.  
  659.   return FALSE;
  660. }
  661. /*-------  Ende der Window-Prozedur des Client  -----*/
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668. /*---------  Start der PaintWin-Funktion ------------*/
  669. /*                                                   */
  670. /* - schreibt mit GpiCharStringAt die Zeilennummern  */
  671. /*   des fiktiven Textes. Die Nummernwerte sind      */
  672. /*   u.a. abhaengig von sVPos und sHPos.             */
  673. /* - wenn das WM_PAINT durch ein Scroll-Event        */
  674. /*   erzeugt wurde, sitzt eine der beiden Flaggen    */
  675. /*   bVertScroll oder bHorzScroll, was zum Aufruf    */
  676. /*   von DisplayScroll fuehrt.                       */
  677. /*                                                   */
  678. /* - Formalparameter:                                */
  679. /*     hwnd   Clientbereich, in den geschrieben wird */
  680. /*                                                   */
  681. /* - globale Variable:                               */
  682. /*    referiert: sVPos, sTextRows, cyClient, cyChar, */
  683. /*               sHPos, cxCaps, cyDesc.              */
  684. /*                                                   */
  685. /* - aufgerufen von: ClientWindowProc, WM_PAINT      */
  686. /*---------------------------------------------------*/
  687. void PaintWin( HWND hwnd )
  688. {
  689.   HPS     hps;     // Handle cache-PS
  690.   RECTL   rectl;   // Struktur Rechteck-Koordinaten:
  691.                    //   erhaelt Koordinaten des Client
  692.   POINTL  ptl;
  693.   int     i,
  694.           sVPaintBeg,
  695.           sVPaintEnd;
  696.   char    szTmp[10];
  697.   BOOL    brc;
  698.  
  699.         // macht den ganzen(!) Client zur Update-Region
  700.   brc = WinInvalidateRect( hwnd, NULL, FALSE );
  701.  
  702.                 // Erzeuge einen Presentation Space
  703.   hps = WinBeginPaint( hwnd, NULL, &rectl );
  704.  
  705.     brc = WinFillRect( hps, &rectl, CLR_RED );
  706.  
  707.     brc = GpiSetColor( hps, SYSCLR_WINDOWTEXT );
  708.     brc = GpiSetBackMix( hps, BM_OVERPAINT );
  709.  
  710.  
  711.     sVPaintBeg = sVPos;
  712.     sVPaintEnd = min ( sTextRows - 1 + sVPos,
  713.                        cyClient/cyChar - 1 + sVPos
  714.                      );
  715.  
  716.     for ( i = sVPaintBeg; i <= sVPaintEnd; i++ )
  717.     {
  718.       ptl.x =  8 * cxCaps - sHPos * cxCaps;
  719.       ptl.y =  cyClient  -  (i + 1 - sVPos) * cyChar
  720.                          +  cyDesc;
  721.       itoa( i, szTmp, 10 );
  722.  
  723.       GpiCharStringAt( hps, &ptl,
  724.                        (LONG) strlen( szTmp ),
  725.                        szTmp
  726.                      );
  727.     }
  728.  
  729.     if ( bVertScroll || bHorzScroll )
  730.       DisplayScroll( hps, &rectl );
  731.  
  732.  
  733.   WinEndPaint( hps );   // Paint ist erledigt
  734.  
  735. }
  736. /*------  Ende der PaintWin-Funktion  ------------*/
  737.  
  738.  
  739.  
  740. /*------  Start der DisplayScroll-Funktion ----------*/
  741. /*                                                   */
  742. /* - Falls ein Scroll-Event ein WM_PAINT erzeugt,    */
  743. /*   wird hier die Art der Scroll-Message ausgegeben.*/
  744. /* - Die Ausgabe wird normalerweise in den Client    */
  745. /*   geschrieben; passt der Text nicht ganz in       */
  746. /*   den Client, erfolgt die Ausgabe in einer        */
  747. /*   Messagebox.                                     */
  748. /*                                                   */
  749. /* - Formalparameter:                                */
  750. /*    hps     aktueller Presentation Space           */
  751. /*    pRectl  Ausdehnung des ganzen Client-Bereiches */
  752. /*                                                   */
  753. /* - aufgerufen von: PaintWin                        */
  754. /*---------------------------------------------------*/
  755. void DisplayScroll( HPS hps, PRECTL pRectl )
  756. {
  757.   RECTL  R;   // Ausdehnung des Fensters im Client
  758.               //   fuer Ausgabe per WinDrawText
  759.   LONG   lcx; // Breite der Textbox. Damit gecheckt,
  760.               //   ob der Text in den Client passt.
  761.   POINTL aptlTextBox[TXTBOX_COUNT];
  762.               // Array von Punkten, die die
  763.               // Eckkoordinaten der TextBox
  764.               // enthalten
  765.   BOOL   bMsgBox = FALSE; // ist TRUE, wenn die Ausgabe
  766.                           // in einer Messagebox
  767.                           // erfolgen muss, weil der
  768.                           // Client zu klein ist.
  769.   LONG   lLen = 0L;
  770.   BOOL   brc;
  771.   SHORT  src;
  772.  
  773.   // CHECKEN der Text-Dimension
  774.   // Die Hoehe soll mindestens 4 Zeilen betragen
  775.   if ( (cyChar * 4) + cyDesc > (SHORT) pRectl->yTop )
  776.   {
  777.      bMsgBox = TRUE;
  778.   }
  779.   else
  780.   {
  781.     // Bearbeitung von szBoxTitel:
  782.     brc = GpiQueryTextBox ( hps,
  783.                             (LONG)strlen((char *)szBoxTitel),
  784.                             szBoxTitel,
  785.                             TXTBOX_COUNT,
  786.                             aptlTextBox );
  787.     lcx  =  aptlTextBox[TXTBOX_BOTTOMRIGHT].x  -
  788.                aptlTextBox[TXTBOX_BOTTOMLEFT].x ;
  789.  
  790.     // Voraussetzung: pRectl->xLeft des Client ist 0 !
  791.     if ( lcx > pRectl->xRight )
  792.     {
  793.        bMsgBox = TRUE;
  794.     }
  795.     else
  796.     {
  797.       // Bearbeitung von szBoxText, das erst zu fuellen
  798.       if ( bVertScroll )
  799.         lLen = (LONG) sprintf( szBoxText,
  800.                                apchFormatTable[1],
  801.                                sVStart, sVEnd, sVPos );
  802.       else if ( bHorzScroll )
  803.         lLen = (LONG) sprintf( szBoxText,
  804.                                apchFormatTable[2],
  805.                                sHStart, sHEnd, sHPos );
  806.  
  807.       brc = GpiQueryTextBox ( hps,
  808.                               lLen,
  809.                               szBoxText,
  810.                               TXTBOX_COUNT,
  811.                               aptlTextBox );
  812.       lcx  =  aptlTextBox[TXTBOX_BOTTOMRIGHT].x  -
  813.                  aptlTextBox[TXTBOX_BOTTOMLEFT].x ;
  814.  
  815.       if (  lcx  >  pRectl->xRight  )
  816.          bMsgBox = TRUE;
  817.     }
  818.   }
  819.  
  820.   if (  bMsgBox  )
  821.     // hier passt Text nicht in den Client
  822.     //   --> Ausgabe in einer Messagebox
  823.     // szBoxText ist bei Ausgabe in Messagebox
  824.     //   etwas ausfuehrlicher als im Client
  825.   {
  826.     bMsgBox = FALSE;
  827.  
  828.     if ( bVertScroll )
  829.     {
  830.       bVertScroll = FALSE;
  831.       lLen = (LONG) sprintf( szBoxText,
  832.                              apchFormatTable[3],
  833.                              sVStart, sVEnd, sVPos,
  834.                              sTextRows, sTextCols );
  835.     }
  836.     else if ( bHorzScroll )
  837.     {
  838.       bHorzScroll = FALSE;
  839.       lLen = (LONG) sprintf( szBoxText,
  840.                              apchFormatTable[4],
  841.                              sHStart, sHEnd, sHPos,
  842.                              sTextRows, sTextCols );
  843.     }
  844.  
  845.     AusgabeBox();
  846.   }
  847.  
  848.   else  // hier passt der Text in den Client
  849.   {
  850.     R.xLeft   =  pRectl->xLeft;
  851.     R.xRight  =  pRectl->xRight;
  852.  
  853.     // --> Ausgabe rechtsbuendig in den Client
  854.     if ( bVertScroll )
  855.     {
  856.       bVertScroll = FALSE;
  857.  
  858.       R.yTop    = (pRectl->yTop / 2) + ( cyChar * 2 );
  859.       R.yBottom = (pRectl->yTop / 2);
  860.  
  861.       src = WinDrawText( hps, -1,
  862.                          szBoxText, &R,
  863.                          CLR_YELLOW, CLR_BROWN,
  864.                          DT_RIGHT | DT_VCENTER );
  865.  
  866.       R.yTop    = (pRectl->yTop / 2);
  867.       R.yBottom = (pRectl->yTop / 2) - ( cyChar * 2 );
  868.  
  869.       src = WinDrawText( hps, -1,
  870.                          szBoxTitel, &R,
  871.                          CLR_YELLOW, CLR_BROWN,
  872.                          DT_RIGHT | DT_VCENTER );
  873.     }
  874.  
  875.     // --> Ausgabe horizontal zentriert in den Client
  876.     else if ( bHorzScroll )
  877.     {
  878.       bHorzScroll = FALSE;
  879.  
  880.       R.yTop    = pRectl->yBottom + ( cyChar * 4 )
  881.                                   + cyDesc;
  882.       R.yBottom = pRectl->yBottom + ( cyChar * 2 )
  883.                                   + cyDesc;
  884.  
  885.       src = WinDrawText( hps, -1,
  886.                          szBoxText, &R,
  887.                          CLR_YELLOW, CLR_BROWN,
  888.                          DT_BOTTOM | DT_CENTER );
  889.  
  890.       R.yTop    =  pRectl->yBottom + ( cyChar * 2 )
  891.                                    + cyDesc;
  892.       R.yBottom =  pRectl->yBottom + cyDesc;
  893.  
  894.       src = WinDrawText( hps, -1,
  895.                          szBoxTitel, &R,
  896.                          CLR_YELLOW, CLR_BROWN,
  897.                          DT_BOTTOM | DT_CENTER );
  898.     }
  899.   }
  900. }
  901. /*-------  Ende der DisplayScroll-Funktion ----------*/
  902.  
  903.  
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912. /*------  Start der AusgabeBox-Funktion -------------*/
  913. /*                                                   */
  914. /* - Gibt in einer beweglichen, applikationsmodalen  */
  915. /*   Messagebox den Text und den Titel aus, der      */
  916. /*   zu diesem Zeitpunkt in den globalen Variablen   */
  917. /*   szBoxText und szBoxTitel steht.                 */
  918. /*                                                   */
  919. /* - globale Variable:                               */
  920. /*    referiert: szBoxTitel, szBoxText               */
  921. /*                                                   */
  922. /* - aufgerufen von:                                 */
  923. /*       WndCreate ( initial ),                      */
  924. /*       ClientWindowProc ( Programm-Information ),  */
  925. /*       DisplayScroll ( falls Text nicht in den     */
  926. /*                       Client passt ).             */
  927. /*---------------------------------------------------*/
  928. void AusgabeBox ()
  929. {
  930.    WinMessageBox ( HWND_DESKTOP,
  931.                    hwndClient,
  932.                    (PSZ) szBoxText,
  933.                    (PSZ) szBoxTitel,     // Titel
  934.                    (USHORT)NULL,
  935.                    MB_MOVEABLE
  936.                   );
  937. }
  938. /*-------  Ende der AusgabeBox-Funktion -------------*/
  939.  
  940.  
  941.  
  942.  
  943. /*----  Start der LiesKommandoArg-Funktion  ---------*/
  944. /*                                                   */
  945. /* - liest Kommandoargumente fuer die globalen       */
  946. /*   Variablen  sTextRows, sTextCols,                */
  947. /*              sVStart und sHStart                  */
  948. /*   ein.                                            */
  949. /* - Entsprechend der Eingabe werden die globalen    */
  950. /*   Variablen szBoxText und szBoxTitel fuer die     */
  951. /*   initiale Messagebox-Ausgabe gefuellt.           */
  952. /*                                                   */
  953. /* - aufgerufen von: main                            */
  954. /*                                                   */
  955. /*---------------------------------------------------*/
  956. void LiesKommandoArg(int argc, char *argv[] )
  957. {
  958.   // Aendern Textgroesse
  959.   if (argc == 3)
  960.   {
  961.     sTextRows = (USHORT) atoi( argv[1] );
  962.     sTextCols = (USHORT) atoi( argv[2] );
  963.     sVStart   =  BEGIN_V_RANGE;
  964.     sHStart   =  BEGIN_H_RANGE;
  965.  
  966.     sprintf( szBoxText, apchFormatTable[5],
  967.              sTextRows, sTextCols );
  968.     szBoxTitel = "EINGABE:";
  969.   }
  970.  
  971.   // Aendern Textgroesse und Scrollbereich
  972.   else if (argc == 5)
  973.   {
  974.     sTextRows = (USHORT) atoi( argv[1] );
  975.     sTextCols = (USHORT) atoi( argv[2] );
  976.     sVStart   = (USHORT) atoi( argv[3] );
  977.     sHStart   = (USHORT) atoi( argv[4] );
  978.  
  979.     if (  sVStart < 0  ||  sHStart < 0  )
  980.     {
  981.       sVStart  =  BEGIN_V_RANGE;
  982.       sHStart  =  BEGIN_H_RANGE;
  983.  
  984.       sprintf( szBoxText, apchFormatTable[6],
  985.                sTextRows, sTextCols,
  986.                sVStart, sHStart );
  987.       szBoxTitel = "ACHTUNG   !!!";
  988.     }
  989.     else
  990.     {
  991.       sprintf( szBoxText, apchFormatTable[7],
  992.                sTextRows, sTextCols,
  993.                sVStart, sHStart );
  994.       szBoxTitel = "EINGABE:";
  995.     }
  996.   }
  997.  
  998.   // keine oder die falsche Zahl Kommandoarg. einggb.
  999.   else
  1000.   {
  1001.     sTextRows =  STANDARD_ROWS;
  1002.     sTextCols =  STANDARD_COLS;
  1003.     sVStart   =  BEGIN_V_RANGE;
  1004.     sHStart   =  BEGIN_H_RANGE;
  1005.  
  1006.     sprintf( szBoxText, apchFormatTable[8],
  1007.              STANDARD_ROWS, STANDARD_COLS );
  1008.     szBoxTitel = "ACHTUNG   !!!";      // Titel !
  1009.   }
  1010.  
  1011.   sVPos     = sVStart;
  1012.   sHPos     = sHStart;
  1013. }
  1014. /*-----  Ende der LiesKommandoArg-Funktion  ---------*/
  1015.