home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1991 / 05 / d_flat / listbox.c < prev    next >
Text File  |  1991-02-18  |  5KB  |  182 lines

  1. /* ------------- listbox.c ------------ */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "dflat.h"
  7.  
  8. static void near writeselection(WINDOW, int, int, RECT *);
  9. static void near change_selection(WINDOW, int);
  10. static int near selection_in_window(WINDOW, int);
  11.  
  12.  
  13. int ListBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  14. {
  15.     int rtn;
  16.     static int py = -1;
  17.     int my = (int) p2 - GetTop(wnd);
  18.  
  19.     if (my >= wnd->wlines-wnd->wtop)
  20.         my = wnd->wlines - wnd->wtop;
  21.  
  22.     switch (msg)    {
  23.         case CREATE_WINDOW:
  24.             rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
  25.             wnd->selection = -1;
  26.             return rtn;
  27.         case ADDTEXT:
  28.             p2 = wnd->wlines == wnd->selection;
  29.             break;
  30.         case CLEARTEXT:
  31.             wnd->selection = -1;
  32.             break;
  33.         case SCROLL:
  34.             rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
  35.             if (!selection_in_window(wnd, wnd->selection))    {
  36.                 if (p1)
  37.                     PostMessage(wnd, LB_SELECTION, wnd->selection+1, FALSE);
  38.                 else
  39.                     PostMessage(wnd, LB_SELECTION, wnd->selection-1, FALSE);
  40.             }
  41.             else
  42.                 writeselection(wnd, wnd->selection, TRUE, NULL);
  43.             return rtn;
  44.         case KEYBOARD:
  45.             if (WindowMoving || WindowSizing)
  46.                 break;
  47.             switch ((int) p1)    {
  48.                 case UP:
  49.                     if (wnd->selection > 0)    {
  50.                         if (wnd->selection == wnd->wtop)    {
  51.                             writeselection(wnd, wnd->selection, FALSE, NULL);
  52.                             --wnd->selection;
  53.                             rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
  54.                             PostMessage(wnd, LB_SELECTION, wnd->selection, FALSE);
  55.                         }
  56.                         else    {
  57.                             int newsel = wnd->selection-1;
  58.                             if (wnd->wlines == ClientHeight(wnd))
  59.                                 while (*TextLine(wnd, newsel) == LINE)
  60.                                     --newsel;
  61.                             PostMessage(wnd, LB_SELECTION, newsel, FALSE);
  62.                         }
  63.                     }
  64.                     return TRUE;
  65.                 case DN:
  66.                     if (wnd->selection < wnd->wlines-1)    {
  67.                         if (wnd->selection == wnd->wtop+ClientHeight(wnd)-1)    {
  68.                             writeselection(wnd, wnd->selection, FALSE, NULL);
  69.                             wnd->selection++;
  70.                             rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
  71.                             PostMessage(wnd, LB_SELECTION, wnd->selection, FALSE);
  72.                         }
  73.                         else    {
  74.                             int newsel = wnd->selection+1;
  75.                             if (wnd->wlines == ClientHeight(wnd))
  76.                                 while (*TextLine(wnd, newsel) == LINE)
  77.                                     newsel++;
  78.                             PostMessage(wnd, LB_SELECTION, newsel, FALSE);
  79.                         }
  80.                     }
  81.                     return TRUE;
  82.                 case PGUP:
  83.                 case PGDN:
  84.                     rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
  85.                     PostMessage(wnd, LB_SELECTION, wnd->wtop, FALSE);
  86.                     return rtn;
  87.                 case HOME:
  88.                     rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
  89.                     PostMessage(wnd, LB_SELECTION, 0, FALSE);
  90.                     return rtn;
  91.                 case END:
  92.                     rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
  93.                     PostMessage(wnd, LB_SELECTION, wnd->wlines-1, FALSE);
  94.                     return rtn;
  95.                 case '\r':
  96.                     if (wnd->selection != -1)    {
  97.                         WINDOW pwnd = GetParent(wnd);
  98.                         SendMessage(wnd, LB_SELECTION, wnd->selection, TRUE);
  99.                         SendMessage(pwnd, LB_CHOOSE, wnd->selection, 0);
  100.                     }
  101.                     return TRUE;
  102.                 default:
  103.                     break;
  104.             }
  105.             break;
  106.         case BUTTON_RELEASED:
  107.             py = -1;
  108.             break;
  109.         case LEFT_BUTTON:
  110.             if (!(WindowMoving || WindowSizing))    {
  111.                 RECT rc = ClientRect(wnd);
  112.                 if (!InsideRect(p1, p2, rc))
  113.                     break;
  114.                 if (my != py)    {
  115.                     int newsel = wnd->wtop+my-1;
  116.                     if (*TextLine(wnd, newsel) != LINE)
  117.                         SendMessage(wnd, LB_SELECTION, newsel, TRUE);
  118.                     py = my;
  119.                 }
  120.                 return TRUE;
  121.             }
  122.             break;
  123.         case DOUBLE_CLICK:
  124.             BaseWndProc(LISTBOX, wnd, msg, p1, p2);
  125.             if (!(WindowMoving || WindowSizing))
  126.                 SendMessage(GetParent(wnd), LB_CHOOSE, wnd->selection, 0);
  127.             return TRUE;
  128.         case LB_SETSELECTION:
  129.             change_selection(wnd, (int) p1);
  130.             return TRUE;
  131.         case LB_SELECTION:    {
  132.             WINDOW pwnd = GetParent(wnd);
  133.             CLASS class = GetClass(pwnd);
  134.             change_selection(wnd, (int) p1);
  135.             if (class != LISTBOX && DerivedClass(class) != LISTBOX)
  136.                 SendMessage(GetParent(wnd), LB_SELECTION, wnd->selection, 0);
  137.             return TRUE;
  138.         }
  139.         case LB_CURRENTSELECTION:
  140.             return wnd->selection;
  141.         case LB_GETTEXT:
  142.             if ((int)p2 != -1)    {
  143.                 char *cp1 = (char *)p1;
  144.                 char *cp2 = TextLine(wnd, (int)p2);
  145.                 while (cp2 && *cp2 && *cp2 != '\n')
  146.                     *cp1++ = *cp2++;
  147.                 *cp1 = '\0';
  148.             }
  149.             return TRUE;
  150.         case PAINT:
  151.             if (isVisible(wnd))    {
  152.                 rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
  153.                 writeselection(wnd, wnd->selection, TRUE, (RECT *)p1);
  154.                 return rtn;
  155.             }
  156.             break;
  157.         default:
  158.             break;
  159.     }
  160.     return BaseWndProc(LISTBOX, wnd, msg, p1, p2);
  161. }
  162.  
  163. static int near selection_in_window(WINDOW wnd, int sel)
  164. {
  165.     return (wnd->wlines && sel >= wnd->wtop && sel < wnd->wtop+ClientHeight(wnd));
  166. }
  167.  
  168. static void near writeselection(WINDOW wnd, int sel, int reverse, RECT *rc)
  169. {
  170.     if (selection_in_window(wnd, sel))
  171.         WriteTextLine(wnd, rc, sel-wnd->wtop, reverse);
  172. }
  173.  
  174. static void near change_selection(WINDOW wnd, int sel)
  175. {
  176.     if (sel != wnd->selection)    {
  177.         writeselection(wnd, wnd->selection, FALSE, NULL);
  178.         wnd->selection = sel;
  179.         writeselection(wnd, sel, TRUE, NULL);
  180.     }
  181. }
  182.