home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / window / dflat / dialbox.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-01  |  20.8 KB  |  710 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(WINDOW wnd);
  9. static void NextFocus(void);
  10. static void PrevFocus(void);
  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 = db->ctl;
  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();
  143.             break;
  144.         case ALT_F6:
  145.         case '\t':
  146.         case FWD:
  147.         case DN:
  148.             NextFocus();
  149.             break;
  150.         case ' ':
  151.             if (((int)p2 & ALTKEY) &&
  152.                     TestAttribute(wnd, CONTROLBOX))    {
  153.                 SysMenuOpen = TRUE;
  154.                 BuildSystemMenu(wnd);
  155.             }
  156.             break;
  157.         case CTRL_F4:
  158.         case ESC:
  159.             SendMessage(wnd, COMMAND, ID_CANCEL, 0);
  160.             break;
  161.         default:
  162.             /* ------ search all the shortcut keys ----- */
  163.             dbShortcutKeys(db, (int) p1);
  164.             break;
  165.     }
  166.     return wnd->Modal;
  167. }
  168.  
  169. /* -------- COMMAND Message --------- */
  170. static BOOL CommandMsg(WINDOW wnd, PARAM p1, PARAM p2)
  171. {
  172.     DBOX *db = wnd->extension;
  173.     switch ((int) p1)    {
  174.         case ID_OK:
  175.         case ID_CANCEL:
  176.             if ((int)p2 != 0)
  177.                 return TRUE;
  178.             wnd->ReturnCode = (int) p1;
  179.             if (wnd->Modal)
  180.                 PostMessage(wnd, ENDDIALOG, 0, 0);
  181.             else
  182.                 SendMessage(wnd, CLOSE_WINDOW, TRUE, 0);
  183.             return TRUE;
  184.         case ID_HELP:
  185.             if ((int)p2 != 0)
  186.                 return TRUE;
  187.             return DisplayHelp(wnd, db->HelpName);
  188.         default:
  189.             break;
  190.     }
  191.     return FALSE;
  192. }
  193.  
  194. /* ----- window-processing module, DIALOG window class ----- */
  195. int DialogProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  196. {
  197.     DBOX *db = wnd->extension;
  198.  
  199.     switch (msg)    {
  200.         case CREATE_WINDOW:
  201.             return CreateWindowMsg(wnd, p1, p2);
  202.         case SHIFT_CHANGED:
  203.             if (wnd->Modal)
  204.                 return TRUE;
  205.             break;
  206.         case LEFT_BUTTON:
  207.             if (LeftButtonMsg(wnd, p1, p2))
  208.                 return TRUE;
  209.             break;
  210.         case KEYBOARD:
  211.             if (KeyboardMsg(wnd, p1, p2))
  212.                 return TRUE;
  213.             break;
  214.         case CLOSE_POPDOWN:
  215.             SysMenuOpen = FALSE;
  216.             break;
  217.         case LB_SELECTION:
  218.         case LB_CHOOSE:
  219.             if (SysMenuOpen)
  220.                 return TRUE;
  221.             SendMessage(wnd, COMMAND, inFocusCommand(db), msg);
  222.             break;
  223.         case COMMAND:
  224.             if (CommandMsg(wnd, p1, p2))
  225.                 return TRUE;
  226.             break;
  227.         case PAINT:
  228.             p2 = TRUE;
  229.             break;
  230.         case CLOSE_WINDOW:
  231.             if (!p1)    {
  232.                 SendMessage(wnd, COMMAND, ID_CANCEL, 0);
  233.                 return TRUE;
  234.             }
  235.             break;
  236.         default:
  237.             break;
  238.     }
  239.     return BaseWndProc(DIALOG, wnd, msg, p1, p2);
  240. }
  241.  
  242. /* ------- create and execute a dialog box ---------- */
  243. BOOL DialogBox(WINDOW wnd, DBOX *db, BOOL Modal,
  244.   int (*wndproc)(struct window *, enum messages, PARAM, PARAM))
  245. {
  246.     BOOL rtn;
  247.     int x = db->dwnd.x, y = db->dwnd.y;
  248.     WINDOW DialogWnd;
  249.  
  250.     if (!Modal && wnd != NULL)    {
  251.         x += GetLeft(wnd);
  252.         y += GetTop(wnd);
  253.     }
  254.     DialogWnd = CreateWindow(DIALOG,
  255.                         db->dwnd.title,
  256.                         x, y,
  257.                         db->dwnd.h,
  258.                         db->dwnd.w,
  259.                         db,
  260.                         wnd,
  261.                         wndproc,
  262.                         Modal ? SAVESELF : 0);
  263.     DialogWnd->Modal = Modal;
  264.     FirstFocus(DialogWnd);
  265.     PostMessage(DialogWnd, INITIATE_DIALOG, 0, 0);
  266.     if (Modal)    {
  267.         SendMessage(DialogWnd, CAPTURE_MOUSE, 0, 0);
  268.         SendMessage(DialogWnd, CAPTURE_KEYBOARD, 0, 0);
  269.         while (dispatch_message())
  270.             ;
  271.         rtn = DialogWnd->ReturnCode == ID_OK;
  272.         SendMessage(DialogWnd, RELEASE_MOUSE, 0, 0);
  273.         SendMessage(DialogWnd, RELEASE_KEYBOARD, 0, 0);
  274.         SendMessage(DialogWnd, CLOSE_WINDOW, TRUE, 0);
  275.         return rtn;
  276.     }
  277.     return FALSE;
  278. }
  279.  
  280. /* ----- return command code of in-focus control window ---- */
  281. static int inFocusCommand(DBOX *db)
  282. {
  283.     CTLWINDOW *ct = db->ctl;
  284.     while (ct->class)    {
  285.         if (ct->wnd == inFocus)
  286.             return ct->command;
  287.         ct++;
  288.     }
  289.     return -1;
  290. }
  291.  
  292. /* -------- find a specified control structure ------- */
  293. CTLWINDOW *FindCommand(DBOX *db, enum commands cmd, int class)
  294. {
  295.     CTLWINDOW *ct = db->ctl;
  296.     while (ct->class)    {
  297.         if (ct->class == class)
  298.             if (cmd == ct->command)
  299.                 return ct;
  300.         ct++;
  301.     }
  302.     return NULL;
  303. }
  304.  
  305. /* ---- return the window handle of a specified command ---- */
  306. WINDOW ControlWindow(DBOX *db, enum commands cmd)
  307. {
  308.     CTLWINDOW *ct = db->ctl;
  309.     while (ct->class)    {
  310.         if (ct->class != TEXT && cmd == ct->command)
  311.             return ct->wnd;
  312.         ct++;
  313.     }
  314.     return NULL;
  315. }
  316.  
  317. /* ---- set a control ON or OFF ----- */
  318. void ControlSetting(DBOX *db, enum commands cmd,
  319.                                 int class, int setting)
  320. {
  321.     CTLWINDOW *ct = FindCommand(db, cmd, class);
  322.     if (ct != NULL)    {
  323.         ct->isetting = setting;
  324.         if (ct->wnd != NULL)
  325.             ct->setting = setting;
  326.     }
  327. }
  328.  
  329. /* ---- return pointer to the text of a control window ---- */
  330. char *GetDlgTextString(DBOX *db,enum commands cmd,CLASS class)
  331. {
  332.     CTLWINDOW *ct = FindCommand(db, cmd, class);
  333.     if (ct != NULL)
  334.         return ct->itext;
  335.     else
  336.         return NULL;
  337. }
  338.  
  339. /* ------- set the text of a control specification ------ */
  340. void SetDlgTextString(DBOX *db, enum commands cmd,
  341.                                     char *text, CLASS class)
  342. {
  343.     CTLWINDOW *ct = FindCommand(db, cmd, class);
  344.     if (ct != NULL)    {
  345.         ct->itext = DFrealloc(ct->itext, strlen(text)+1);
  346.         strcpy(ct->itext, text);
  347.     }
  348. }
  349.  
  350. /* ------- set the text of a control window ------ */
  351. void PutItemText(WINDOW wnd, enum commands cmd, char *text)
  352. {
  353.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd, EDITBOX);
  354.  
  355.     if (ct == NULL)
  356.         ct = FindCommand(wnd->extension, cmd, TEXTBOX);
  357.     if (ct == NULL)
  358.         ct = FindCommand(wnd->extension, cmd, COMBOBOX);
  359.     if (ct == NULL)
  360.         ct = FindCommand(wnd->extension, cmd, LISTBOX);
  361.     if (ct == NULL)
  362.         ct = FindCommand(wnd->extension, cmd, SPINBUTTON);
  363.     if (ct == NULL)
  364.         ct = FindCommand(wnd->extension, cmd, TEXT);
  365.     if (ct != NULL)        {
  366.         WINDOW cwnd = (WINDOW) (ct->wnd);
  367.         switch (ct->class)    {
  368.             case COMBOBOX:
  369.             case EDITBOX:
  370.                 SendMessage(cwnd, CLEARTEXT, 0, 0);
  371.                 SendMessage(cwnd, ADDTEXT, (PARAM) text, 0);
  372.                 if (!isMultiLine(cwnd))
  373.                     SendMessage(cwnd, PAINT, 0, 0);
  374.                 break;
  375.             case LISTBOX:
  376.             case TEXTBOX:
  377.             case SPINBUTTON:
  378.                 SendMessage(cwnd, ADDTEXT, (PARAM) text, 0);
  379.                 break;
  380.             case TEXT:    {
  381.                 SendMessage(cwnd, CLEARTEXT, 0, 0);
  382.                 SendMessage(cwnd, ADDTEXT, (PARAM) text, 0);
  383.                 SendMessage(cwnd, PAINT, 0, 0);
  384.                 break;
  385.             }
  386.             default:
  387.                 break;
  388.         }
  389.     }
  390. }
  391.  
  392. /* ------- get the text of a control window ------ */
  393. void GetItemText(WINDOW wnd, enum commands cmd,
  394.                                 char *text, int len)
  395. {
  396.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd, EDITBOX);
  397.     unsigned char *cp;
  398.  
  399.     if (ct == NULL)
  400.         ct = FindCommand(wnd->extension, cmd, COMBOBOX);
  401.     if (ct == NULL)
  402.         ct = FindCommand(wnd->extension, cmd, TEXTBOX);
  403.     if (ct == NULL)
  404.         ct = FindCommand(wnd->extension, cmd, TEXT);
  405.     if (ct != NULL)    {
  406.         WINDOW cwnd = (WINDOW) (ct->wnd);
  407.         if (cwnd != NULL)    {
  408.             switch (ct->class)    {
  409.                 case TEXT:
  410.                     if (GetText(cwnd) != NULL)    {
  411.                         cp = strchr(GetText(cwnd), '\n');
  412.                         if (cp != NULL)
  413.                             len = (int) (cp - GetText(cwnd));
  414.                         strncpy(text, GetText(cwnd), len);
  415.                         *(text+len) = '\0';
  416.                     }
  417.                     break;
  418.                 case TEXTBOX:
  419.                     if (GetText(cwnd) != NULL)
  420.                         strncpy(text, GetText(cwnd), len);
  421.                     break;
  422.                 case COMBOBOX:
  423.                 case EDITBOX:
  424.                     SendMessage(cwnd,GETTEXT,(PARAM)text,len);
  425.                     break;
  426.                 default:
  427.                     break;
  428.             }
  429.         }
  430.     }
  431. }
  432.  
  433. /* ------- set the text of a listbox control window ------ */
  434. void GetDlgListText(WINDOW wnd, char *text, enum commands cmd)
  435. {
  436.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd, LISTBOX);
  437.     int sel = SendMessage(ct->wnd, LB_CURRENTSELECTION, 0, 0);
  438.     SendMessage(ct->wnd, LB_GETTEXT, (PARAM) text, sel);
  439. }
  440.  
  441. /* -- find control structure associated with text control -- */
  442. static CTLWINDOW *AssociatedControl(DBOX *db,enum commands Tcmd)
  443. {
  444.     CTLWINDOW *ct = db->ctl;
  445.     while (ct->class)    {
  446.         if (ct->class != TEXT)
  447.             if (ct->command == Tcmd)
  448.                 break;
  449.         ct++;
  450.     }
  451.     return ct;
  452. }
  453.  
  454. /* --- process dialog box shortcut keys --- */
  455. static void dbShortcutKeys(DBOX *db, int ky)
  456. {
  457.     CTLWINDOW *ct;
  458.     int ch = AltConvert(ky);
  459.  
  460.     if (ch != 0)    {
  461.         ct = db->ctl;
  462.         while (ct->class)    {
  463.             char *cp = ct->itext;
  464.             while (cp && *cp)    {
  465.                 if (*cp == SHORTCUTCHAR &&
  466.                             tolower(*(cp+1)) == ch)    {
  467.                     if (ct->class == TEXT)
  468.                         ct = AssociatedControl(db, ct->command);
  469.                     if (ct->class == RADIOBUTTON)
  470.                         SetRadioButton(db, ct);
  471.                     else if (ct->class == CHECKBOX)    {
  472.                         ct->setting ^= ON;
  473.                         SendMessage(ct->wnd, PAINT, 0, 0);
  474.                     }
  475.                     else if (ct->class)    {
  476.                         SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  477.                         if (ct->class == BUTTON)
  478.                            SendMessage(ct->wnd,KEYBOARD,'\r',0);
  479.                     }
  480.                     return;
  481.                 }
  482.                 cp++;
  483.             }
  484.             ct++;
  485.         }
  486.     }
  487. }
  488.  
  489. /* --- dynamically add or remove scroll bars
  490.                             from a control window ---- */
  491. void SetScrollBars(WINDOW wnd)
  492. {
  493.     int oldattr = GetAttribute(wnd);
  494.     if (wnd->wlines > ClientHeight(wnd))
  495.         AddAttribute(wnd, VSCROLLBAR);
  496.     else 
  497.         ClearAttribute(wnd, VSCROLLBAR);
  498.     if (wnd->textwidth > ClientWidth(wnd))
  499.         AddAttribute(wnd, HSCROLLBAR);
  500.     else 
  501.         ClearAttribute(wnd, HSCROLLBAR);
  502.     if (GetAttribute(wnd) != oldattr)
  503.         SendMessage(wnd, BORDER, 0, 0);
  504. }
  505.  
  506. /* ------- CREATE_WINDOW Message (Control) ----- */
  507. static void CtlCreateWindowMsg(WINDOW wnd)
  508. {
  509.     CTLWINDOW *ct;
  510.     ct = wnd->ct = wnd->extension;
  511.     wnd->extension = NULL;
  512.     if (ct != NULL)
  513.         ct->wnd = wnd;
  514. }
  515.  
  516. /* ------- KEYBOARD Message (Control) ----- */
  517. static BOOL CtlKeyboardMsg(WINDOW wnd, PARAM p1, PARAM p2)
  518. {
  519.     CTLWINDOW *ct = GetControl(wnd);
  520.     switch ((int) p1)    {
  521.         case F1:
  522.             if (WindowMoving || WindowSizing)
  523.                 break;
  524.             if (!DisplayHelp(wnd, ct->help))
  525.                 SendMessage(GetParent(wnd),COMMAND,ID_HELP,0);
  526.             return TRUE;
  527.         case ' ':
  528.             if (!((int)p2 & ALTKEY))
  529.                 break;
  530.         case ALT_F6:
  531.         case CTRL_F4:
  532.         case ALT_F4:
  533.             PostMessage(GetParent(wnd), KEYBOARD, p1, p2);
  534.             return TRUE;
  535.         default:
  536.             break;
  537.     }
  538.     if (GetClass(wnd) == EDITBOX)
  539.         if (isMultiLine(wnd))
  540.             return FALSE;
  541.     switch ((int) p1)    {
  542.         case UP:
  543.             if (!isDerivedFrom(wnd, LISTBOX))    {
  544.                 p1 = CTRL_FIVE;
  545.                 p2 = LEFTSHIFT;
  546.             }
  547.             break;
  548.         case BS:
  549.             if (!isDerivedFrom(wnd, EDITBOX))    {
  550.                 p1 = CTRL_FIVE;
  551.                 p2 = LEFTSHIFT;
  552.             }
  553.             break;
  554.         case DN:
  555.             if (!isDerivedFrom(wnd, LISTBOX) &&
  556.                     !isDerivedFrom(wnd, COMBOBOX))
  557.                 p1 = '\t';
  558.             break;
  559.         case FWD:
  560.             if (!isDerivedFrom(wnd, EDITBOX))
  561.                 p1 = '\t';
  562.             break;
  563.         case '\r':
  564.             if (isDerivedFrom(wnd, EDITBOX))
  565.                 if (isMultiLine(wnd))
  566.                     break;
  567.             if (isDerivedFrom(wnd, BUTTON))
  568.                 break;
  569.             SendMessage(GetParent(wnd), COMMAND, ID_OK, 0);
  570.             return TRUE;
  571.         default:
  572.             break;
  573.     }
  574.     return FALSE;
  575. }
  576.  
  577. /* ------- CLOSE_WINDOW Message (Control) ----- */
  578. static void CtlCloseWindowMsg(WINDOW wnd)
  579. {
  580.     CTLWINDOW *ct = GetControl(wnd);
  581.     if (ct != NULL)    {
  582.         ct->wnd = NULL;
  583.         if (GetParent(wnd)->ReturnCode == ID_OK)    {
  584.             if (ct->class == EDITBOX || ct->class == COMBOBOX)    {
  585.                 if (wnd->TextChanged)    {
  586.                     ct->itext=DFrealloc(ct->itext,strlen(wnd->text)+1);
  587.                     strcpy(ct->itext, wnd->text);
  588.                     if (!isMultiLine(wnd))    {
  589.                         char *cp = ct->itext+strlen(ct->itext)-1;
  590.                         if (*cp == '\n')
  591.                             *cp = '\0';
  592.                     }
  593.                 }
  594.             }
  595.             else if (ct->class == RADIOBUTTON || ct->class == CHECKBOX)
  596.                 ct->isetting = ct->setting;
  597.         }
  598.     }
  599. }
  600.  
  601.  
  602.  
  603. static void FixColors(WINDOW wnd)
  604. {
  605.     CTLWINDOW *ct = wnd->ct;
  606.     if (ct->class != BUTTON)    {
  607.         if (ct->class != SPINBUTTON && ct->class != COMBOBOX)    {
  608.             wnd->WindowColors[FRAME_COLOR][FG] = 
  609.                 GetParent(wnd)->WindowColors[FRAME_COLOR][FG];
  610.             wnd->WindowColors[FRAME_COLOR][BG] = 
  611.                 GetParent(wnd)->WindowColors[FRAME_COLOR][BG];
  612.             if (ct->class != EDITBOX && ct->class != LISTBOX)    {
  613.                 wnd->WindowColors[STD_COLOR][FG] = 
  614.                     GetParent(wnd)->WindowColors[STD_COLOR][FG];
  615.                 wnd->WindowColors[STD_COLOR][BG] = 
  616.                     GetParent(wnd)->WindowColors[STD_COLOR][BG];
  617.             }
  618.         }
  619.     }
  620. }
  621.  
  622. /* -- generic window processor used by dialog box controls -- */
  623. static int ControlProc(WINDOW wnd,MESSAGE msg,PARAM p1,PARAM p2)
  624. {
  625.     DBOX *db;
  626.     CTLWINDOW *ct;
  627.  
  628.     if (wnd == NULL)
  629.         return FALSE;
  630.     db = GetParent(wnd) ? GetParent(wnd)->extension : NULL;
  631.     ct = GetControl(wnd);
  632.  
  633.     switch (msg)    {
  634.         case CREATE_WINDOW:
  635.             CtlCreateWindowMsg(wnd);
  636.             break;
  637.         case KEYBOARD:
  638.             if (CtlKeyboardMsg(wnd, p1, p2))
  639.                 return TRUE;
  640.             break;
  641.         case PAINT:
  642.             FixColors(wnd);
  643.             if (GetClass(wnd) == EDITBOX ||
  644.                     GetClass(wnd) == LISTBOX ||
  645.                         GetClass(wnd) == TEXTBOX)
  646.                 SetScrollBars(wnd);
  647.             break;
  648.         case BORDER:
  649.             FixColors(wnd);
  650.             if (GetClass(wnd) == EDITBOX)    {
  651.                 WINDOW oldFocus = inFocus;
  652.                 inFocus = NULL;
  653.                 DefaultWndProc(wnd, msg, p1, p2);
  654.                 inFocus = oldFocus;
  655.                 return TRUE;
  656.             }
  657.             break;
  658.         case SETFOCUS:
  659.             if (p1)    {
  660.                 DefaultWndProc(wnd, msg, p1, p2);
  661.                 SendMessage(GetParent(wnd), COMMAND,
  662.                     inFocusCommand(db), ENTERFOCUS);
  663.                 return TRUE;
  664.             }
  665.             else 
  666.                 SendMessage(GetParent(wnd), COMMAND,
  667.                     inFocusCommand(db), LEAVEFOCUS);
  668.             break;
  669.         case CLOSE_WINDOW:
  670.             CtlCloseWindowMsg(wnd);
  671.             break;
  672.         default:
  673.             break;
  674.     }
  675.     return DefaultWndProc(wnd, msg, p1, p2);
  676. }
  677.  
  678. /* ---- change the focus to the first control --- */
  679. static void FirstFocus(WINDOW wnd)
  680. {
  681.     WINDOW fwnd = FirstWindow(wnd);
  682.     do    {
  683.         SendMessage(fwnd, SETFOCUS, TRUE, 0);
  684.         if ((fwnd = NextWindow(fwnd)) == NULL)
  685.             break;
  686.     } while (GetClass(inFocus) == TEXT || GetClass(inFocus) == BOX);
  687. }
  688.  
  689. /* ---- change the focus to the next control --- */
  690. static void NextFocus(void)
  691. {
  692.     do    SetNextFocus();
  693.     while (GetClass(inFocus) == TEXT || GetClass(inFocus) == BOX);
  694. }
  695.  
  696. /* ---- change the focus to the previous control --- */
  697. static void PrevFocus(void)
  698. {
  699.     do    SetPrevFocus();
  700.     while (GetClass(inFocus) == TEXT || GetClass(inFocus) == BOX);
  701. }
  702.  
  703. void SetFocusCursor(WINDOW wnd)
  704. {
  705.     if (wnd == inFocus)    {
  706.         SendMessage(NULL, SHOW_CURSOR, 0, 0);
  707.         SendMessage(wnd, KEYBOARD_CURSOR, 1, 0);
  708.     }
  709. }
  710.