home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / pmtermsr.lzh / pmscroll.c < prev    next >
C/C++ Source or Header  |  1995-10-13  |  10KB  |  313 lines

  1. #include "pmterm.h"
  2.  
  3. /*
  4.  * This file contains most of the code used to control scrolling
  5.  * of the client window;  it was stolen from another program
  6.  * I wrote and quickly adapted for the PmTerm sample.
  7.  */
  8.  
  9. const char WC_Scroll[] = "ScrollClass";
  10.  
  11. int ClientScrollPaint(SCROLL *scrl);
  12. int vscroll(SCROLL *scrl, MPARAM mp1, MPARAM mp2);
  13. int hscroll(SCROLL *scrl, MPARAM mp1, MPARAM mp2);
  14.  
  15. static MRESULT EXPENTRY ScrollWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  16. {
  17.     SCROLL *scrl = WinQueryWindowPtr(hwnd, 0);
  18.  
  19.     switch (msg) {
  20.     case WM_CREATE:
  21.         scrl = (PVOID)mp1;
  22.         WinSetWindowPtr(hwnd, 0, scrl);
  23.         break;
  24.     case WM_SIZE:
  25.         scrl->xClient = SHORT1FROMMP(mp2);
  26.         scrl->yClient = SHORT2FROMMP(mp2);
  27.             scrl->rows = scrl->yClient / scrl->yChar;
  28.             scrl->cols = scrl->xClient / scrl->xChar;
  29.         vScrollParms(scrl, scrl->vScrollPos, scrl->records); /* recalibrate scroll bar */
  30.         hScrollParms(scrl, scrl->hScrollPos, scrl->width);
  31.         break;
  32.     case WM_CALCVALIDRECTS:
  33.         return (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
  34.     case WM_ERASEBACKGROUND:
  35.         /* Return TRUE to request PM to paint the window background in
  36.          * SYSCLR_WINDOW.
  37.          */
  38.         return (MRESULT) (TRUE);
  39.     case WM_DESTROY:
  40.         free(scrl);
  41.         break;
  42.     case WM_PAINT:
  43.         ClientScrollPaint(scrl);
  44.         break;
  45.         case WM_VSCROLL:
  46.             vscroll(scrl, mp1, mp2);
  47.         break;
  48.     case WM_HSCROLL:
  49.         hscroll(scrl, mp1, mp2);
  50.         break;
  51.     case WM_PRESPARAMCHANGED:
  52.         if( LONGFROMMP(mp1) == PP_FONTNAMESIZE){
  53.            HPS hps;
  54.            hps = WinGetPS(scrl->hwndClient);
  55.                GpiQueryFontMetrics(hps, sizeof(scrl->fm), &scrl->fm);
  56.            WinReleasePS(hps);
  57.                scrl->xChar = (int) scrl->fm.lAveCharWidth;
  58.                scrl->yChar = (int) scrl->fm.lMaxBaselineExt;
  59.                scrl->yDesc = (int) scrl->fm.lMaxDescender;
  60.                scrl->rows = scrl->yClient / scrl->yChar;
  61.                scrl->cols = scrl->xClient / scrl->xChar;
  62.                vScrollParms(scrl, scrl->vScrollPos, scrl->records); /* recalibrate scroll bar */
  63.                hScrollParms(scrl, scrl->hScrollPos, scrl->width);
  64.                //vScrollParms(scrl,  0, scrl->records);
  65.                //hScrollParms(scrl,  0, scrl->width);
  66.                WinInvalidateRect(scrl->hwndFrame, NULL, TRUE);
  67.         }
  68.         break;
  69.     case WMU_PAINTLINES:
  70.         PaintLines(hwnd, (int)mp1, (int)mp2);
  71.         break;
  72.     case WMU_CLS:
  73.         Cls(hwnd);
  74.         break;
  75.         case WMU_PRESCROLL:
  76.             WinScrollWindow(hwnd, 0, scrl->yChar * (int)mp1,
  77.                             NULL, NULL, NULLHANDLE, NULL, SW_INVALIDATERGN);
  78.             break;
  79.     default:
  80.         return WinDefWindowProc(hwnd, msg, mp1, mp2);
  81.     }
  82.     return 0;
  83. }
  84.  
  85. void ScrollRegister(HAB hab, ULONG flStyle)
  86. {
  87.     CLASSINFO clsi;
  88.     if(!WinQueryClassInfo(hab, (PSZ)WC_Scroll, &clsi))
  89.         WinRegisterClass(hab, (PSZ)WC_Scroll, ScrollWindowProc, flStyle, sizeof(SCROLL *));
  90. }
  91.  
  92. int ClientScrollSetup(
  93.     HWND hwndFrame,
  94.     ULONG  records,    /* number of records */
  95.     ULONG  width,      /* max record width, in chars */
  96.     char * (*func)(long recnum, void *user),    /* call back function */
  97.     PVOID  user)       /* user pointer (for application programmer's use) */
  98. {
  99.     HPS hps;
  100.     SCROLL *scrl = malloc(sizeof(SCROLL));
  101.     static const char font[] = "10.System VIO";
  102.  
  103.     ScrollRegister(WinQueryAnchorBlock(hwndFrame), 0);
  104.     memset(scrl, 0, sizeof(scrl));
  105.     scrl->func = func;
  106.     scrl->hwndFrame  = hwndFrame;
  107.     scrl->hwndClient = WinCreateWindow(hwndFrame,
  108.                                        (PSZ)WC_Scroll,
  109.                        NULL,
  110.                        WS_VISIBLE,
  111.                        0, 0,
  112.                        0, 0,
  113.                        hwndFrame,
  114.                        HWND_TOP,
  115.                        FID_CLIENT,    // id
  116.                        scrl,        // ctrl data
  117.                        NULL);
  118.     scrl->user = user;
  119.     WinSetPresParam(scrl->hwndClient, PP_FONTNAMESIZE, sizeof(font), font);
  120.  
  121.     hps = WinGetPS(scrl->hwndClient);
  122.     GpiQueryFontMetrics(hps, sizeof(scrl->fm), &scrl->fm);
  123.     WinReleasePS(hps);
  124.  
  125.     scrl->xChar = (int) scrl->fm.lAveCharWidth;
  126.     scrl->yChar = (int) scrl->fm.lMaxBaselineExt;
  127.     scrl->yDesc = (int) scrl->fm.lMaxDescender;
  128.  
  129.     vScrollParms(scrl,    0, records);
  130.     hScrollParms(scrl,    0, width);
  131.     return(TRUE);
  132. }
  133.  
  134. /* ClientScrollPaint() is called during WM_PAINT.  It calculates
  135.  * which text lines need to be drawn,  then calls the user format
  136.  * function to return a buffer to each of them.
  137.  */
  138. int ClientScrollPaint(SCROLL *scrl)
  139. {
  140.     RECTL rc;                    /* Rectangle coordinates        */
  141.     POINTL pt;                  /* String screen coordinates      */
  142.     int cols, line, ofs;
  143.     char *str;
  144.     int PaintBeg, PaintEnd;
  145.     HPS hps;
  146.  
  147.     hps = WinBeginPaint(scrl->hwndClient, NULLHANDLE, &rc);
  148.     GpiErase(hps);
  149.  
  150.     PaintBeg = max (0, scrl->vScrollPos +
  151.                    (scrl->yClient - (SHORT) rc.yTop) / scrl->yChar);
  152.     PaintEnd = min (scrl->records, scrl->vScrollPos +
  153.                    (scrl->yClient - (SHORT) rc.yBottom)
  154.                         / scrl->yChar + 1);
  155.     pt.x = 0L;
  156.     ofs = scrl->hScrollPos;
  157.     for(line=PaintBeg; line<PaintEnd; line++){
  158.         pt.y = scrl->yClient - scrl->yChar * (line + 1 - scrl->vScrollPos) + scrl->yDesc;
  159.         str = (*scrl->func)(line, scrl->user);
  160.         if(str){
  161.             if(strlen(str) > ofs){
  162.                 cols = strlen(str + ofs);
  163.                 if(cols)
  164.                     GpiCharStringAt( hps, &pt,
  165.                     (ULONG) ((cols > (scrl->cols+5)) ? (scrl->cols+5) : cols),
  166.                     str + ofs);
  167.             }
  168.         }
  169.     }
  170.  
  171.     WinEndPaint(hps);
  172.     return(TRUE);
  173. }
  174.  
  175. int vscroll(SCROLL *scrl, MPARAM mp1, MPARAM mp2)
  176. {
  177.     HWND hwndBar;
  178.     USHORT cmd;
  179.     int setpos = TRUE;
  180.  
  181.     hwndBar = WinWindowFromID(scrl->hwndFrame, SHORT1FROMMP(mp1));
  182.     cmd = SHORT2FROMMP(mp2);
  183.     switch(cmd){
  184.     case SB_LINEUP:
  185.         scrl->vScrollInc = -1;
  186.         break;
  187.     case SB_LINEDOWN:
  188.         scrl->vScrollInc = 1;
  189.         break;
  190.     case SB_PAGEUP:
  191.         scrl->vScrollInc = -scrl->rows;
  192.         break;
  193.     case SB_PAGEDOWN:
  194.         scrl->vScrollInc = scrl->rows;
  195.         break;
  196.     case SB_SLIDERTRACK:
  197.         scrl->vScrollInc = SHORT1FROMMP(mp2) - scrl->vScrollPos;
  198.         setpos = FALSE;
  199.         break;
  200.         case SB_SLIDERPOSITION:
  201.         scrl->vScrollInc = SHORT1FROMMP(mp2) - scrl->vScrollPos;
  202.         break;
  203.     case SB_ENDSCROLL:
  204.         scrl->vScrollInc = 0;
  205.         break;
  206.     default:
  207.         scrl->vScrollInc = 0;
  208.         setpos = FALSE;
  209.         break;
  210.     }
  211.     if(0 != (scrl->vScrollInc = max (-scrl->vScrollPos, min (scrl->vScrollInc, scrl->vScrollMax - scrl->vScrollPos)))){
  212.     scrl->vScrollPos += scrl->vScrollInc;
  213.         WinScrollWindow(scrl->hwndClient, 0, scrl->yChar * scrl->vScrollInc,
  214.             NULL, NULL, NULLHANDLE, NULL, SW_INVALIDATERGN);
  215.         WinUpdateWindow(scrl->hwndClient);
  216.     }
  217.     if( setpos )
  218.     WinSendMsg( hwndBar, SBM_SETPOS, MPFROMSHORT(scrl->vScrollPos), 0L);
  219.     return 0;
  220. }
  221.  
  222. int hscroll(SCROLL *scrl, MPARAM mp1, MPARAM mp2)
  223. {
  224.     HWND hwndBar;
  225.     USHORT cmd;
  226.     int setpos = TRUE;
  227.  
  228.     hwndBar = WinWindowFromID(scrl->hwndFrame, SHORT1FROMMP(mp1));
  229.     cmd = SHORT2FROMMP(mp2);
  230.     switch(cmd){
  231.     case SB_LINELEFT:
  232.         scrl->hScrollInc = -1;
  233.         break;
  234.     case SB_LINERIGHT:
  235.         scrl->hScrollInc = 1;
  236.         break;
  237.     case SB_PAGELEFT:
  238.         scrl->hScrollInc = -max(8, scrl->hScrollMax / 10);
  239.         break;
  240.     case SB_PAGERIGHT:
  241.         scrl->hScrollInc = max(8, scrl->hScrollMax / 10);
  242.         break;
  243.     case SB_SLIDERTRACK:
  244.         scrl->hScrollInc = SHORT1FROMMP(mp2) - scrl->hScrollPos;
  245.         setpos = FALSE;
  246.         break;
  247.     case SB_SLIDERPOSITION:
  248.         scrl->hScrollInc = SHORT1FROMMP(mp2) - scrl->hScrollPos;
  249.         break;
  250.     case SB_ENDSCROLL:
  251.         scrl->hScrollInc = 0;
  252.         break;
  253.     default:
  254.         scrl->hScrollInc = 0;
  255.         setpos = FALSE;
  256.         break;
  257.     }
  258.     if (0 != (scrl->hScrollInc = max (-scrl->hScrollPos, min (scrl->hScrollInc, scrl->hScrollMax - scrl->hScrollPos)))){
  259.     scrl->hScrollPos += scrl->hScrollInc;
  260.         if(scrl->fm.fsType & FM_TYPE_FIXED){
  261.         WinScrollWindow(scrl->hwndClient, -scrl->xChar * scrl->hScrollInc, 0,
  262.                             NULL, NULL, NULLHANDLE, NULL, SW_INVALIDATERGN);
  263.     }
  264.     else{  /* for proportional font, cls() before re-draw */
  265.         WinInvalidateRect( scrl->hwndClient, NULL, FALSE );
  266.     }
  267.         WinUpdateWindow(scrl->hwndClient);
  268.     }
  269.     if( setpos )
  270.     WinSendMsg( hwndBar, SBM_SETPOS, MPFROMSHORT(scrl->hScrollPos), 0L);
  271.     return 0;
  272. }
  273.  
  274.  
  275. BOOL vScrollParms(SCROLL *scrl, ULONG rec, ULONG maxrec)
  276. {
  277.     HWND hwndBar;
  278.  
  279.     if( rec >= maxrec )
  280.     return FALSE;
  281.     scrl->records = maxrec;
  282.     scrl->vScrollMax = max (0, scrl->records - scrl->rows) ;
  283.     scrl->vScrollPos = min (rec, scrl->vScrollMax) ;
  284.     hwndBar = WinWindowFromID( scrl->hwndFrame, FID_VERTSCROLL );
  285.     WinSendMsg(hwndBar, SBM_SETSCROLLBAR,
  286.         MPFROMSHORT(scrl->vScrollPos),           /* slider position */
  287.         MPFROM2SHORT(0, scrl->vScrollMax));       /* slider range    */
  288.     WinSendMsg(hwndBar, SBM_SETTHUMBSIZE,
  289.         MPFROM2SHORT(scrl->rows, scrl->records), 0);
  290.     WinEnableWindow (hwndBar, scrl->vScrollMax ? TRUE : FALSE) ;
  291.     return(TRUE);
  292. }
  293.  
  294. BOOL hScrollParms(SCROLL *scrl, ULONG pos, ULONG maxlen)
  295. {
  296.     HWND hwndBar;
  297.  
  298.     if( pos >= maxlen )
  299.     return FALSE;
  300.     scrl->width = maxlen;
  301.     scrl->hScrollMax = max (0, scrl->width - scrl->cols) ;
  302.     scrl->hScrollPos = min (pos, scrl->hScrollMax) ;
  303.     hwndBar = WinWindowFromID( scrl->hwndFrame, FID_HORZSCROLL );
  304.     WinSendMsg( hwndBar, SBM_SETSCROLLBAR,
  305.         MPFROMSHORT(scrl->hScrollPos),           /* slider position */
  306.         MPFROM2SHORT(0, scrl->hScrollMax));       /* slider range    */
  307.     WinSendMsg(hwndBar, SBM_SETTHUMBSIZE,
  308.         MPFROM2SHORT(scrl->cols, scrl->width), 0);
  309.     WinEnableWindow (hwndBar, scrl->hScrollMax ? TRUE : FALSE) ;
  310.     return(TRUE);
  311. }
  312.  
  313.