home *** CD-ROM | disk | FTP | other *** search
/ Media Share 13 / mediashare_13.zip / mediashare_13 / ZIPPED / PROGRAM / APR94_3.ZIP / DF16.ZIP / DIALBOX.C < prev    next >
Text File  |  1993-04-17  |  22KB  |  764 lines

  1. /* ----------------- dialbox.c -------------- */
  2.  
  3. #include "dflat.h"
  4.  
  5. static int inFocusCommand(DBOX *);
  6. static void dbShortcutKeys(DBOX *, int);
  7. static int ControlProc(WINDOW, MESSAGE, PARAM, PARAM);
  8. static void FirstFocus(DBOX *db);
  9. static void NextFocus(DBOX *db);
  10. static void PrevFocus(DBOX *db);
  11. static CTLWINDOW *AssociatedControl(DBOX *, enum commands);
  12.  
  13. static BOOL SysMenuOpen;
  14.  
  15. static DBOX **dbs = NULL;
  16. static int dbct = 0;
  17.  
  18. /* --- clear all heap allocations to control text fields --- */
  19. void ClearDialogBoxes(void)
  20. {
  21.     int i;
  22.     for (i = 0; i < dbct; i++)    {
  23.         CTLWINDOW *ct = (*(dbs+i))->ctl;
  24.         while (ct->class)    {
  25.             if ((ct->class == EDITBOX ||
  26.                     ct->class == COMBOBOX) &&
  27.                     ct->itext != NULL)
  28.                 free(ct->itext);
  29.             ct++;
  30.         }
  31.     }
  32.     if (dbs != NULL)    {
  33.         free(dbs);
  34.         dbs = NULL;
  35.     }
  36.     dbct = 0;
  37. }
  38.  
  39. /* -------- CREATE_WINDOW Message --------- */
  40. static int CreateWindowMsg(WINDOW wnd, PARAM p1, PARAM p2)
  41. {
  42.     DBOX *db = wnd->extension;
  43.     CTLWINDOW *ct = db->ctl;
  44.     WINDOW cwnd;
  45.     int rtn, i;
  46.     /* ---- build a table of processed dialog boxes ---- */
  47.     for (i = 0; i < dbct; i++)
  48.         if (db == dbs[i])
  49.             break;
  50.     if (i == dbct)    {
  51.         dbs = DFrealloc(dbs, sizeof(DBOX *) * (dbct+1));
  52.         *(dbs + dbct++) = db;
  53.     }
  54.     rtn = BaseWndProc(DIALOG, wnd, CREATE_WINDOW, p1, p2);
  55.     ct = db->ctl;
  56.     while (ct->class)    {
  57.         int attrib = 0;
  58.         if (TestAttribute(wnd, NOCLIP))
  59.             attrib |= NOCLIP;
  60.         if (wnd->Modal)
  61.             attrib |= SAVESELF;
  62.         ct->setting = ct->isetting;
  63.         if (ct->class == EDITBOX && ct->dwnd.h > 1)
  64.             attrib |= (MULTILINE | HASBORDER);
  65.         else if ((ct->class == LISTBOX || ct->class == TEXTBOX) &&
  66.                 ct->dwnd.h > 2)
  67.             attrib |= HASBORDER;
  68.         cwnd = CreateWindow(ct->class,
  69.                         ct->dwnd.title,
  70.                         ct->dwnd.x+GetClientLeft(wnd),
  71.                         ct->dwnd.y+GetClientTop(wnd),
  72.                         ct->dwnd.h,
  73.                         ct->dwnd.w,
  74.                         ct,
  75.                         wnd,
  76.                         ControlProc,
  77.                         attrib);
  78.         if ((ct->class == EDITBOX ||
  79.                 ct->class == COMBOBOX) &&
  80.                     ct->itext != NULL)
  81.             SendMessage(cwnd, SETTEXT, (PARAM) ct->itext, 0);
  82.         ct++;
  83.     }
  84.     return rtn;
  85. }
  86.  
  87. /* -------- LEFT_BUTTON Message --------- */
  88. static BOOL LeftButtonMsg(WINDOW wnd, PARAM p1, PARAM p2)
  89. {
  90.     DBOX *db = wnd->extension;
  91.     CTLWINDOW *ct = db->ctl;
  92.     if (WindowSizing || WindowMoving)
  93.         return TRUE;
  94.     if (HitControlBox(wnd, p1-GetLeft(wnd), p2-GetTop(wnd))) {
  95.         PostMessage(wnd, KEYBOARD, ' ', ALTKEY);
  96.         return TRUE;
  97.     }
  98.     while (ct->class)    {
  99.         WINDOW cwnd = ct->wnd;
  100.         if (ct->class == COMBOBOX)    {
  101.             if (p2 == GetTop(cwnd))    {
  102.                 if (p1 == GetRight(cwnd)+1)    {
  103.                     SendMessage(cwnd, LEFT_BUTTON, p1, p2);
  104.                     return TRUE;
  105.                 }
  106.             }
  107.             if (GetClass(inFocus) == LISTBOX)
  108.                 SendMessage(wnd, SETFOCUS, TRUE, 0);
  109.         }
  110.         else if (ct->class == SPINBUTTON)    {
  111.             if (p2 == GetTop(cwnd))    {
  112.                 if (p1 == GetRight(cwnd)+1 ||
  113.                         p1 == GetRight(cwnd)+2)    {
  114.                     SendMessage(cwnd, LEFT_BUTTON, p1, p2);
  115.                     return TRUE;
  116.                 }
  117.             }
  118.         }
  119.         ct++;
  120.     }
  121.     return FALSE;
  122. }
  123.  
  124. /* -------- KEYBOARD Message --------- */
  125. static BOOL KeyboardMsg(WINDOW wnd, PARAM p1, PARAM p2)
  126. {
  127.     DBOX *db = wnd->extension;
  128.     CTLWINDOW *ct;
  129.  
  130.     if (WindowMoving || WindowSizing)
  131.         return FALSE;
  132.     switch ((int)p1)    {
  133.         case F1:
  134.             ct = GetControl(inFocus);
  135.             if (ct != NULL)
  136.                 if (DisplayHelp(wnd, ct->help))
  137.                     return TRUE;
  138.             break;
  139.         case SHIFT_HT:
  140.         case BS:
  141.         case UP:
  142.             PrevFocus(db);
  143.             break;
  144.         case ALT_F6:
  145.         case '\t':
  146.         case FWD:
  147.         case DN:
  148.             NextFocus(db);
  149.             break;
  150.         case ' ':
  151.             if (((int)p2 & ALTKEY) &&
  152.                     TestAttribute(wnd, CONTROLBOX))    {
  153.                 SysMenuOpen = TRUE;
  154.                 BuildSystemMenu(wnd);
  155.                 return TRUE;
  156.             }
  157.             break;
  158.         case CTRL_F4:
  159.         case ESC:
  160.             SendMessage(wnd, COMMAND, ID_CANCEL, 0);
  161.             break;
  162.         default:
  163.             /* ------ search all the shortcut keys ----- */
  164.             dbShortcutKeys(db, (int) p1);
  165.             break;
  166.     }
  167.     return wnd->Modal;
  168. }
  169.  
  170. /* -------- COMMAND Message --------- */
  171. static BOOL CommandMsg(WINDOW wnd, PARAM p1, PARAM p2)
  172. {
  173.     DBOX *db = wnd->extension;
  174.     switch ((int) p1)    {
  175.         case ID_OK:
  176.         case ID_CANCEL:
  177.             if ((int)p2 != 0)
  178.                 return TRUE;
  179.             wnd->ReturnCode = (int) p1;
  180.             if (wnd->Modal)
  181.                 PostMessage(wnd, ENDDIALOG, 0, 0);
  182.             else
  183.                 SendMessage(wnd, CLOSE_WINDOW, TRUE, 0);
  184.             return TRUE;
  185.         case ID_HELP:
  186.             if ((int)p2 != 0)
  187.                 return TRUE;
  188.             return DisplayHelp(wnd, db->HelpName);
  189.         default:
  190.             break;
  191.     }
  192.     return FALSE;
  193. }
  194.  
  195. /* ----- window-processing module, DIALOG window class ----- */
  196. int DialogProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  197. {
  198.     int rtn;
  199.     DBOX *db = wnd->extension;
  200.  
  201.     switch (msg)    {
  202.         case CREATE_WINDOW:
  203.             return CreateWindowMsg(wnd, p1, p2);
  204.         case SHIFT_CHANGED:
  205.             if (wnd->Modal)
  206.                 return TRUE;
  207.             break;
  208.         case LEFT_BUTTON:
  209.             if (LeftButtonMsg(wnd, p1, p2))
  210.                 return TRUE;
  211.             break;
  212.         case KEYBOARD:
  213.             if (KeyboardMsg(wnd, p1, p2))
  214.                 return TRUE;
  215.             break;
  216.         case CLOSE_POPDOWN:
  217.             SysMenuOpen = FALSE;
  218.             break;
  219.         case LB_SELECTION:
  220.         case LB_CHOOSE:
  221.             if (SysMenuOpen)
  222.                 return TRUE;
  223.             SendMessage(wnd, COMMAND, inFocusCommand(db), msg);
  224.             break;
  225.         case COMMAND:
  226.             if (CommandMsg(wnd, p1, p2))
  227.                 return TRUE;
  228.             break;
  229.         case PAINT:
  230.             p2 = TRUE;
  231.             break;
  232.         case MOVE:
  233.         case SIZE:
  234.             rtn = BaseWndProc(DIALOG, wnd, msg, p1, p2);
  235.             if (wnd->dfocus != NULL)
  236.                 SendMessage(wnd->dfocus, SETFOCUS, TRUE, 0);
  237.             return rtn;
  238.         case CLOSE_WINDOW:
  239.             if (!p1)    {
  240.                 SendMessage(wnd, COMMAND, ID_CANCEL, 0);
  241.                 return TRUE;
  242.             }
  243.             break;
  244.         default:
  245.             break;
  246.     }
  247.     return BaseWndProc(DIALOG, wnd, msg, p1, p2);
  248. }
  249.  
  250. /* ------- create and execute a dialog box ---------- */
  251. BOOL DialogBox(WINDOW wnd, DBOX *db, BOOL Modal,
  252.   int (*wndproc)(struct window *, enum messages, PARAM, PARAM))
  253. {
  254.     BOOL rtn;
  255.     int x = db->dwnd.x, y = db->dwnd.y;
  256.     WINDOW DialogWnd;
  257.  
  258.     if (!Modal && wnd != NULL)    {
  259.         x += GetLeft(wnd);
  260.         y += GetTop(wnd);
  261.     }
  262.     DialogWnd = CreateWindow(DIALOG,
  263.                         db->dwnd.title,
  264.                         x, y,
  265.                         db->dwnd.h,
  266.                         db->dwnd.w,
  267.                         db,
  268.                         wnd,
  269.                         wndproc,
  270.                         Modal ? SAVESELF : 0);
  271.     DialogWnd->Modal = Modal;
  272.     FirstFocus(db);
  273.     PostMessage(DialogWnd, INITIATE_DIALOG, 0, 0);
  274.     if (Modal)    {
  275.         SendMessage(DialogWnd, CAPTURE_MOUSE, 0, 0);
  276.         SendMessage(DialogWnd, CAPTURE_KEYBOARD, 0, 0);
  277.         while (dispatch_message())
  278.             ;
  279.         rtn = DialogWnd->ReturnCode == ID_OK;
  280.         SendMessage(DialogWnd, RELEASE_MOUSE, 0, 0);
  281.         SendMessage(DialogWnd, RELEASE_KEYBOARD, 0, 0);
  282.         SendMessage(DialogWnd, CLOSE_WINDOW, TRUE, 0);
  283.         return rtn;
  284.     }
  285.     return FALSE;
  286. }
  287.  
  288. /* ----- return command code of in-focus control window ---- */
  289. static int inFocusCommand(DBOX *db)
  290. {
  291.     CTLWINDOW *ct = db->ctl;
  292.     while (ct->class)    {
  293.         if (ct->wnd == inFocus)
  294.             return ct->command;
  295.         ct++;
  296.     }
  297.     return -1;
  298. }
  299.  
  300. /* -------- find a specified control structure ------- */
  301. CTLWINDOW *FindCommand(DBOX *db, enum commands cmd, int class)
  302. {
  303.     CTLWINDOW *ct = db->ctl;
  304.     while (ct->class)    {
  305.         if (ct->class == class)
  306.             if (cmd == ct->command)
  307.                 return ct;
  308.         ct++;
  309.     }
  310.     return NULL;
  311. }
  312.  
  313. /* ---- return the window handle of a specified command ---- */
  314. WINDOW ControlWindow(DBOX *db, enum commands cmd)
  315. {
  316.     CTLWINDOW *ct = db->ctl;
  317.     while (ct->class)    {
  318.         if (ct->class != TEXT && cmd == ct->command)
  319.             return ct->wnd;
  320.         ct++;
  321.     }
  322.     return NULL;
  323. }
  324.  
  325. /* --- return a pointer to the control structure that matches a window --- */
  326. CTLWINDOW *WindowControl(DBOX *db, WINDOW wnd)
  327. {
  328.     CTLWINDOW *ct = db->ctl;
  329.     while (ct->class)    {
  330.         if (ct->wnd == wnd)
  331.             return ct;
  332.         ct++;
  333.     }
  334.     return NULL;
  335. }
  336.  
  337. /* ---- set a control ON or OFF ----- */
  338. void ControlSetting(DBOX *db, enum commands cmd,
  339.                                 int class, int setting)
  340. {
  341.     CTLWINDOW *ct = FindCommand(db, cmd, class);
  342.     if (ct != NULL)    {
  343.         ct->isetting = setting;
  344.         if (ct->wnd != NULL)
  345.             ct->setting = setting;
  346.     }
  347. }
  348.  
  349. /* ---- return pointer to the text of a control window ---- */
  350. char *GetDlgTextString(DBOX *db,enum commands cmd,CLASS class)
  351. {
  352.     CTLWINDOW *ct = FindCommand(db, cmd, class);
  353.     if (ct != NULL)
  354.         return ct->itext;
  355.     else
  356.         return NULL;
  357. }
  358.  
  359. /* ------- set the text of a control specification ------ */
  360. void SetDlgTextString(DBOX *db, enum commands cmd,
  361.                                     char *text, CLASS class)
  362. {
  363.     CTLWINDOW *ct = FindCommand(db, cmd, class);
  364.     if (ct != NULL)    {
  365.         ct->itext = DFrealloc(ct->itext, strlen(text)+1);
  366.         strcpy(ct->itext, text);
  367.         if (ct->wnd != NULL)    {
  368.             SendMessage(ct->wnd, SETTEXT, (PARAM) text, 0);
  369.             SendMessage(ct->wnd, PAINT, 0, 0);
  370.         }
  371.     }
  372. }
  373.  
  374. /* ------- set the text of a control window ------ */
  375. void PutItemText(WINDOW wnd, enum commands cmd, char *text)
  376. {
  377.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd, EDITBOX);
  378.  
  379.     if (ct == NULL)
  380.         ct = FindCommand(wnd->extension, cmd, TEXTBOX);
  381.     if (ct == NULL)
  382.         ct = FindCommand(wnd->extension, cmd, COMBOBOX);
  383.     if (ct == NULL)
  384.         ct = FindCommand(wnd->extension, cmd, LISTBOX);
  385.     if (ct == NULL)
  386.         ct = FindCommand(wnd->extension, cmd, SPINBUTTON);
  387.     if (ct == NULL)
  388.         ct = FindCommand(wnd->extension, cmd, TEXT);
  389.     if (ct != NULL)        {
  390.         WINDOW cwnd = (WINDOW) (ct->wnd);
  391.         switch (ct->class)    {
  392.             case COMBOBOX:
  393.             case EDITBOX:
  394.                 SendMessage(cwnd, CLEARTEXT, 0, 0);
  395.                 SendMessage(cwnd, ADDTEXT, (PARAM) text, 0);
  396.                 if (!isMultiLine(cwnd))
  397.                     SendMessage(cwnd, PAINT, 0, 0);
  398.                 break;
  399.             case LISTBOX:
  400.             case TEXTBOX:
  401.             case SPINBUTTON:
  402.                 SendMessage(cwnd, ADDTEXT, (PARAM) text, 0);
  403.                 break;
  404.             case TEXT:    {
  405.                 SendMessage(cwnd, CLEARTEXT, 0, 0);
  406.                 SendMessage(cwnd, ADDTEXT, (PARAM) text, 0);
  407.                 SendMessage(cwnd, PAINT, 0, 0);
  408.                 break;
  409.             }
  410.             default:
  411.                 break;
  412.         }
  413.     }
  414. }
  415.  
  416. /* ------- get the text of a control window ------ */
  417. void GetItemText(WINDOW wnd, enum commands cmd,
  418.                                 char *text, int len)
  419. {
  420.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd, EDITBOX);
  421.     unsigned char *cp;
  422.  
  423.     if (ct == NULL)
  424.         ct = FindCommand(wnd->extension, cmd, COMBOBOX);
  425.     if (ct == NULL)
  426.         ct = FindCommand(wnd->extension, cmd, TEXTBOX);
  427.     if (ct == NULL)
  428.         ct = FindCommand(wnd->extension, cmd, TEXT);
  429.     if (ct != NULL)    {
  430.         WINDOW cwnd = (WINDOW) (ct->wnd);
  431.         if (cwnd != NULL)    {
  432.             switch (ct->class)    {
  433.                 case TEXT:
  434.                     if (GetText(cwnd) != NULL)    {
  435.                         cp = strchr(GetText(cwnd), '\n');
  436.                         if (cp != NULL)
  437.                             len = (int) (cp - GetText(cwnd));
  438.                         strncpy(text, GetText(cwnd), len);
  439.                         *(text+len) = '\0';
  440.                     }
  441.                     break;
  442.                 case TEXTBOX:
  443.                     if (GetText(cwnd) != NULL)
  444.                         strncpy(text, GetText(cwnd), len);
  445.                     break;
  446.                 case COMBOBOX:
  447.                 case EDITBOX:
  448.                     SendMessage(cwnd,GETTEXT,(PARAM)text,len);
  449.                     break;
  450.                 default:
  451.                     break;
  452.             }
  453.         }
  454.     }
  455. }
  456.  
  457. /* ------- set the text of a listbox control window ------ */
  458. void GetDlgListText(WINDOW wnd, char *text, enum commands cmd)
  459. {
  460.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd, LISTBOX);
  461.     int sel = SendMessage(ct->wnd, LB_CURRENTSELECTION, 0, 0);
  462.     SendMessage(ct->wnd, LB_GETTEXT, (PARAM) text, sel);
  463. }
  464.  
  465. /* -- find control structure associated with text control -- */
  466. static CTLWINDOW *AssociatedControl(DBOX *db,enum commands Tcmd)
  467. {
  468.     CTLWINDOW *ct = db->ctl;
  469.     while (ct->class)    {
  470.         if (ct->class != TEXT)
  471.             if (ct->command == Tcmd)
  472.                 break;
  473.         ct++;
  474.     }
  475.     return ct;
  476. }
  477.  
  478. /* --- process dialog box shortcut keys --- */
  479. static void dbShortcutKeys(DBOX *db, int ky)
  480. {
  481.     CTLWINDOW *ct;
  482.     int ch = AltConvert(ky);
  483.  
  484.     if (ch != 0)    {
  485.         ct = db->ctl;
  486.         while (ct->class)    {
  487.             char *cp = ct->itext;
  488.             while (cp && *cp)    {
  489.                 if (*cp == SHORTCUTCHAR &&
  490.                             tolower(*(cp+1)) == ch)    {
  491.                     if (ct->class == TEXT)
  492.                         ct = AssociatedControl(db, ct->command);
  493.                     if (ct->class == RADIOBUTTON)
  494.                         SetRadioButton(db, ct);
  495.                     else if (ct->class == CHECKBOX)    {
  496.                         ct->setting ^= ON;
  497.                         SendMessage(ct->wnd, PAINT, 0, 0);
  498.                     }
  499.                     else if (ct->class)    {
  500.                         SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  501.                         if (ct->class == BUTTON)
  502.                            SendMessage(ct->wnd,KEYBOARD,'\r',0);
  503.                     }
  504.                     return;
  505.                 }
  506.                 cp++;
  507.             }
  508.             ct++;
  509.         }
  510.     }
  511. }
  512.  
  513. /* --- dynamically add or remove scroll bars
  514.                             from a control window ---- */
  515. void SetScrollBars(WINDOW wnd)
  516. {
  517.     int oldattr = GetAttribute(wnd);
  518.     if (wnd->wlines > ClientHeight(wnd))
  519.         AddAttribute(wnd, VSCROLLBAR);
  520.     else 
  521.         ClearAttribute(wnd, VSCROLLBAR);
  522.     if (wnd->textwidth > ClientWidth(wnd))
  523.         AddAttribute(wnd, HSCROLLBAR);
  524.     else 
  525.         ClearAttribute(wnd, HSCROLLBAR);
  526.     if (GetAttribute(wnd) != oldattr)
  527.         SendMessage(wnd, BORDER, 0, 0);
  528. }
  529.  
  530. /* ------- CREATE_WINDOW Message (Control) ----- */
  531. static void CtlCreateWindowMsg(WINDOW wnd)
  532. {
  533.     CTLWINDOW *ct;
  534.     ct = wnd->ct = wnd->extension;
  535.     wnd->extension = NULL;
  536.     if (ct != NULL)
  537.         ct->wnd = wnd;
  538. }
  539.  
  540. /* ------- KEYBOARD Message (Control) ----- */
  541. static BOOL CtlKeyboardMsg(WINDOW wnd, PARAM p1, PARAM p2)
  542. {
  543.     CTLWINDOW *ct = GetControl(wnd);
  544.     switch ((int) p1)    {
  545.         case F1:
  546.             if (WindowMoving || WindowSizing)
  547.                 break;
  548.             if (!DisplayHelp(wnd, ct->help))
  549.                 SendMessage(GetParent(wnd),COMMAND,ID_HELP,0);
  550.             return TRUE;
  551.         case ' ':
  552.             if (!((int)p2 & ALTKEY))
  553.                 break;
  554.         case ALT_F6:
  555.         case CTRL_F4:
  556.         case ALT_F4:
  557.             PostMessage(GetParent(wnd), KEYBOARD, p1, p2);
  558.             return TRUE;
  559.         default:
  560.             break;
  561.     }
  562.     if (GetClass(wnd) == EDITBOX)
  563.         if (isMultiLine(wnd))
  564.             return FALSE;
  565.     switch ((int) p1)    {
  566.         case UP:
  567.             if (!isDerivedFrom(wnd, LISTBOX))    {
  568.                 p1 = CTRL_FIVE;
  569.                 p2 = LEFTSHIFT;
  570.             }
  571.             break;
  572.         case BS:
  573.             if (!isDerivedFrom(wnd, EDITBOX))    {
  574.                 p1 = CTRL_FIVE;
  575.                 p2 = LEFTSHIFT;
  576.             }
  577.             break;
  578.         case DN:
  579.             if (!isDerivedFrom(wnd, LISTBOX) &&
  580.                     !isDerivedFrom(wnd, COMBOBOX))
  581.                 p1 = '\t';
  582.             break;
  583.         case FWD:
  584.             if (!isDerivedFrom(wnd, EDITBOX))
  585.                 p1 = '\t';
  586.             break;
  587.         case '\r':
  588.             if (isDerivedFrom(wnd, EDITBOX))
  589.                 if (isMultiLine(wnd))
  590.                     break;
  591.             if (isDerivedFrom(wnd, BUTTON))
  592.                 break;
  593.             SendMessage(GetParent(wnd), COMMAND, ID_OK, 0);
  594.             return TRUE;
  595.         default:
  596.             break;
  597.     }
  598.     return FALSE;
  599. }
  600.  
  601. /* ------- CLOSE_WINDOW Message (Control) ----- */
  602. static void CtlCloseWindowMsg(WINDOW wnd)
  603. {
  604.     CTLWINDOW *ct = GetControl(wnd);
  605.     if (ct != NULL)    {
  606.         ct->wnd = NULL;
  607.         if (GetParent(wnd)->ReturnCode == ID_OK)    {
  608.             if (ct->class == EDITBOX || ct->class == COMBOBOX)    {
  609.                 if (wnd->TextChanged)    {
  610.                     ct->itext=DFrealloc(ct->itext,strlen(wnd->text)+1);
  611.                     strcpy(ct->itext, wnd->text);
  612.                     if (!isMultiLine(wnd))    {
  613.                         char *cp = ct->itext+strlen(ct->itext)-1;
  614.                         if (*cp == '\n')
  615.                             *cp = '\0';
  616.                     }
  617.                 }
  618.             }
  619.             else if (ct->class == RADIOBUTTON || ct->class == CHECKBOX)
  620.                 ct->isetting = ct->setting;
  621.         }
  622.     }
  623. }
  624.  
  625. static void FixColors(WINDOW wnd)
  626. {
  627.     CTLWINDOW *ct = wnd->ct;
  628.     if (ct->class != BUTTON)    {
  629.         if (ct->class != SPINBUTTON && ct->class != COMBOBOX)    {
  630.             wnd->WindowColors[FRAME_COLOR][FG] = 
  631.                 GetParent(wnd)->WindowColors[FRAME_COLOR][FG];
  632.             wnd->WindowColors[FRAME_COLOR][BG] = 
  633.                 GetParent(wnd)->WindowColors[FRAME_COLOR][BG];
  634.             if (ct->class != EDITBOX && ct->class != LISTBOX)    {
  635.                 wnd->WindowColors[STD_COLOR][FG] = 
  636.                     GetParent(wnd)->WindowColors[STD_COLOR][FG];
  637.                 wnd->WindowColors[STD_COLOR][BG] = 
  638.                     GetParent(wnd)->WindowColors[STD_COLOR][BG];
  639.             }
  640.         }
  641.     }
  642. }
  643.  
  644. /* -- generic window processor used by dialog box controls -- */
  645. static int ControlProc(WINDOW wnd,MESSAGE msg,PARAM p1,PARAM p2)
  646. {
  647.     DBOX *db;
  648.  
  649.     if (wnd == NULL)
  650.         return FALSE;
  651.     db = GetParent(wnd) ? GetParent(wnd)->extension : NULL;
  652.  
  653.     switch (msg)    {
  654.         case CREATE_WINDOW:
  655.             CtlCreateWindowMsg(wnd);
  656.             break;
  657.         case KEYBOARD:
  658.             if (CtlKeyboardMsg(wnd, p1, p2))
  659.                 return TRUE;
  660.             break;
  661.         case PAINT:
  662.             FixColors(wnd);
  663.             if (GetClass(wnd) == EDITBOX ||
  664.                     GetClass(wnd) == LISTBOX ||
  665.                         GetClass(wnd) == TEXTBOX)
  666.                 SetScrollBars(wnd);
  667.             break;
  668.         case BORDER:
  669.             FixColors(wnd);
  670.             if (GetClass(wnd) == EDITBOX)    {
  671.                 WINDOW oldFocus = inFocus;
  672.                 inFocus = NULL;
  673.                 DefaultWndProc(wnd, msg, p1, p2);
  674.                 inFocus = oldFocus;
  675.                 return TRUE;
  676.             }
  677.             break;
  678.         case SETFOCUS:    {
  679.             WINDOW pwnd = GetParent(wnd);
  680.             if (p1)    {
  681.                 DefaultWndProc(wnd, msg, p1, p2);
  682.                 if (pwnd != NULL)    {
  683.                     pwnd->dfocus = wnd;
  684.                     SendMessage(pwnd, COMMAND,
  685.                         inFocusCommand(db), ENTERFOCUS);
  686.                 }
  687.                 return TRUE;
  688.             }
  689.             else
  690.                 SendMessage(pwnd, COMMAND,
  691.                     inFocusCommand(db), LEAVEFOCUS);
  692.             break;
  693.         }
  694.         case CLOSE_WINDOW:
  695.             CtlCloseWindowMsg(wnd);
  696.             break;
  697.         default:
  698.             break;
  699.     }
  700.     return DefaultWndProc(wnd, msg, p1, p2);
  701. }
  702.  
  703. /* ---- change the focus to the first control --- */
  704. static void FirstFocus(DBOX *db)
  705. {
  706.     CTLWINDOW *ct = db->ctl;
  707.     if (ct != NULL)    {
  708.         while (ct->class == TEXT || ct->class == BOX)    {
  709.             ct++;
  710.             if (ct->class == 0)
  711.                 return;
  712.         }
  713.         SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  714.     }
  715. }
  716.  
  717. /* ---- change the focus to the next control --- */
  718. static void NextFocus(DBOX *db)
  719. {
  720.     CTLWINDOW *ct = WindowControl(db, inFocus);
  721.     int looped = 0;
  722.     if (ct != NULL)    {
  723.         do    {
  724.             ct++;
  725.             if (ct->class == 0)    {
  726.                 if (looped)
  727.                     return;
  728.                 looped++;
  729.                 ct = db->ctl;
  730.             }
  731.         } while (ct->class == TEXT || ct->class == BOX);
  732.         SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  733.     }
  734. }
  735.  
  736. /* ---- change the focus to the previous control --- */
  737. static void PrevFocus(DBOX *db)
  738. {
  739.     CTLWINDOW *ct = WindowControl(db, inFocus);
  740.     int looped = 0;
  741.     if (ct != NULL)    {
  742.         do    {
  743.             if (ct == db->ctl)    {
  744.                 if (looped)
  745.                     return;
  746.                 looped++;
  747.                 while (ct->class)
  748.                     ct++;
  749.             }
  750.             --ct;
  751.         } while (ct->class == TEXT || ct->class == BOX);
  752.         SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  753.     }
  754. }
  755.  
  756. void SetFocusCursor(WINDOW wnd)
  757. {
  758.     if (wnd == inFocus)    {
  759.         SendMessage(NULL, SHOW_CURSOR, 0, 0);
  760.         SendMessage(wnd, KEYBOARD_CURSOR, 1, 0);
  761.     }
  762. }
  763. 
  764.