home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1990 / 10 / grdlagen / scroll1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-10  |  31.0 KB  |  737 lines

  1. /**********************************************************/
  2. /*                                                        */
  3. /*                      SCROLL1.c                         */
  4. /*           (C) 1990 J. Heid & toolbox                   */
  5. /*                                                        */
  6. /*       1. Version zur Demonstration des Scrollbars      */
  7. /*          F3     : beendet das Programm                 */
  8. /*  Aufruf:  scroll1  [ 50 100 [ 10 10 ] ]                */
  9. /*  - die 4 Argumente sind optional                       */
  10. /*  - Argument 1 / 2: Zahl der Textzeilen und Textspalten */
  11. /*  - Argument 3 / 4: Index der ersten Zeile und Spalte   */
  12. /*          zum Ausdruck des Beginns des Scrollbereiches  */
  13. /*  Benötigte Dateien:                                    */
  14. /*          SCROLL1.c      - Quellcode-Datei              */
  15. /*          SCROLL1.rc     - Resource-Datei               */
  16. /*          SCROLL1.h      - Header-Datei                 */
  17. /*          SCROLL1.def    - Modul-Definitions-Datei      */
  18. /*          SCROLL1.mak    - Make-Datei                   */
  19. /**********************************************************/
  20. #define INCL_WIN
  21. #define INCL_GPI
  22. #include <os2.h>                        // PM-Include-Datei
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include "scroll1.h"              // Symbol. Konstanten für
  27.                                 // scroll1.c und scroll1.rc
  28. #define  STANDARD_COLS   200        // Text mit 200 Spalten
  29. #define  STANDARD_ROWS   100         // Text mit 100 Zeilen
  30. #define  BEGIN_V_RANGE     0          // Standardwerte für
  31. #define  BEGIN_H_RANGE     0          //  den Scrollbereich
  32. /**********************************************************/
  33. /* Funktions-Prototypen                                   */
  34. /**********************************************************/
  35. int     cdecl    main( int, char ** );
  36. BOOL             WndCreate( VOID );
  37. MRESULT EXPENTRY ClientWindowProc( HWND   hwnd, USHORT msg,
  38.                                    MPARAM mp1, MPARAM mp2 );
  39. void             PaintWin( HWND hwnd);
  40. void             DisplayScroll( HPS hps, PRECTL pRectl );
  41. void             AusgabeBox ( VOID );
  42. void             LiesKommandoArg( int argc, char *argv[] );
  43. /**********************************************************/
  44. /* globale Variablen                                      */
  45. /**********************************************************/
  46. HAB  hab;                                  // Programmanker
  47. CHAR szClientClass[] = "KlasseScroll1";
  48.                          //          Name der Fensterklasse
  49. HWND hwndFrame;          //    Handle für das Frame-Fenster
  50. HWND hwndClient;         //   Handle für den Client-Bereich
  51.                          //                    des Fensters
  52. SHORT sVStart,           //   - sVStart und sVEnd bestimmen
  53.       sVEnd  ,           //              den Scrollbereich.
  54.       sVPos  ;           //     (analog sHStart und sHEnd).
  55. SHORT sHStart,           //  - Dieser ist ebenso wie PAGEUP
  56.       sHEnd  ,           // abhängig von der Fenstergrösse!
  57.       sHPos  ;           // - sVStart und sHStart haben als
  58.                          //     Standardwerte BEGIN_V_RANGE
  59.                          //     und BEGIN_H_RANGE (änderbar
  60.                          //      durch Kommandoarg. 3 + 4 )
  61. SHORT cxChar,            //          Grössen des akt. Fonts
  62.       cxCaps,            //           ( benötigte Teile der
  63.       cyChar,            //          FONTMETRICS-Struktur )
  64.       cyDesc;
  65. CHAR  szBoxText[255];    //    enthalten Text und Titel für
  66. PSZ   szBoxTitel;        //   die Ausgabe in der Messagebox
  67.                                           // oder im Client
  68. BOOL  bVertScroll = FALSE;  //              Flagge, welcher
  69. BOOL  bHorzScroll = FALSE;  //     Scrollbar geklickt wurde
  70. SHORT cxClient,          //   Ausdehnung des Clientbereichs
  71.       cyClient ;
  72. SHORT sTextCols;         //      Anzahl der Spalten im Text
  73. SHORT sTextRows;         //       Anzahl der Zeilen im Text
  74.                          //              Standardwerte sind
  75.                          // STANDARD_COLS und STANDARD_COLS
  76.                    //   (änderbar durch Kommandoarg. 1 + 2)
  77.            // Formatstrings für die Meldungen per szBoxText
  78. static CHAR * apchFormatTable [] =
  79. {
  80.   // ---  0  ---
  81.     "Das Programm zeigt die Messages für die \
  82.     Scrollbars an! \
  83.   \nEs nimmt anhand der Kommandoargumente an:\
  84.   \n - der Text, in dem man scrollt, hat\
  85.   \n    %d Zeilen und %d Spalten und \
  86.   \n - die Scrollbereichs-Startwerte sind\
  87.   \n    %d (V) und %d (H).",
  88.   // ---  1  ---
  89.     "Vertikale Ausdehnung=(%d,%d)  Position=%d",
  90.   // ---  2  ---
  91.     "Horizontale Ausdehnung=(%d,%d)  Position=%d",
  92.   // ---  3  ---
  93.     "Vertikale Ausdehnung=(%d,%d)  Position=%d \
  94.   \nText: Zeilen/Spaltenzahl %d / %d",
  95.   // ---  4  ---
  96.     "Horizontale Ausdehnung=(%d,%d)  Position=%d \
  97.   \nText: Zeilen/Spaltenzahl %d / %d",
  98.   // ---  5  ---
  99.     "Das Programm simuliert das Scrollen in einem \
  100.   \nText mit %d Zeilen und %d Spalten.",
  101.   // ---  6  ---
  102.     "Scrollen in einem Text\
  103.  mit %d Zeilen und %d Spalten und\
  104.  mit den Startwerten %d (V) und %d (H).\
  105.   \nStartwerte dürfen nicht negativ sein!",
  106.   // ---  7  ---
  107.     "Das Programm simuliert das Scrollen in einem Text\
  108.  mit %d Zeilen und %d Spalten und\
  109.   \n mit den Startwerten %d (V) und %d (H).",
  110.   // ---  8  ---
  111.     "Es wurden nicht genau 2 bzw. 4 Argumente übergeben.\
  112.  Deshalb wird die Zeilenzahl auf %d und \
  113.  die Spaltenzahl auf %d gesetzt.",
  114. };
  115. /*-------*  Start der main-Funktion  *--------------------*/
  116. /* - initialisiert und terminiert                         */
  117. /* - liest evtl. vorhandene Kommandoargumente             */
  118. /* - enthält Message-Loop                                 */
  119. /* - globale Variablen:     definiert: hab.               */
  120. /*    referiert: hwndFrame.                               */
  121. /* - ruft: WndCreate(), LiesKommandoArg()                 */
  122. /*--------------------------------------------------------*/
  123. int cdecl main (argc, argv)
  124.   int argc;
  125.   char *argv[];
  126. {
  127.   HMQ   hmq;                // Handle für die Message-Queue
  128.   QMSG  qmsg;               // Message in der Message-Queue
  129.   LiesKommandoArg(argc, argv);
  130.   hab = WinInitialize( NULL );          // Initialisiere PM
  131.   hmq = WinCreateMsgQueue( hab, 0 );// Erzeuge Message-Queue
  132.  
  133.   if ( hmq != (HMQ)NULL )
  134.   {
  135.     if ( WndCreate() == TRUE )
  136.     {
  137.       /****************************************************/
  138.       /* "Message-processing-Loop":                       */
  139.       /* Empfängt und verteilt Messages aus der           */
  140.       /* Message-Queue der Anwendung, bis WinGetMsg       */
  141.       /* FALSE zurückgibt: dies geschieht dann, wenn      */
  142.       /* WinGetMsg eine WM_QUIT-Message erhielt.          */
  143.       /****************************************************/
  144.       while( WinGetMsg( hab, (PQMSG)&qmsg, (HWND)NULL, 0, 0)
  145.             )
  146.         WinDispatchMsg( hab, (PQMSG)&qmsg );
  147.       WinDestroyWindow( hwndFrame );
  148.     }
  149.     WinDestroyMsgQueue( hmq );
  150.   }
  151.   WinTerminate( hab );
  152.   return 0;
  153. }
  154. /*-------*  Ende der main-Funktion  *---------------------*/
  155.  
  156. /*-------*  Start der WndCreate-Funktion  *---------------*/
  157. /*                                                        */
  158. /* - registriert die Fensterklasse des Client.            */
  159. /* - erzeugt das Standardfenster.                         */
  160. /* - gibt in einer Message die Größe des fiktiven Textes  */
  161. /*   und die Untergrenzen der Scrollbereiche aus.         */
  162. /* - globale Variablen: definiert: hwndClient, hwndFrame. */
  163. /*              referiert: hab, szClientClass, hwndFrame. */
  164. /* - aufgerufen von: main()                               */
  165. /* - Return: - TRUE,  wenn alles klappt                   */
  166. /*           - FALSE, wenn etwas schiefging. Dann         */
  167. /*                    bricht main() Verarbeitung ab.      */
  168. /*--------------------------------------------------------*/
  169. BOOL WndCreate( VOID )
  170. {                       //         Flaggen für die Erzeugung
  171.   ULONG flCreateFrame;  //                      der Controls
  172.   BOOL  brc;            //    Hilfsvariable zum Abprüfen des
  173.                         // Rückgabewertes von API-Funktionen
  174.                   // Ordne die ClientWndProc einer Klasse zu
  175.   brc = WinRegisterClass(
  176.           hab,              //                 Programmanker
  177.           szClientClass,    //        Name der Fensterklasse
  178.           ClientWindowProc, //      Adr. der Fensterprozedur
  179.           CS_SIZEREDRAW,    //                 Klassen-Style
  180.           0                 // keine Extra-Bytes reservieren
  181.           );
  182.                   // wenn WinRegisterClass nicht erfolgreich
  183.   if ( brc == FALSE ) return ( FALSE );
  184.                    // nun Standardfenster auch mit Actionbar
  185.                    //    und Akzeleratortabelle als Resource
  186.   flCreateFrame = FCF_STANDARD & ~FCF_ICON |
  187.                   FCF_VERTSCROLL | FCF_HORZSCROLL;
  188.                           // Erzeugen eines Standardfensters
  189.   hwndFrame = WinCreateStdWindow(
  190.            HWND_DESKTOP,         // Handle des Vaterfensters
  191.            WS_VISIBLE,           // Style des Frame-Fensters
  192.            (PULONG)&flCreateFrame,
  193.            szClientClass,           // Client-Fenster-Klasse
  194.            " - Scrollbar-Demo",     //     Titel-Erweiterung
  195.            0L,                //   Style des Client-Fensters
  196.            NULL,              // Resourcen sind in EXE-Datei
  197.            ID_RESOURCE,       //    Bezeichner für Resourcen
  198.            (PHWND)&hwndClient //       Zeiger auf den Handle
  199.                               //         des Client-Fensters
  200.            );
  201.                      // WinCreateStdWindow nicht erfolgreich
  202.   if ( hwndFrame == (HWND)NULL ) return ( FALSE );
  203.   AusgabeBox();
  204.   return ( TRUE );
  205. }
  206. /*-------*  Ende der WndCreate-Funktion  *----------------*/
  207.  
  208. /*-------*  Start der Window-Prozedur des Client  *-------*/
  209. /*                                                        */
  210. /* - behandelt die Reaktionen des Clientfensters          */
  211. /* - explizit behandelte Events:                          */
  212. /*     WM_CREATE,  WM_SIZE,   WM_PAINT,  WM_COMMAND,      */
  213. /*     WM_VSCROLL, WM_HSCROLL, WM_CHAR.                   */
  214. /* - aufgerufen von: Presentation Manager                 */
  215. /* - ruft: in WM_PAINT:   PaintWin                        */
  216. /*         in WM_COMMAND: AusgabeBox                      */
  217. /*--------------------------------------------------------*/
  218. MRESULT EXPENTRY ClientWindowProc( HWND hwnd,   USHORT msg,
  219.                                    MPARAM mp1,  MPARAM mp2 )
  220. {                            //   Presentation-Space-Handle
  221.   HPS    hps;                //     Struktur mit Attributen
  222.   FONTMETRICS fm;            //              des akt. Fonts
  223.   static HWND hwndVScroll;   //              Handle für den
  224.                              //        vertikalen Scrollbar
  225.   static HWND hwndHScroll;   //              Handle für den
  226.                              //      horizontalen Scrollbar
  227.   SHORT  sVPosOld, sHPosOld;
  228.   USHORT usVKey;          // Komponente der WM_CHAR-Message
  229.   USHORT command;         //    Command-Wert bei WM_COMMAND
  230.                           //  ID des gewählten Menüeintrags
  231.   switch( msg )
  232.   {
  233.     case WM_CREATE:
  234.       /****************************************************/
  235.       /* - bestimmt die Handles der beiden Scrolls:       */
  236.       /*   wenn nicht möglich, Verarbeitung abgebrochen   */
  237.       /* - bestimmt die Attribute des aktuellen Fonts:    */
  238.       /*   die benötigten Teile werden in den globalen    */
  239.       /*   Varbl. cxChar, cxCaps, cyChar, cyDesc abgelegt */
  240.       /****************************************************/
  241.       hwndVScroll =
  242.           WinWindowFromID( WinQueryWindow( hwnd, QW_PARENT,
  243.                                            FALSE ),
  244.                                            FID_VERTSCROLL );
  245.       hwndHScroll =
  246.           WinWindowFromID( WinQueryWindow( hwnd, QW_PARENT,
  247.                                            FALSE ),
  248.                                            FID_HORZSCROLL );
  249.       if (  hwndVScroll == (HWND)NULL  ||
  250.             hwndHScroll == (HWND)NULL     )
  251.         return ( (MRESULT)TRUE );
  252.       hps = WinGetPS( HWND_DESKTOP );
  253.         GpiQueryFontMetrics( hps, (LONG)sizeof( fm ), &fm );
  254.       WinReleasePS( hps );
  255.       cxChar = (SHORT) fm.lAveCharWidth;
  256.       cxCaps = (SHORT) fm.lEmInc;
  257.       cyChar = (SHORT) fm.lMaxBaselineExt;
  258.       cyDesc = (SHORT) fm.lMaxDescender;
  259.       return 0;
  260.  
  261.     case WM_SIZE:
  262.       /****************************************************/
  263.       /* - bestimmt die Ausdehnung des Client             */
  264.       /* - bestimmt für den vertikalen Scrollbar sVEnd    */
  265.       /*   und sVPos in Abhängigkeit von Client-Höhe und  */
  266.       /*   Font-Grösse.  Damit werden die Slider-Position */
  267.       /*   und der Slider-Bereich festgelegt.             */
  268.       /* - Ist der Text kleiner als der Client, wird      */
  269.       /*   der Scrollbar disabled und unmgekehrt.         */
  270.       /* - Analog beim horizontalen Scrollbar             */
  271.       /****************************************************/
  272.       cxClient = SHORT1FROMMP (mp2) ;
  273.       cyClient = SHORT2FROMMP (mp2) ;
  274.       sVEnd   = max ( sVStart,
  275.                       sTextRows  -  cyClient / cyChar
  276.                                  +  sVStart) ;
  277.       sVPos   = min ( sVPos, sVEnd );
  278.       WinSendMsg( hwndVScroll, SBM_SETSCROLLBAR,
  279.                   MPFROMSHORT( sVPos ),
  280.                   MPFROM2SHORT( sVStart, sVEnd ) );
  281.       WinEnableWindow( hwndVScroll, ( sVEnd - sVStart ) ?
  282.                         TRUE : FALSE
  283.                      );
  284.       sHEnd   = max ( sHStart,
  285.                       sTextCols  -  (cxClient / cxCaps)
  286.                                  +  sHStart );
  287.       sHPos   = min ( sHPos, sHEnd );
  288.       WinSendMsg( hwndHScroll,
  289.                   SBM_SETSCROLLBAR,
  290.                   MPFROMSHORT( sHPos ),
  291.                   MPFROM2SHORT( sHStart, sHEnd ) );
  292.       WinEnableWindow( hwndHScroll,
  293.                        ( sHEnd - sHStart ) ?
  294.                          TRUE : FALSE
  295.                      );
  296.       return 0 ;
  297.     case WM_PAINT:
  298.       /****************************************************/
  299.       /* hier wird der Inhalt des Clients gezeichnet      */
  300.       /****************************************************/
  301.       PaintWin ( hwnd );
  302.       return 0;
  303.     case WM_CHAR:
  304.       /****************************************************/
  305.       /* damit reagiert der Scrollbar auch auf            */
  306.       /*   Eingaben von der Tastatur                      */
  307.       /****************************************************/
  308.                  // die VK-Werte sind definiert in PMWIN.h !
  309.       usVKey = (USHORT) CHARMSG(&msg)->vkey;
  310.       if (  usVKey == VK_UP       ||
  311.             usVKey == VK_DOWN     ||
  312.             usVKey == VK_PAGEUP   ||
  313.             usVKey == VK_PAGEDOWN  )
  314.          return(  WinSendMsg( hwndVScroll, msg, mp1, mp2) );
  315.       else if (  usVKey == VK_LEFT  ||
  316.                  usVKey == VK_RIGHT   )
  317.          return(  WinSendMsg( hwndHScroll, msg, mp1, mp2) );
  318.       else
  319.         break;
  320.     case WM_COMMAND:
  321.       /****************************************************/
  322.       /* Bearbeiten der Menü-Selektion:                   */
  323.       /*  - Die ersten 2 Byte des Message-Parameters mp1  */
  324.       /*    enthalten den "command"-Wert, also den Wert   */
  325.       /*    des Bezeichners für den ausgewählten Eintrag  */
  326.       /*  - Wenn im "Exit und Info"-Submenü der           */
  327.       /*    Eintrag "Exit" gewählt wird, schickt          */
  328.       /*    sich die Anwendung eine WM_QUIT-Message.      */
  329.       /*  - Bei "Resume" tut sie gar nichts.              */
  330.       /*  - Bei "Programm-Information" wird in einer      */
  331.       /*    Messagebox der Zweck des Programms erklärt.   */
  332.       /****************************************************/
  333.       command = COMMANDMSG(&msg)->cmd;
  334.       switch( command )
  335.       {
  336.         case IDM_ABOUT:
  337.           sprintf( szBoxText, apchFormatTable[0],
  338.                    sTextRows, sTextCols, sVStart, sHStart );
  339.           szBoxTitel = "Programmzweck";           // Titel !
  340.           AusgabeBox();
  341.           break;
  342.         case IDM_EXITPROG:
  343.           WinPostMsg( hwnd, WM_QUIT, (MPARAM)0, (MPARAM)0 );
  344.           break;
  345.       }
  346.       break;
  347.     case WM_VSCROLL:
  348.       /***********************************************/
  349.       /* - hier werden alle Fälle einer Message des */
  350.       /*   vertikalen Scrollbars behandelt.          */
  351.       /* - je nachdem, was der Benutzer mit der Maus */
  352.       /*   im Scrollbar macht, nehmen die höheren   */
  353.       /*   beiden Bytes des 2. Messageparameters     */
  354.       /*   verschiedene Werte an.                    */
  355.       /* - Das Programm muss entsprechend auf diese  */
  356.       /*   Informationen reagieren, indem es evtl.   */
  357.       /*   sVPos verändert, den Slider neu setzt    */
  358.       /*   und ein WM_PAINT generiert: dort wird der */
  359.       /*   Text entsprechend dem neuen sVPos neu     */
  360.       /*   ausgegeben.                               */
  361.       /***********************************************/
  362.       sVPosOld = sVPos;
  363.       switch( SHORT2FROMMP(mp2) )
  364.       {
  365.          case SB_LINEUP:
  366.             szBoxTitel = "SB_LINEUP";
  367.             sVPos--;
  368.             break;
  369.          case SB_PAGEUP:
  370.             szBoxTitel = "SB_PAGEUP";
  371.             sVPos -= cyClient / cyChar;
  372.             break;
  373.          case SB_LINEDOWN:
  374.             szBoxTitel = "SB_LINEDOWN";
  375.             sVPos++;
  376.             break;
  377.          case SB_PAGEDOWN:
  378.             szBoxTitel = "SB_PAGEDOWN";
  379.             sVPos += cyClient / cyChar;
  380.             break;
  381.          case SB_SLIDERTRACK:
  382.             szBoxTitel = "SB_SLIDERTRACK";
  383.             sVPos = SHORT1FROMMP(mp2);
  384.             break;
  385.          case SB_SLIDERPOSITION:
  386.             szBoxTitel = "SB_SLIDERPOSITION";
  387.             sVPos = SHORT1FROMMP(mp2);
  388.             break;
  389.          case SB_ENDSCROLL:
  390.             return (MRESULT)0;
  391.          default:
  392.             szBoxTitel = "default";
  393.             return (MRESULT)0;
  394.       }
  395.        //        es gilt:   sVStart  <=  sVPos  <=  sVEnd
  396.        // Identisch: sVPos = max(sVStart, min(sVPos,sVEnd));
  397.       if ( sVPos < sVStart )
  398.          sVPos = sVStart;
  399.       else if ( sVPos > sVEnd )
  400.          sVPos = sVEnd;
  401.       if ( sVPosOld != sVPos )
  402.       {
  403.         WinSendMsg( hwndVScroll, SBM_SETPOS,
  404.                     MPFROMSHORT( sVPos ), MPFROMSHORT( 0 ));
  405.         bVertScroll = TRUE;
  406.         WinInvalidateRect( hwnd, NULL, FALSE );
  407.       }
  408.       break;
  409.     case WM_HSCROLL:
  410.       /***********************************************/
  411.       /* - hier werden alle Fälle einer Message des */
  412.       /*   horizontalen Scrollbars behandelt.        */
  413.       /* - je nachdem, was der Benutzer mit der Maus */
  414.       /*   im Scrollbar macht, nehmen die höheren   */
  415.       /*   beiden Bytes des 2. Messageparameters     */
  416.       /*   verschiedene Werte an.                    */
  417.       /* - Das Programm muss entsprechend auf diese  */
  418.       /*   Informationen reagieren, indem es evtl.   */
  419.       /*   sHPos verändert, den Slider neu setzt    */
  420.       /*   und ein WM_PAINT generiert: dort wird der */
  421.       /*   Text entsprechend dem neuen sHPos neu     */
  422.       /*   ausgegeben.                               */
  423.       /***********************************************/
  424.       sHPosOld = sHPos;
  425.       switch( SHORT2FROMMP(mp2) )
  426.       {
  427.          case SB_LINELEFT:
  428.             szBoxTitel = "SB_LINELEFT";
  429.             sHPos--;
  430.             break;
  431.          case SB_PAGELEFT:
  432.             szBoxTitel = "SB_PAGELEFT";
  433.             sHPos -= cxClient / cxCaps;
  434.             break;
  435.          case SB_LINERIGHT:
  436.             szBoxTitel = "SB_LINERIGHT";
  437.             sHPos++;
  438.             break;
  439.          case SB_PAGERIGHT:
  440.             szBoxTitel = "SB_PAGERIGHT";
  441.             sHPos += cxClient / cxCaps;
  442.             break;
  443.          case SB_SLIDERPOSITION:
  444.             szBoxTitel = "SB_SLIDERPOSITION";
  445.             sHPos = SHORT1FROMMP(mp2);
  446.             break;
  447.          case SB_ENDSCROLL:
  448.             return (MRESULT)0;
  449.          default:
  450.             szBoxTitel = "default";
  451.             return (MRESULT)0;
  452.       }
  453.       // es gilt:   sHStart  <=  sHPos  <=  sHEnd
  454.       // Identisch mit:
  455.       //    sHPos = max(sHStart, min(sHPos,sHEnd));
  456.       // ist:
  457.       if ( sHPos < sHStart )
  458.         sHPos = sHStart;
  459.       else if ( sHPos > sHEnd )
  460.         sHPos = sHEnd;
  461.  
  462.       if ( sHPosOld != sHPos )
  463.       {
  464.         WinSendMsg( hwndHScroll,
  465.                     SBM_SETPOS,
  466.                     MPFROMSHORT( sHPos ),
  467.                     MPFROMSHORT( 0 ) );
  468.         bHorzScroll = TRUE;
  469.         WinInvalidateRect( hwnd, NULL, FALSE );
  470.       }
  471.       break;
  472.     default:         // default für switch( msg )
  473.       return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  474.   }
  475.   return FALSE;
  476. }
  477. /*-------*  Ende der Window-Prozedur des Client  *--------*/
  478.  
  479. /*---------*  Start der PaintWin-Funktion  *--------------*/
  480. /* - schreibt mit GpiCharStringAt die Zeilennummern       */
  481. /*   des fiktiven Textes. Die Nummernwerte sind           */
  482. /*   u.a. abhängig von sVPos und sHPos.                   */
  483. /* - wenn das WM_PAINT durch ein Scroll-Event             */
  484. /*   erzeugt wurde, sitzt eine der beiden Flaggen         */
  485. /*   bVertScroll oder bHorzScroll, was zum Aufruf         */
  486. /*   von DisplayScroll führt.                             */
  487. /* - Formalparameter:                                     */
  488. /*     hwnd   Clientbereich, in den geschrieben wird      */
  489. /* - globale Variablen: referiert: sVPos, sTextRows,      */
  490. /*              cyClient, cyChar, sHPos, cxCaps, cyDesc   */
  491. /* - aufgerufen von: ClientWindowProc, WM_PAINT           */
  492. /*--------------------------------------------------------*/
  493. void PaintWin( HWND hwnd )
  494. {                        //                 Handle cache-PS
  495.   HPS     hps;           //  Struktur Rechteck-Koordinaten:
  496.   RECTL   rectl;         //   erhält Koordinaten des Client
  497.   POINTL  ptl;
  498.   int     i,
  499.           sVPaintBeg,
  500.           sVPaintEnd;
  501.   char    szTmp[10];
  502.   BOOL    brc;
  503.             // macht den ganzen(!) Client zur Update-Region
  504.   brc = WinInvalidateRect( hwnd, NULL, FALSE );
  505.                         // Erzeuge einen Presentation Space
  506.   hps = WinBeginPaint( hwnd, NULL, &rectl );
  507.     brc = WinFillRect( hps, &rectl, CLR_RED );
  508.     brc = GpiSetColor( hps, SYSCLR_WINDOWTEXT );
  509.     brc = GpiSetBackMix( hps, BM_OVERPAINT );
  510.     sVPaintBeg = sVPos;
  511.     sVPaintEnd = min ( sTextRows - 1 + sVPos,
  512.                        cyClient/cyChar - 1 + sVPos
  513.                      );
  514.     for ( i = sVPaintBeg; i <= sVPaintEnd; i++ )
  515.     {
  516.       ptl.x =  8 * cxCaps - sHPos * cxCaps;
  517.       ptl.y =  cyClient  -  (i + 1 - sVPos) * cyChar
  518.                          +  cyDesc;
  519.       itoa( i, szTmp, 10 );
  520.       GpiCharStringAt( hps, &ptl, (LONG) strlen( szTmp ),
  521.                        szTmp
  522.                      );
  523.     }
  524.     if ( bVertScroll || bHorzScroll )
  525.       DisplayScroll( hps, &rectl );
  526.   WinEndPaint( hps );                 // Paint ist erledigt
  527. }
  528. /*------*  Ende der PaintWin-Funktion  *------------------*/
  529.  
  530. /*------*  Start der DisplayScroll-Funktion  *------------*/
  531. /*                                                        */
  532. /* - Falls ein Scroll-Event ein WM_PAINT erzeugt,         */
  533. /*   wird hier die Art der Scroll-Message ausgegeben.     */
  534. /* - Die Ausgabe wird normalerweise in den Client         */
  535. /*   geschrieben; paßt der Text nicht ganz in den Client, */
  536. /*   erfolgt die Ausgabe in einer Messagebox.             */
  537. /* - Formalparameter:                                     */
  538. /*    hps     aktueller Presentation Space                */
  539. /*    pRectl  Ausdehnung des ganzen Client-Bereiches      */
  540. /* - aufgerufen von: PaintWin                             */
  541. /*--------------------------------------------------------*/
  542. void DisplayScroll( HPS hps, PRECTL pRectl )
  543. {
  544.   RECTL  R;           //   Ausdehnung des Fensters im Client
  545.                       //         für Ausgabe per WinDrawText
  546.   LONG   lcx;         // Breite der Textbox. Damit gecheckt,
  547.                       //     ob der Text in den Client paßt.
  548.   POINTL aptlTextBox[TXTBOX_COUNT];
  549.               //   Array von Punkten, die die Eckkoordinaten
  550.               //                       der TextBox enthalten
  551.   BOOL   bMsgBox = FALSE;      // ist TRUE, wenn die Ausgabe
  552.               // in einer Messagebox erfolgen muss, weil der
  553.                                //       Client zu klein ist.
  554.   LONG   lLen = 0L;
  555.   BOOL   brc;
  556.   SHORT  src;
  557.                                // CHECKEN der Text-Dimension
  558.                // Die Höhe soll mindestens 4 Zeilen betragen
  559.   if ( (cyChar * 4) + cyDesc > (SHORT) pRectl->yTop )
  560.   {
  561.      bMsgBox = TRUE;
  562.   }
  563.   else
  564.   {
  565.                                // Bearbeitung von szBoxTitel:
  566.     brc = GpiQueryTextBox ( hps,
  567.                             (LONG)strlen((char *)szBoxTitel),
  568.                             szBoxTitel, TXTBOX_COUNT,
  569.                             aptlTextBox );
  570.     lcx  =  aptlTextBox[TXTBOX_BOTTOMRIGHT].x  -
  571.                aptlTextBox[TXTBOX_BOTTOMLEFT].x ;
  572.            // Voraussetzung: pRectl->xLeft des Client ist 0 !
  573.     if ( lcx > pRectl->xRight )
  574.     {
  575.        bMsgBox = TRUE;
  576.     }
  577.     else
  578.     {
  579.             // Bearbeitung von szBoxText, das erst zu füllen
  580.       if ( bVertScroll )
  581.        lLen = (LONG) sprintf( szBoxText, apchFormatTable[1],
  582.                                sVStart, sVEnd, sVPos );
  583.       else if ( bHorzScroll )
  584.        lLen = (LONG) sprintf( szBoxText, apchFormatTable[2],
  585.                                sHStart, sHEnd, sHPos );
  586.       brc = GpiQueryTextBox ( hps, lLen, szBoxText,
  587.                               TXTBOX_COUNT, aptlTextBox );
  588.       lcx  =  aptlTextBox[TXTBOX_BOTTOMRIGHT].x  -
  589.                  aptlTextBox[TXTBOX_BOTTOMLEFT].x ;
  590.       if (  lcx  >  pRectl->xRight  )
  591.          bMsgBox = TRUE;
  592.     }
  593.   }
  594.   if (  bMsgBox  )    // hier paßt Text nicht in den Client
  595.                  //         --> Ausgabe in einer Messagebox
  596.                  // szBoxText ist bei Ausgabe in Messagebox
  597.                  //       etwas ausführlicher als im Client
  598.   {
  599.     bMsgBox = FALSE;
  600.     if ( bVertScroll )
  601.     {
  602.       bVertScroll = FALSE;
  603.       lLen = (LONG) sprintf( szBoxText, apchFormatTable[3],
  604.                              sVStart, sVEnd, sVPos,
  605.                              sTextRows, sTextCols );
  606.     }
  607.     else if ( bHorzScroll )
  608.     {
  609.       bHorzScroll = FALSE;
  610.       lLen = (LONG) sprintf( szBoxText, apchFormatTable[4],
  611.                              sHStart, sHEnd, sHPos,
  612.                              sTextRows, sTextCols );
  613.     }
  614.     AusgabeBox();
  615.   }
  616.   else                  // hier paßt der Text in den Client
  617.   {
  618.     R.xLeft   =  pRectl->xLeft;
  619.     R.xRight  =  pRectl->xRight;
  620.                   // --> Ausgabe rechtsbündig in den Client
  621.     if ( bVertScroll )
  622.     {
  623.       bVertScroll = FALSE;
  624.       R.yTop    = (pRectl->yTop / 2) + ( cyChar * 2 );
  625.       R.yBottom = (pRectl->yTop / 2);
  626.       src = WinDrawText( hps, -1, szBoxText, &R,
  627.                          CLR_YELLOW, CLR_BROWN,
  628.                          DT_RIGHT | DT_VCENTER );
  629.       R.yTop    = (pRectl->yTop / 2);
  630.       R.yBottom = (pRectl->yTop / 2) - ( cyChar * 2 );
  631.       src = WinDrawText( hps, -1, szBoxTitel, &R,
  632.                          CLR_YELLOW, CLR_BROWN,
  633.                          DT_RIGHT | DT_VCENTER );
  634.     }
  635.           // --> Ausgabe horizontal zentriert in den Client
  636.     else if ( bHorzScroll )
  637.     {
  638.       bHorzScroll = FALSE;
  639.       R.yTop    = pRectl->yBottom + ( cyChar * 4 )
  640.                                   + cyDesc;
  641.       R.yBottom = pRectl->yBottom + ( cyChar * 2 )
  642.                                   + cyDesc;
  643.       src = WinDrawText( hps, -1, szBoxText, &R,
  644.                          CLR_YELLOW, CLR_BROWN,
  645.                          DT_BOTTOM | DT_CENTER );
  646.       R.yTop    =  pRectl->yBottom + ( cyChar * 2 )
  647.                                    + cyDesc;
  648.       R.yBottom =  pRectl->yBottom + cyDesc;
  649.       src = WinDrawText( hps, -1, szBoxTitel, &R,
  650.                          CLR_YELLOW, CLR_BROWN,
  651.                          DT_BOTTOM | DT_CENTER );
  652.     }
  653.   }
  654. }
  655. /*-------*  Ende der DisplayScroll-Funktion  *------------*/
  656.  
  657. /*------*  Start der AusgabeBox-Funktion  *---------------*/
  658. /* - Gibt in einer beweglichen, applikationsmodalen       */
  659. /*   Messagebox den Text und den Titel aus, der           */
  660. /*   zu diesem Zeitpunkt in den globalen Variablen        */
  661. /*   szBoxText und szBoxTitel steht.                      */
  662. /* - globale Variable: referiert: szBoxTitel, szBoxText   */
  663. /* - aufgerufen von: WndCreate ( initial ),               */
  664. /*     ClientWindowProc ( Programm-Information ),         */
  665. /*     DisplayScroll (falls Text nicht in den Client paßt)*/
  666. /*--------------------------------------------------------*/
  667. void AusgabeBox ()
  668. {
  669.   WinMessageBox ( HWND_DESKTOP, hwndClient, (PSZ) szBoxText,
  670.                    (PSZ) szBoxTitel,                // Titel
  671.                    (USHORT)NULL, MB_MOVEABLE
  672.                   );
  673. }
  674. /*-------*  Ende der AusgabeBox-Funktion  *---------------*/
  675.  
  676. /*----*  Start der LiesKommandoArg-Funktion  *------------*/
  677. /*                                                        */
  678. /* - liest Kommandoargumente ein für die globalen         */
  679. /*   Variablen  sTextRows, sTextCols, sVStart und sHStart */
  680. /* - Entsprechend der Eingabe werden die globalen         */
  681. /*   Variablen szBoxText und szBoxTitel für die           */
  682. /*   initiale Messagebox-Ausgabe gefüllt.                 */
  683. /* - aufgerufen von: main                                 */
  684. /*--------------------------------------------------------*/
  685. void LiesKommandoArg(int argc, char *argv[] )
  686. {
  687.   // Aendern Textgrösse
  688.   if (argc == 3)
  689.   {
  690.     sTextRows = (USHORT) atoi( argv[1] );
  691.     sTextCols = (USHORT) atoi( argv[2] );
  692.     sVStart   =  BEGIN_V_RANGE;
  693.     sHStart   =  BEGIN_H_RANGE;
  694.     sprintf( szBoxText, apchFormatTable[5],
  695.              sTextRows, sTextCols );
  696.     szBoxTitel = "EINGABE:";
  697.   }
  698.                        // Ändern Textgröße und Scrollbereich
  699.   else if (argc == 5)
  700.   {
  701.     sTextRows = (USHORT) atoi( argv[1] );
  702.     sTextCols = (USHORT) atoi( argv[2] );
  703.     sVStart   = (USHORT) atoi( argv[3] );
  704.     sHStart   = (USHORT) atoi( argv[4] );
  705.     if (  sVStart < 0  ||  sHStart < 0  )
  706.     {
  707.       sVStart  =  BEGIN_V_RANGE;
  708.       sHStart  =  BEGIN_H_RANGE;
  709.       sprintf( szBoxText, apchFormatTable[6],
  710.                sTextRows, sTextCols, sVStart, sHStart );
  711.       szBoxTitel = "ACHTUNG   !!!";
  712.     }
  713.     else
  714.     {
  715.       sprintf( szBoxText, apchFormatTable[7],
  716.                sTextRows, sTextCols, sVStart, sHStart );
  717.       szBoxTitel = "EINGABE:";
  718.     }
  719.   }
  720.  
  721.         // keine oder die falsche Zahl Kommandoarg. einggb.
  722.   else
  723.   {
  724.     sTextRows =  STANDARD_ROWS;
  725.     sTextCols =  STANDARD_COLS;
  726.     sVStart   =  BEGIN_V_RANGE;
  727.     sHStart   =  BEGIN_H_RANGE;
  728.  
  729.     sprintf( szBoxText, apchFormatTable[8],
  730.              STANDARD_ROWS, STANDARD_COLS );
  731.     szBoxTitel = "ACHTUNG   !!!";      // Titel !
  732.   }
  733.   sVPos     = sVStart;
  734.   sHPos     = sHStart;
  735. }
  736. /*-----*  Ende der LiesKommandoArg-Funktion  *------------*/
  737.