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