home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 14 / CD_ASCQ_14_0694.iso / maj / 661 / dialbox.c < prev    next >
Text File  |  1994-02-20  |  23KB  |  771 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.     SendMessage(DialogWnd, SETFOCUS, TRUE, 0);
  272.     SendMessage(DialogWnd, SHOW_WINDOW, 0, 0);
  273.     DialogWnd->Modal = Modal;
  274.     FirstFocus(db);
  275.     PostMessage(DialogWnd, INITIATE_DIALOG, 0, 0);
  276.     if (Modal)    {
  277.         SendMessage(DialogWnd, CAPTURE_MOUSE, 0, 0);
  278.         SendMessage(DialogWnd, CAPTURE_KEYBOARD, 0, 0);
  279.         while (dispatch_message())
  280.             ;
  281.         rtn = DialogWnd->ReturnCode == ID_OK;
  282.         SendMessage(DialogWnd, RELEASE_MOUSE, 0, 0);
  283.         SendMessage(DialogWnd, RELEASE_KEYBOARD, 0, 0);
  284.         SendMessage(DialogWnd, CLOSE_WINDOW, TRUE, 0);
  285.         return rtn;
  286.     }
  287.     return FALSE;
  288. }
  289.  
  290. /* ----- return command code of in-focus control window ---- */
  291. static int inFocusCommand(DBOX *db)
  292. {
  293.     CTLWINDOW *ct = db->ctl;
  294.     while (ct->class)    {
  295.         if (ct->wnd == inFocus)
  296.             return ct->command;
  297.         ct++;
  298.     }
  299.     return -1;
  300. }
  301.  
  302. /* -------- find a specified control structure ------- */
  303. CTLWINDOW *FindCommand(DBOX *db, enum commands cmd, int class)
  304. {
  305.     CTLWINDOW *ct = db->ctl;
  306.     while (ct->class)    {
  307.         if (ct->class == class)
  308.             if (cmd == ct->command)
  309.                 return ct;
  310.         ct++;
  311.     }
  312.     return NULL;
  313. }
  314.  
  315. /* ---- return the window handle of a specified command ---- */
  316. WINDOW ControlWindow(DBOX *db, enum commands cmd)
  317. {
  318.     CTLWINDOW *ct = db->ctl;
  319.     while (ct->class)    {
  320.         if (ct->class != TEXT && cmd == ct->command)
  321.             return ct->wnd;
  322.         ct++;
  323.     }
  324.     return NULL;
  325. }
  326.  
  327. /* --- return a pointer to the control structure that matches a window --- */
  328. CTLWINDOW *WindowControl(DBOX *db, WINDOW wnd)
  329. {
  330.     CTLWINDOW *ct = db->ctl;
  331.     while (ct->class)    {
  332.         if (ct->wnd == wnd)
  333.             return ct;
  334.         ct++;
  335.     }
  336.     return NULL;
  337. }
  338.  
  339. /* ---- set a control ON or OFF ----- */
  340. void ControlSetting(DBOX *db, enum commands cmd,
  341.                                 int class, int setting)
  342. {
  343.     CTLWINDOW *ct = FindCommand(db, cmd, class);
  344.     if (ct != NULL)    {
  345.         ct->isetting = setting;
  346.         if (ct->wnd != NULL)
  347.             ct->setting = setting;
  348.     }
  349. }
  350.  
  351. /* ---- return pointer to the text of a control window ---- */
  352. char *GetDlgTextString(DBOX *db,enum commands cmd,CLASS class)
  353. {
  354.     CTLWINDOW *ct = FindCommand(db, cmd, class);
  355.     if (ct != NULL)
  356.         return ct->itext;
  357.     else
  358.         return NULL;
  359. }
  360.  
  361. /* ------- set the text of a control specification ------ */
  362. void SetDlgTextString(DBOX *db, enum commands cmd,
  363.                                     char *text, CLASS class)
  364. {
  365.     CTLWINDOW *ct = FindCommand(db, cmd, class);
  366.     if (ct != NULL)    {
  367.         ct->itext = DFrealloc(ct->itext, strlen(text)+1);
  368.         strcpy(ct->itext, text);
  369.         if (ct->wnd != NULL)    {
  370.             SendMessage(ct->wnd, SETTEXT, (PARAM) text, 0);
  371.             SendMessage(ct->wnd, PAINT, 0, 0);
  372.         }
  373.     }
  374. }
  375.  
  376. /* ------- set the text of a control window ------ */
  377. void PutItemText(WINDOW wnd, enum commands cmd, char *text)
  378. {
  379.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd, EDITBOX);
  380.  
  381.     if (ct == NULL)
  382.         ct = FindCommand(wnd->extension, cmd, TEXTBOX);
  383.     if (ct == NULL)
  384.         ct = FindCommand(wnd->extension, cmd, COMBOBOX);
  385.     if (ct == NULL)
  386.         ct = FindCommand(wnd->extension, cmd, LISTBOX);
  387.     if (ct == NULL)
  388.         ct = FindCommand(wnd->extension, cmd, SPINBUTTON);
  389.     if (ct == NULL)
  390.         ct = FindCommand(wnd->extension, cmd, TEXT);
  391.     if (ct != NULL)        {
  392.         WINDOW cwnd = (WINDOW) (ct->wnd);
  393.         switch (ct->class)    {
  394.             case COMBOBOX:
  395.             case EDITBOX:
  396.                 SendMessage(cwnd, CLEARTEXT, 0, 0);
  397.                 SendMessage(cwnd, ADDTEXT, (PARAM) text, 0);
  398.                 if (!isMultiLine(cwnd))
  399.                     SendMessage(cwnd, PAINT, 0, 0);
  400.                 break;
  401.             case LISTBOX:
  402.             case TEXTBOX:
  403.             case SPINBUTTON:
  404.                 SendMessage(cwnd, ADDTEXT, (PARAM) text, 0);
  405.                 break;
  406.             case TEXT:    {
  407.                 SendMessage(cwnd, CLEARTEXT, 0, 0);
  408.                 SendMessage(cwnd, ADDTEXT, (PARAM) text, 0);
  409.                 SendMessage(cwnd, PAINT, 0, 0);
  410.                 break;
  411.             }
  412.             default:
  413.                 break;
  414.         }
  415.     }
  416. }
  417.  
  418. /* ------- get the text of a control window ------ */
  419. void GetItemText(WINDOW wnd, enum commands cmd,
  420.                                 char *text, int len)
  421. {
  422.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd, EDITBOX);
  423.     unsigned char *cp;
  424.  
  425.     if (ct == NULL)
  426.         ct = FindCommand(wnd->extension, cmd, COMBOBOX);
  427.     if (ct == NULL)
  428.         ct = FindCommand(wnd->extension, cmd, TEXTBOX);
  429.     if (ct == NULL)
  430.         ct = FindCommand(wnd->extension, cmd, TEXT);
  431.     if (ct != NULL)    {
  432.         WINDOW cwnd = (WINDOW) (ct->wnd);
  433.         if (cwnd != NULL)    {
  434.             switch (ct->class)    {
  435.                 case TEXT:
  436.                     if (GetText(cwnd) != NULL)    {
  437.                         cp = strchr(GetText(cwnd), '\n');
  438.                         if (cp != NULL)
  439.                             len = (int) (cp - GetText(cwnd));
  440.                         strncpy(text, GetText(cwnd), len);
  441.                         *(text+len) = '\0';
  442.                     }
  443.                     break;
  444.                 case TEXTBOX:
  445.                     if (GetText(cwnd) != NULL)
  446.                         strncpy(text, GetText(cwnd), len);
  447.                     break;
  448.                 case COMBOBOX:
  449.                 case EDITBOX:
  450.                     SendMessage(cwnd,GETTEXT,(PARAM)text,len);
  451.                     break;
  452.                 default:
  453.                     break;
  454.             }
  455.         }
  456.     }
  457. }
  458.  
  459. /* ------- set the text of a listbox control window ------ */
  460. void GetDlgListText(WINDOW wnd, char *text, enum commands cmd)
  461. {
  462.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd, LISTBOX);
  463.     int sel = SendMessage(ct->wnd, LB_CURRENTSELECTION, 0, 0);
  464.     SendMessage(ct->wnd, LB_GETTEXT, (PARAM) text, sel);
  465. }
  466.  
  467. /* -- find control structure associated with text control -- */
  468. static CTLWINDOW *AssociatedControl(DBOX *db,enum commands Tcmd)
  469. {
  470.     CTLWINDOW *ct = db->ctl;
  471.     while (ct->class)    {
  472.         if (ct->class != TEXT)
  473.             if (ct->command == Tcmd)
  474.                 break;
  475.         ct++;
  476.     }
  477.     return ct;
  478. }
  479.  
  480. /* --- process dialog box shortcut keys --- */
  481. static void dbShortcutKeys(DBOX *db, int ky)
  482. {
  483.     CTLWINDOW *ct;
  484.     int ch = AltConvert(ky);
  485.  
  486.     if (ch != 0)    {
  487.         ct = db->ctl;
  488.         while (ct->class)    {
  489.             char *cp = ct->itext;
  490.             while (cp && *cp)    {
  491.                 if (*cp == SHORTCUTCHAR &&
  492.                             tolower(*(cp+1)) == ch)    {
  493.                     if (ct->class == TEXT)
  494.                         ct = AssociatedControl(db, ct->command);
  495.                     if (ct->class == RADIOBUTTON)
  496.                         SetRadioButton(db, ct);
  497.                     else if (ct->class == CHECKBOX)    {
  498.                         ct->setting ^= ON;
  499.                         SendMessage(ct->wnd, PAINT, 0, 0);
  500.                     }
  501.                     else if (ct->class)    {
  502.                         SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  503.                         if (ct->class == BUTTON)
  504.                            SendMessage(ct->wnd,KEYBOARD,'\r',0);
  505.                     }
  506.                     return;
  507.                 }
  508.                 cp++;
  509.             }
  510.             ct++;
  511.         }
  512.     }
  513. }
  514.  
  515. /* --- dynamically add or remove scroll bars
  516.                             from a control window ---- */
  517. void SetScrollBars(WINDOW wnd)
  518. {
  519.     int oldattr = GetAttribute(wnd);
  520.     if (wnd->wlines > ClientHeight(wnd))
  521.         AddAttribute(wnd, VSCROLLBAR);
  522.     else 
  523.         ClearAttribute(wnd, VSCROLLBAR);
  524.     if (wnd->textwidth > ClientWidth(wnd))
  525.         AddAttribute(wnd, HSCROLLBAR);
  526.     else 
  527.         ClearAttribute(wnd, HSCROLLBAR);
  528.     if (GetAttribute(wnd) != oldattr)
  529.         SendMessage(wnd, BORDER, 0, 0);
  530. }
  531.  
  532. /* ------- CREATE_WINDOW Message (Control) ----- */
  533. static void CtlCreateWindowMsg(WINDOW wnd)
  534. {
  535.     CTLWINDOW *ct;
  536.     ct = wnd->ct = wnd->extension;
  537.     wnd->extension = NULL;
  538.     if (ct != NULL)
  539.         ct->wnd = wnd;
  540. }
  541.  
  542. /* ------- KEYBOARD Message (Control) ----- */
  543. static BOOL CtlKeyboardMsg(WINDOW wnd, PARAM p1, PARAM p2)
  544. {
  545.     CTLWINDOW *ct = GetControl(wnd);
  546.     switch ((int) p1)    {
  547.         case F1:
  548.             if (WindowMoving || WindowSizing)
  549.                 break;
  550.             if (!DisplayHelp(wnd, ct->help))
  551.                 SendMessage(GetParent(wnd),COMMAND,ID_HELP,0);
  552.             return TRUE;
  553.         case ' ':
  554.             if (!((int)p2 & ALTKEY))
  555.                 break;
  556.         case ALT_F6:
  557.         case CTRL_F4:
  558.         case ALT_F4:
  559.             PostMessage(GetParent(wnd), KEYBOARD, p1, p2);
  560.             return TRUE;
  561.         default:
  562.             break;
  563.     }
  564.     if (GetClass(wnd) == EDITBOX)
  565.         if (isMultiLine(wnd))
  566.             return FALSE;
  567.     if (GetClass(wnd) == TEXTBOX)
  568.         if (WindowHeight(wnd) > 1)
  569.             return FALSE;
  570.     switch ((int) p1)    {
  571.         case UP:
  572.             if (!isDerivedFrom(wnd, LISTBOX))    {
  573.                 p1 = CTRL_FIVE;
  574.                 p2 = LEFTSHIFT;
  575.             }
  576.             break;
  577.         case BS:
  578.             if (!isDerivedFrom(wnd, EDITBOX))    {
  579.                 p1 = CTRL_FIVE;
  580.                 p2 = LEFTSHIFT;
  581.             }
  582.             break;
  583.         case DN:
  584.             if (!isDerivedFrom(wnd, LISTBOX) &&
  585.                     !isDerivedFrom(wnd, COMBOBOX))
  586.                 p1 = '\t';
  587.             break;
  588.         case FWD:
  589.             if (!isDerivedFrom(wnd, EDITBOX))
  590.                 p1 = '\t';
  591.             break;
  592.         case '\r':
  593.             if (isDerivedFrom(wnd, EDITBOX))
  594.                 if (isMultiLine(wnd))
  595.                     break;
  596.             if (isDerivedFrom(wnd, BUTTON))
  597.                 break;
  598.             if (isDerivedFrom(wnd, LISTBOX))
  599.                 break;
  600.             SendMessage(GetParent(wnd), COMMAND, ID_OK, 0);
  601.             return TRUE;
  602.         default:
  603.             break;
  604.     }
  605.     return FALSE;
  606. }
  607.  
  608. /* ------- CLOSE_WINDOW Message (Control) ----- */
  609. static void CtlCloseWindowMsg(WINDOW wnd)
  610. {
  611.     CTLWINDOW *ct = GetControl(wnd);
  612.     if (ct != NULL)    {
  613.         ct->wnd = NULL;
  614.         if (GetParent(wnd)->ReturnCode == ID_OK)    {
  615.             if (ct->class == EDITBOX || ct->class == COMBOBOX)    {
  616.                 if (wnd->TextChanged)    {
  617.                     ct->itext=DFrealloc(ct->itext,strlen(wnd->text)+1);
  618.                     strcpy(ct->itext, wnd->text);
  619.                     if (!isMultiLine(wnd))    {
  620.                         char *cp = ct->itext+strlen(ct->itext)-1;
  621.                         if (*cp == '\n')
  622.                             *cp = '\0';
  623.                     }
  624.                 }
  625.             }
  626.             else if (ct->class == RADIOBUTTON || ct->class == CHECKBOX)
  627.                 ct->isetting = ct->setting;
  628.         }
  629.     }
  630. }
  631.  
  632. static void FixColors(WINDOW wnd)
  633. {
  634.     CTLWINDOW *ct = wnd->ct;
  635.     if (ct->class != BUTTON)    {
  636.         if (ct->class != SPINBUTTON && ct->class != COMBOBOX)    {
  637.             if (ct->class != EDITBOX && ct->class != LISTBOX)    {
  638.                 wnd->WindowColors[FRAME_COLOR][FG] = 
  639.                     GetParent(wnd)->WindowColors[FRAME_COLOR][FG];
  640.                 wnd->WindowColors[FRAME_COLOR][BG] = 
  641.                     GetParent(wnd)->WindowColors[FRAME_COLOR][BG];
  642.                 wnd->WindowColors[STD_COLOR][FG] = 
  643.                     GetParent(wnd)->WindowColors[STD_COLOR][FG];
  644.                 wnd->WindowColors[STD_COLOR][BG] = 
  645.                     GetParent(wnd)->WindowColors[STD_COLOR][BG];
  646.             }
  647.         }
  648.     }
  649. }
  650.  
  651. /* -- generic window processor used by dialog box controls -- */
  652. static int ControlProc(WINDOW wnd,MESSAGE msg,PARAM p1,PARAM p2)
  653. {
  654.     DBOX *db;
  655.  
  656.     if (wnd == NULL)
  657.         return FALSE;
  658.     db = GetParent(wnd) ? GetParent(wnd)->extension : NULL;
  659.  
  660.     switch (msg)    {
  661.         case CREATE_WINDOW:
  662.             CtlCreateWindowMsg(wnd);
  663.             break;
  664.         case KEYBOARD:
  665.             if (CtlKeyboardMsg(wnd, p1, p2))
  666.                 return TRUE;
  667.             break;
  668.         case PAINT:
  669.             FixColors(wnd);
  670.             if (GetClass(wnd) == EDITBOX ||
  671.                     GetClass(wnd) == LISTBOX ||
  672.                         GetClass(wnd) == TEXTBOX)
  673.                 SetScrollBars(wnd);
  674.             break;
  675.         case BORDER:
  676.             FixColors(wnd);
  677.             if (GetClass(wnd) == EDITBOX)    {
  678.                 WINDOW oldFocus = inFocus;
  679.                 inFocus = NULL;
  680.                 DefaultWndProc(wnd, msg, p1, p2);
  681.                 inFocus = oldFocus;
  682.                 return TRUE;
  683.             }
  684.             break;
  685.         case SETFOCUS:    {
  686.             WINDOW pwnd = GetParent(wnd);
  687.             if (p1)    {
  688.                 DefaultWndProc(wnd, msg, p1, p2);
  689.                 if (pwnd != NULL)    {
  690.                     pwnd->dfocus = wnd;
  691.                     SendMessage(pwnd, COMMAND,
  692.                         inFocusCommand(db), ENTERFOCUS);
  693.                 }
  694.                 return TRUE;
  695.             }
  696.             else
  697.                 SendMessage(pwnd, COMMAND,
  698.                     inFocusCommand(db), LEAVEFOCUS);
  699.             break;
  700.         }
  701.         case CLOSE_WINDOW:
  702.             CtlCloseWindowMsg(wnd);
  703.             break;
  704.         default:
  705.             break;
  706.     }
  707.     return DefaultWndProc(wnd, msg, p1, p2);
  708. }
  709.  
  710. /* ---- change the focus to the first control --- */
  711. static void FirstFocus(DBOX *db)
  712. {
  713.     CTLWINDOW *ct = db->ctl;
  714.     if (ct != NULL)    {
  715.         while (ct->class == TEXT || ct->class == BOX)    {
  716.             ct++;
  717.             if (ct->class == 0)
  718.                 return;
  719.         }
  720.         SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  721.     }
  722. }
  723.  
  724. /* ---- change the focus to the next control --- */
  725. static void NextFocus(DBOX *db)
  726. {
  727.     CTLWINDOW *ct = WindowControl(db, inFocus);
  728.     int looped = 0;
  729.     if (ct != NULL)    {
  730.         do    {
  731.             ct++;
  732.             if (ct->class == 0)    {
  733.                 if (looped)
  734.                     return;
  735.                 looped++;
  736.                 ct = db->ctl;
  737.             }
  738.         } while (ct->class == TEXT || ct->class == BOX);
  739.         SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  740.     }
  741. }
  742.  
  743. /* ---- change the focus to the previous control --- */
  744. static void PrevFocus(DBOX *db)
  745. {
  746.     CTLWINDOW *ct = WindowControl(db, inFocus);
  747.     int looped = 0;
  748.     if (ct != NULL)    {
  749.         do    {
  750.             if (ct == db->ctl)    {
  751.                 if (looped)
  752.                     return;
  753.                 looped++;
  754.                 while (ct->class)
  755.                     ct++;
  756.             }
  757.             --ct;
  758.         } while (ct->class == TEXT || ct->class == BOX);
  759.         SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  760.     }
  761. }
  762.  
  763. void SetFocusCursor(WINDOW wnd)
  764. {
  765.     if (wnd == inFocus)    {
  766.         SendMessage(NULL, SHOW_CURSOR, 0, 0);
  767.         SendMessage(wnd, KEYBOARD_CURSOR, 1, 0);
  768.     }
  769. }
  770. 
  771.