home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 24 / CD_ASCQ_24_0995.iso / vrac / dflt20.zip / DIALBOX.C < prev    next >
Text File  |  1995-02-13  |  24KB  |  809 lines

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