home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1990 / 12 / grdlagen / scroll2.c < prev    next >
Encoding:
Text File  |  1990-09-11  |  17.3 KB  |  436 lines

  1. /**********************************************************/
  2. /*                        SCROLL2.c                       */
  3. /*                                                        */
  4. /*                (C) 1990 J. Heid & toolbox              */
  5. /*                                                        */
  6. /*      2. Version zur Demonstration des Scrollbars       */
  7. /**********************************************************/
  8.  
  9. #define INCL_WIN
  10. #define INCL_GPI
  11. #define INCL_DOS    // Linker-Information für DosGetResource
  12. #include <os2.h>    // PM-Include-Datei
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include "scroll2.h"                   // Symbol. Konstanten
  17. #define  BEGIN_V_RANGE  0              // Standardwerte für
  18. #define  BEGIN_H_RANGE  0              // den Scrollbereich
  19. #define  EINRUECKUNG    3              // linker Rand
  20.  
  21. /* Funktions-Prototypen: */
  22. int     cdecl    main(             VOID );
  23. BOOL             WndCreate(        VOID );
  24. MRESULT EXPENTRY ClientWindowProc( HWND hwnd,  USHORT msg,
  25.                                    MPARAM mp1, MPARAM mp2 );
  26. void             PaintWin(     HWND hwnd);
  27. void             AusgabeBox(   VOID );
  28. BOOL             FrageBox(     VOID );
  29. int              SaveLineInfo( HWND  hwnd,
  30.                                SHORT sLineNo,
  31.                                SHORT sLineLength,
  32.                                PCHAR pText );
  33. /* globale Variablen: */
  34. HAB  hab;                      //              Programmanker
  35. CHAR szClientClass[] = "KlasseScroll2";
  36. HWND hwndFrame;                //   Handle für Frame-Fenster
  37. HWND hwndClient;               //     Handle für den Client-
  38.                                //       bereich des Fensters
  39. SHORT sVStart = BEGIN_V_RANGE, //      Scrollbereichsgrenzen
  40.       sVEnd,                   //       und Sliderpositionen
  41.       sVPos  ;                 //         für den vertikalen
  42. SHORT sHStart = BEGIN_H_RANGE, //           und horizontalen
  43.       sHEnd, sHPos ;           //                  Scrollbar
  44. SHORT cxChar, cxCaps     // Größen des akt. Fonts (benötigte
  45.       cxChar, cyDesc;    // (Teile der FONTMETRICS-Struktur)
  46. CHAR  szQuelldatei[255];    //  Name der Text-Resource-Datei
  47. CHAR  szBoxText[255];       //  enthalten Text und Titel für
  48. PSZ   szBoxTitel;           // die Ausgabe in der Messagebox
  49. BOOL  bPixelweise = FALSE;  //         TRUE, wenn horizontal
  50.                             //        pixelweise zu scrollen
  51. SHORT cxClient, cyClient ;  // Ausdehnung des Clientbereichs
  52. SHORT sLongestRow = 0;         //  Nummer der längsten Zeile
  53. SHORT sTextCols = 0;           // Anzahl der Spalten im Text
  54. SHORT sTextRows = 0;           //  Anzahl der Zeilen im Text
  55. PCHAR pResource ;              //    Zeiger auf Textresource
  56. ULONG ulSegSize ;              //     Länge der Textresource
  57. typedef struct TEXTPOINTER     //  Zeilenweise Informationen
  58. {                              //        zu dem Text aus der
  59.   SHORT sLineNumber;           //         Textresourcedatei:
  60.   SHORT sLineLength;           //   Zeilennummer, -länge und
  61.   PCHAR pTextplace;            //    Zeiger auf Zeilenanfang
  62. } TEXTPOINTER;
  63. TEXTPOINTER *apstructText;
  64.  
  65. /*---  Formatstrings für die Meldungen per szBoxText:  ---*/
  66. static CHAR * apchFormatTable [] =
  67. { "Das Programm gibt den Text aus, der in der \
  68.   \nResource-Datei \"%s\" steht. \
  69.   \n\nDer Text besteht aus %d Zeilen. \
  70.   \nDie längste Zeile(Nr. %d) hat %d Zeichen. \
  71.   \n\nInnerhalb dieses Textes kann per Maus und \
  72.   \nTastatur gescrollt werden." ,
  73.   "Das Programm gibt den Text aus, der in der \
  74.   \nResource-Datei \"%s\" steht. \
  75.   \n\nDer Text besteht aus %d Zeilen. \
  76.   \nDie längste Zeile(Nr. %d) hat %d Pixel. \
  77.   \n\nInnerhalb dieses Textes kann per Maus und \
  78.   \nTastatur gescrollt werden." ,
  79.   "Man konnte mit malloc nicht genug Speicher \
  80.   \nfür die Struktur apstructText besorgen. \
  81.   \n\nDas Programm terminiert deshalb. \
  82.   \n\nDer Text hatte eine Länge von %d Zeilen.",
  83.   "Abbruch in WM_CREATE. \
  84.   \n\nDie Textresource konnte nicht geladen werden. \
  85.   \n\nRückgabewert von DosGetResource: %d." };
  86.  
  87. /*------------  Start der main-Funktion  -----------------*/
  88. int cdecl main ( void )
  89. {
  90.   HMQ   hmq;                 // Handle für die Message-Queue
  91.   QMSG  qmsg;                // Message in der Message-Queue
  92.   hab = WinInitialize( 0 );         //      Initialisiere PM
  93.   hmq = WinCreateMsgQueue(hab, 0);  // Erzeuge Message-Queue
  94.   if ( hmq != (HMQ)NULL )
  95.   {
  96.     if ( WndCreate() == TRUE )
  97.     {
  98.       while( WinGetMsg( hab, (PQMSG)&qmsg, (HWND)NULL,0,0))
  99.         WinDispatchMsg( hab, (PQMSG)&qmsg );
  100.       WinDestroyWindow( hwndFrame );
  101.     }
  102.     WinDestroyMsgQueue( hmq );
  103.   }
  104.   WinTerminate( hab );
  105.   return 0;
  106. }
  107.  
  108. /*------------  Start der WndCreate-Funktion -------------*/
  109. BOOL WndCreate( VOID )
  110. {
  111.   static CHAR  szTitleBar [40] ;
  112.   ULONG  flCreateFrame; //   Flags für Control-Erzeugung CON
  113.   BOOL   brc;           //   Hilfsvariablen zum Abprüfen des
  114.   USHORT usrc;          // Rückgabewertes von API-Funktionen
  115.   usrc = WinLoadString (hab, (HMODULE)NULL, IDS_TITLE,
  116.                        sizeof(szTitleBar), (PSZ)szTitleBar);
  117.   usrc = WinLoadString (hab, (HMODULE)NULL, IDS_FILE,
  118.                  sizeof (szQuelldatei), (PSZ)szQuelldatei );
  119.   brc = WinRegisterClass(
  120.           hab,              //                 Programmanker
  121.           szClientClass,    //        Name der Fensterklasse
  122.           ClientWindowProc, //      Adr. der Fensterprozedur
  123.           CS_SIZEREDRAW,    //                 Klassen-Style
  124.           0 );              // keine Extra-Bytes reservieren
  125.   if ( brc == FALSE ) return ( FALSE );
  126.   flCreateFrame = FCF_STANDARD & ~FCF_ICON |
  127.                   FCF_VERTSCROLL | FCF_HORZSCROLL;
  128.   hwndFrame = WinCreateStdWindow(
  129.            HWND_DESKTOP,     //     Handle des Vaterfensters
  130.            WS_VISIBLE,       //     Style des Frame-Fensters
  131.            (PULONG)&flCreateFrame,
  132.            szClientClass,    //        Client-Fenster-Klasse
  133.            szTitleBar,       //            Titel-Erweiterung
  134.            0L,               //    Style des Client-Fensters
  135.            (HMODULE)NULL,    //  Resourcen sind in EXE-Datei
  136.            ID_RESOURCE,      //     Bezeichner für Resourcen
  137.            (PHWND)&hwndClient); //     Zeiger auf den Handle
  138.                                 //       des Client-Fensters
  139.   if ( hwndFrame == (HWND)NULL ) return ( FALSE );
  140.   return ( TRUE );
  141. }
  142.  
  143. /*---------  Start der Window-Prozedur des Client --------*/
  144. MRESULT EXPENTRY ClientWindowProc( HWND hwnd, USHORT msg,
  145.                                    MPARAM mp1, MPARAM mp2 )
  146. {
  147.   HPS    hps;              //      Presentation-Space-Handle
  148.   FONTMETRICS fm;          //    Struktur mit Attributen des
  149.                            //                     akt. Fonts
  150.   static HWND hwndVScroll; //  Handle für den vert. Scr.-Bar
  151.   static HWND hwndHScroll; //  Handle für den horz. Scr.-Bar
  152.   SHORT  sVPosOld, sHPosOld;
  153.   static SEL    selResource ;   //        static, da auch in
  154.                                 //      WM_DESTROY benötigt!
  155.   PCHAR         pText ;
  156.   PCHAR         pTextLauf, pTextAnfang ;
  157.   SHORT         sLineLength;
  158.   static SHORT  sNumLines = 0;
  159.   static SHORT  sLineNo = 0;
  160.   USHORT usVKey;           // Komponente der WM_CHAR-Message
  161.   USHORT command;          //    Command-Wert bei WM_COMMAND
  162.                            //  ID des gewählten Menüeintrags
  163.   int    rc;               //    Hilfsvariablen zum Abprüfen
  164.   BOOL   brc;              //     der Rückgabewerte der API-
  165.   USHORT usrc;             //                     Funktionen
  166.   switch( msg )
  167.   {
  168.     case WM_CREATE:
  169.       hwndVScroll =
  170.           WinWindowFromID( WinQueryWindow( hwnd, QW_PARENT,
  171.                            FALSE ), FID_VERTSCROLL );
  172.       hwndHScroll =
  173.           WinWindowFromID( WinQueryWindow( hwnd, QW_PARENT,
  174.                            FALSE ), FID_HORZSCROLL );
  175.       if (  hwndVScroll == (HWND)NULL  ||
  176.             hwndHScroll == (HWND)NULL     )
  177.         return ( (MRESULT)TRUE );
  178.       usrc = DosGetResource ( (HMODULE)NULL, IDT_TEXT,
  179.                                IDT_GEDICHT, &selResource );
  180.       if ( usrc != 0 )
  181.       {
  182.         sprintf( szBoxText, apchFormatTable[3], usrc);
  183.         szBoxTitel = "Programmabbruch"; AusgabeBox();
  184.         return ( (MRESULT)TRUE );
  185.       }
  186.       usrc = DosSizeSeg (selResource, &ulSegSize) ;
  187.       pResource = MAKEP (selResource, 0) ;
  188.       pText = pResource ;
  189.       while (pText - pResource < (USHORT) ulSegSize)
  190.       {
  191.         if (*pText == '\r') sNumLines ++ ;
  192.         pText++ ;
  193.       }
  194.       sTextRows = sNumLines+1;  pTextLauf   = pResource ;
  195.       pTextAnfang = pResource ; sLineLength = 0 ;
  196.  
  197.       while (pTextLauf - pResource < (USHORT)ulSegSize)
  198.       {
  199.         if (*pTextLauf == '\r')
  200.         {
  201.           rc = SaveLineInfo( hwnd, sLineNo,
  202.                              max( 0, sLineLength-2 ),
  203.                              pTextAnfang );
  204.           if ( rc == -1 ) return ( (MRESULT)TRUE );
  205.           sLineNo ++ ; pTextAnfang = pTextLauf + 2;
  206.           sLineLength = 0 ;
  207.         }
  208.  
  209.         pTextLauf++ ; sLineLength ++ ;
  210.       }
  211.       rc = SaveLineInfo( hwnd, sLineNo, max(
  212.                          0, sLineLength-2 ), pTextAnfang );
  213.       if ( rc == -1 ) return ( (MRESULT)TRUE );
  214.       hps = WinGetPS( HWND_DESKTOP );
  215.         brc = GpiQueryFontMetrics(hps,(LONG)sizeof(fm),&fm);
  216.       WinReleasePS( hps );
  217.       cxChar = (SHORT) fm.lAveCharWidth;
  218.       cxCaps = (SHORT) fm.lEmInc;
  219.       cyChar = (SHORT) fm.lMaxBaselineExt;
  220.       cyDesc = (SHORT) fm.lMaxDescender;
  221.       return 0;
  222.     case WM_SIZE:
  223.       cxClient = SHORT1FROMMP (mp2) ;
  224.       cyClient = SHORT2FROMMP (mp2) ;
  225.       sVEnd   = max ( sVStart, sTextRows - cyClient / cyChar
  226.                    +  sVStart) ;
  227.       sVPos   = min ( sVPos, sVEnd );
  228.       WinSendMsg( hwndVScroll, SBM_SETSCROLLBAR, MPFROMSHORT
  229.                 ( sVPos ), MPFROM2SHORT( sVStart, sVEnd ) );
  230.       WinEnableWindow( hwndVScroll, ( sVEnd - sVStart ) ?
  231.                         TRUE : FALSE );
  232.       if ( bPixelweise )
  233.       {
  234.         sHEnd = max ( sHStart, sTextCols - cxClient
  235.                     + sHStart + EINRUECKUNG * cxCaps );
  236.       }
  237.       else
  238.       {
  239.         sHEnd = max ( sHStart, sTextCols - (cxClient /
  240.                         cxCaps) + sHStart + EINRUECKUNG  );
  241.       }
  242.       sHPos = min ( sHPos, sHEnd );
  243.       WinSendMsg( hwndHScroll, SBM_SETSCROLLBAR,
  244.                   MPFROMSHORT( sHPos ),
  245.                   MPFROM2SHORT( sHStart, sHEnd ) );
  246.       WinEnableWindow( hwndHScroll, ( sHEnd - sHStart ) ?
  247.                          TRUE : FALSE );
  248.       return 0 ;
  249.     case WM_PAINT: PaintWin ( hwnd ); return 0;
  250.     case WM_CHAR:
  251.       usVKey = (USHORT) CHARMSG(&msg)->vkey;
  252.       if (  usVKey == VK_UP       ||
  253.             usVKey == VK_DOWN     ||
  254.             usVKey == VK_PAGEUP   ||
  255.             usVKey == VK_PAGEDOWN  )
  256.          return( WinSendMsg( hwndVScroll, msg, mp1, mp2) );
  257.       else if ( usVKey == VK_LEFT || usVKey == VK_RIGHT )
  258.          return( WinSendMsg( hwndHScroll, msg, mp1, mp2) );
  259.       else break;
  260.     case WM_COMMAND:
  261.       command = COMMANDMSG(&msg)->cmd;
  262.       switch( command )
  263.       {
  264.         case IDM_ABOUT:
  265.           if ( !bPixelweise )
  266.           {
  267.             sprintf( szBoxText, apchFormatTable[0],
  268.                      szQuelldatei, sTextRows,
  269.                      sLongestRow, sTextCols);
  270.           }
  271.           else
  272.           {
  273.             sprintf( szBoxText, apchFormatTable[1],
  274.                      szQuelldatei, sTextRows,
  275.                      sLongestRow, sTextCols);
  276.           }
  277.           szBoxTitel = "Programminformation";
  278.           AusgabeBox(); break;
  279.         case IDM_EXITPROG:
  280.           WinPostMsg( hwnd, WM_QUIT, (MPARAM)0, (MPARAM)0 );
  281.           break;
  282.       }
  283.       break;
  284.     case WM_VSCROLL:
  285.       sVPosOld = sVPos;
  286.       switch( SHORT2FROMMP(mp2) )
  287.       {
  288.        case SB_LINEUP:      sVPos--; break;
  289.        case SB_PAGEUP:      sVPos -= cyClient/cyChar; break;
  290.        case SB_LINEDOWN:    sVPos++; break;
  291.        case SB_PAGEDOWN:    sVPos += cyClient/cyChar; break;
  292.        case SB_SLIDERTRACK: sVPos = SHORT1FROMMP(mp2);break;
  293.        default:             return (MRESULT)0;
  294.       }
  295.       if ( sVPos < sVStart ) sVPos = sVStart;
  296.       else if ( sVPos > sVEnd ) sVPos = sVEnd;
  297.       if ( sVPosOld != sVPos )
  298.       {
  299.         WinSendMsg( hwndVScroll, SBM_SETPOS, MPFROMSHORT(
  300.                     sVPos ), MPFROMSHORT( 0 ) );
  301.         WinInvalidateRect( hwnd, NULL, FALSE );
  302.       }
  303.       break;
  304.     case WM_HSCROLL:
  305.       sHPosOld = sHPos;
  306.       switch( SHORT2FROMMP(mp2) )
  307.       {
  308.          case SB_LINELEFT:  sHPos--; break;
  309.          case SB_PAGELEFT:  if ( bPixelweise )
  310.                             { sHPos -= cxClient; }
  311.                       else  { sHPos -= cxClient / cxCaps; }
  312.               break;
  313.          case SB_LINERIGHT: sHPos++; break;
  314.          case SB_PAGERIGHT: if ( bPixelweise )
  315.                             { sHPos += cxClient; }
  316.                        else { sHPos += cxClient / cxCaps; }
  317.               break;
  318.          case SB_SLIDERPOSITION:
  319.                            sHPos = SHORT1FROMMP(mp2); break;
  320.          default:          return (MRESULT)0;
  321.       }
  322.       if ( sHPos < sHStart ) sHPos = sHStart;
  323.       else if ( sHPos > sHEnd ) sHPos = sHEnd;
  324.       if ( sHPosOld != sHPos )
  325.       {
  326.         WinSendMsg( hwndHScroll, SBM_SETPOS,
  327.                    MPFROMSHORT( sHPos ), MPFROMSHORT( 0 ) );
  328.         WinInvalidateRect( hwnd, NULL, FALSE );
  329.       }
  330.       break;
  331.     default: return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  332.   }
  333.   return FALSE;
  334. }
  335.  
  336. /*-------------  Start der PaintWin-Funktion -------------*/
  337. void PaintWin( HWND hwnd )
  338. {
  339.   HPS     hps;            //                 Handle Cache-PS
  340.   RECTL   rectl;          //  Struktur Rechteck-Koordinaten:
  341.                           //   erhält Koordinaten des Client
  342.   POINTL  ptl;
  343.   int     i, sVPaintBeg, sVPaintEnd;
  344.   BOOL    brc;
  345.   hps = WinBeginPaint( hwnd, NULL, &rectl );
  346.     brc = WinFillRect( hps, &rectl, CLR_RED );
  347.     brc = GpiSetColor( hps, SYSCLR_WINDOWTEXT );
  348.     brc = GpiSetBackMix( hps, BM_OVERPAINT );
  349.     sVPaintBeg = sVPos;
  350.     sVPaintEnd = min ( sTextRows - 1 + sVPos,
  351.                        cyClient/cyChar - 1 + sVPos );
  352.     for ( i = sVPaintBeg; i <= sVPaintEnd; i++ )
  353.     {
  354.       if ( !bPixelweise )
  355.       { ptl.x =  ( EINRUECKUNG - sHPos ) * cxCaps; }
  356.       else
  357.       { ptl.x =  EINRUECKUNG * cxCaps  -  sHPos; }
  358.       ptl.y = cyClient - (i + 1 - sVPos) * cyChar + cyDesc;
  359.       GpiCharStringAt( hps, &ptl,
  360.                        (LONG)(apstructText+i)->sLineLength,
  361.                        (apstructText+i)->pTextplace );
  362.     }
  363.   WinEndPaint( hps );
  364. }
  365.  
  366. /*-----------  Start der AusgabeBox-Funktion -------------*/
  367. void AusgabeBox ()
  368. {
  369.    WinMessageBox (HWND_DESKTOP, hwndClient, (PSZ) szBoxText,
  370.               (PSZ) szBoxTitel, (USHORT)NULL, MB_MOVEABLE );
  371. }
  372.  
  373. /*------------  Start der FrageBox-Funktion --------------*/
  374. BOOL FrageBox ( VOID )
  375. {
  376.   USHORT usrc;
  377.   szBoxTitel = "Wie soll horizontal gescrollt werden?";
  378.   strcpy( szBoxText, "Wenn Sie horizontal pixelweise \
  379.                       \nscrollen möchten, \
  380.                       \nwählen Sie bitte \"YES\" :");
  381.  
  382.   usrc = WinMessageBox ( HWND_DESKTOP, hwndClient,
  383.                      (PSZ) szBoxText, (PSZ) szBoxTitel,
  384.                      (USHORT)NULL, MB_MOVEABLE | MB_YESNO );
  385.   if ( usrc == MBID_YES ) return ( TRUE );
  386.   else return (FALSE);
  387. }
  388.  
  389. /*----------  Start der SaveLineInfo-Funktion  -----------*/
  390. int  SaveLineInfo( HWND  hwnd, SHORT sLineNo,
  391.                    SHORT sLineLength, PCHAR pText )
  392. {
  393.   static int initial = 1;
  394.   HPS    hps;
  395.   CHAR   szTmp[255];   // max. Zeilenlänge!
  396.   SHORT  scx;          // Breite der Textbox.
  397.   POINTL aptlTextBox[TXTBOX_COUNT];
  398.   BOOL   brc;
  399.   if ( initial )
  400.   {
  401.     apstructText = (TEXTPOINTER *) malloc (
  402.                     sTextRows * sizeof(TEXTPOINTER) );
  403.     if ( apstructText == NULL )
  404.     {
  405.       sprintf( szBoxText, apchFormatTable[2], sTextRows );
  406.       szBoxTitel = "Programmabsturz";
  407.       AusgabeBox(); return (-1);
  408.     }
  409.     bPixelweise = FrageBox(); initial = 0;
  410.   }
  411.   if ( !bPixelweise )
  412.   {
  413.     if ( sLineLength > sTextCols )
  414.     { sTextCols   = sLineLength; sLongestRow = sLineNo; }
  415.   }
  416.   else
  417.   {
  418.     memcpy(szTmp, (void *)pText, sLineLength );
  419.     szTmp[sLineLength] = '\0'; hps = WinGetPS( hwnd );
  420.       brc = GpiQueryTextBox ( hps, (LONG)sLineLength,
  421.                               szTmp, TXTBOX_COUNT,
  422.                               aptlTextBox );
  423.     WinReleasePS( hps );
  424.     scx = (SHORT) (aptlTextBox[TXTBOX_BOTTOMRIGHT].x
  425.                  - aptlTextBox[TXTBOX_BOTTOMLEFT].x);
  426.  
  427.     if ( scx > sTextCols )
  428.     { sTextCols = scx; sLongestRow = sLineNo; }
  429.   }
  430.   (apstructText + sLineNo)->sLineNumber = sLineNo;
  431.   (apstructText + sLineNo)->sLineLength = sLineLength;
  432.   (apstructText + sLineNo)->pTextplace  = pText;
  433.   return (0);
  434. }
  435. /*-------------- Ende von SCROLL2.C ----------------------*/
  436.