home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1991 / 06 / dflat3 / dialbox.c < prev    next >
Text File  |  1991-05-20  |  17KB  |  768 lines

  1. /* ----------------- dialbox.c -------------- */
  2.  
  3.  
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include <stdlib.h>
  7. #ifdef MSC
  8. #include <direct.h>
  9. #else
  10. #include <dir.h>
  11. #endif
  12. #include <dos.h>
  13. #include <io.h>
  14. #include "dflat.h"
  15.  
  16. static char path[MAXPATH];
  17. static char drive[MAXDRIVE] = " :";
  18. static char dir[MAXDIR];
  19. static char name[MAXFILE];
  20. static char ext[MAXEXT];
  21.  
  22. #ifdef INCLUDE_DIALOG_BOXES
  23.  
  24. static int inFocusCommand(DBOX *);
  25. static void SetRadioButton(WINDOW, DBOX *, CTLWINDOW *);
  26. static void InvertCheckBox(WINDOW, CTLWINDOW *);
  27. static void dbShortcutKeys(WINDOW, DBOX *, int);
  28. static int ControlProc(WINDOW, MESSAGE, PARAM, PARAM);
  29. static void ChangeFocus(WINDOW, int);
  30.  
  31. #ifdef INCLUDE_SYSTEM_MENUS
  32. static int SysMenuOpen = FALSE;
  33. #endif
  34.  
  35. int DialogProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  36. {
  37.     int rtn;
  38.     DBOX *db;
  39.     CTLWINDOW *ct;
  40.  
  41.     db = wnd->extension;
  42.  
  43.     switch (msg)    {
  44.         case SETFOCUS:
  45.             if (p1)
  46.                 return TRUE;
  47.             break;
  48.         case LEFT_BUTTON:
  49. #ifdef INCLUDE_SYSTEM_MENUS
  50.             if (WindowSizing || WindowMoving)
  51.                 return FALSE;
  52. #endif
  53.             if (HitControlBox(wnd, p1-GetLeft(wnd), p2-GetTop(wnd)))    {
  54.                 PostMessage(wnd, KEYBOARD, ' ', ALTKEY);
  55.                 return TRUE;
  56.             }
  57.             ct = db->ctl;
  58.             while (ct->class)    {
  59.                 int mx = (int) p1 - GetClientLeft(wnd);
  60.                 int my = (int) p2 - GetClientTop(wnd);
  61.                 if (ct->class == RADIOBUTTON)    {
  62.                     if (my == ct->dwnd.y && mx == ct->dwnd.x+1)
  63.                         SetRadioButton(wnd, db, ct);
  64.                 }
  65.                 else if (ct->class == CHECKBOX)    {
  66.                     if (my == ct->dwnd.y && mx == ct->dwnd.x+1)
  67.                         InvertCheckBox(wnd, ct);
  68.                 }
  69.                 ct++;
  70.             }
  71.             break;
  72.         case PAINT:
  73.             if (!isVisible(wnd))
  74.                 break;
  75.             if (!p2)
  76.                 BaseWndProc(DIALOG, wnd, msg, p1, p2);
  77.             ct = p2 ? (CTLWINDOW *) p2 : db->ctl;
  78.             while (ct->class)    {
  79.                 if (ct->class == RADIOBUTTON)    {
  80.                     char rb[] = "( )";
  81.                     if (ct->vtext)
  82.                         rb[1] = 7;
  83.                     SetClassColors(DIALOG);
  84.                     writeline(wnd, rb, ct->dwnd.x+1, ct->dwnd.y+1, FALSE);
  85.                 }
  86.                 else if (ct->class == CHECKBOX)    {
  87.                     char rb[] = "[ ]";
  88.                     if (ct->vtext)
  89.                         rb[1] = 'X';
  90.                     SetClassColors(DIALOG);
  91.                     writeline(wnd, rb, ct->dwnd.x+1, ct->dwnd.y+1, FALSE);
  92.                 }
  93.                 else if (ct->class == TEXT && ct->vtext != NULL)    {
  94.                     char txt[100];
  95.                     char *cp = ct->vtext;
  96.                     int len = min(ct->dwnd.h, MsgHeight(cp));
  97.                     int i;
  98.                     for (i = 0; i < len; i++)    {
  99.                         int mlen, dif;
  100.                         char *np = strchr(cp, '\n');
  101.                         memset(txt, ' ', sizeof txt);
  102.                          mlen = CopyCommand(txt, cp, FALSE, WndBackground(wnd));
  103.                         if (np == NULL)
  104.                             dif = mlen - strlen(cp);
  105.                         else
  106.                             dif = mlen - (int) (np - cp);
  107.                         txt[ct->dwnd.w + 1 + dif] = '\0';
  108.                         SetStandardColor(wnd);
  109.                         writeline(wnd, txt, ct->dwnd.x+1, ct->dwnd.y+i+1, FALSE);
  110.                         if ((cp = strchr(cp, '\n')) != NULL)
  111.                             cp++;
  112.                     }
  113.                 }
  114.                 ct++;
  115.                 if (p2)
  116.                     break;
  117.             }
  118.             return TRUE;
  119.         case KEYBOARD:
  120.             switch ((int)p1)    {
  121.                 case CTRL_FIVE:        /* same as SHIFT-TAB */
  122.                     if (p2 & (LEFTSHIFT | RIGHTSHIFT))
  123.                         ChangeFocus(wnd, FALSE);
  124.                     break;
  125.                 case '\t':
  126.                     ChangeFocus(wnd, TRUE);
  127.                     break;
  128. #ifdef INCLUDE_SYSTEM_MENUS
  129.                 case ' ':
  130.                     if ((p2 & ALTKEY) && TestAttribute(wnd, CONTROLBOX))    {
  131.                         wnd->dFocus = inFocus;
  132.                         SysMenuOpen = TRUE;
  133.                         BuildSystemMenu(wnd);
  134.                     }
  135.                     break;
  136. #endif
  137.                 case ALT_F4:
  138.                 case ESC:
  139. #ifdef INCLUDE_SYSTEM_MENUS
  140.                     if (!(WindowMoving || WindowSizing))
  141. #endif
  142.                         SendMessage(wnd, COMMAND, ID_CANCEL, 0);
  143. #ifdef INCLUDE_SYSTEM_MENUS
  144.                 case UP:
  145.                 case DN:
  146.                 case BS:
  147.                 case FWD:
  148.                 case '\r':
  149.                     if (WindowMoving || WindowSizing)
  150.                         return BaseWndProc(DIALOG, wnd, msg, p1, p2);
  151.                     break;
  152. #endif
  153.                 default:
  154.                     /* ------ search all the shortcut keys ----- */
  155.                     dbShortcutKeys(wnd, db, (int) p1);
  156.                     break;
  157.             }
  158.             return TRUE;
  159. #ifdef INCLUDE_SYSTEM_MENUS
  160.         case CLOSE_POPDOWN:
  161.             SysMenuOpen = FALSE;
  162.             break;
  163. #endif
  164.         case BUTTON_RELEASED:
  165. #ifdef INCLUDE_SYSTEM_MENUS
  166.             if (!WindowMoving && !WindowSizing)
  167.                 break;
  168. #endif
  169.             rtn = BaseWndProc(DIALOG, wnd, msg, p1, p2);
  170.             SendMessage(wnd->dFocus, SETFOCUS, TRUE, 0);
  171.             return rtn;
  172.         case LB_SELECTION:
  173.         case LB_CHOOSE:
  174. #ifdef INCLUDE_SYSTEM_MENUS
  175.             if (SysMenuOpen)
  176.                 return TRUE;
  177. #endif
  178.             SendMessage(wnd, COMMAND, inFocusCommand(db), msg);
  179.             break;
  180.         case COMMAND:
  181.             switch ((int) p1)    {
  182.                 case ID_OK:
  183.                 case ID_CANCEL:
  184.                     wnd->ReturnCode = (int) p1;
  185.                     PostMessage(wnd, ENDDIALOG, 0, 0);
  186.                     return TRUE;
  187.                 default:
  188.                     break;
  189.             }
  190.             break;
  191.         case CLOSE_WINDOW:
  192.             if (!p1)
  193.                 SendMessage(wnd, COMMAND, ID_CANCEL, 0);
  194.             else    {
  195.                 ct = db->ctl;
  196.                 while (ct->class)    {
  197.                     if (ct->vtext != NULL && ct->class == TEXT)    {
  198.                         free(ct->vtext);
  199.                         ct->vtext = NULL;
  200.                     }
  201.                     ct++;
  202.                 }
  203.             }
  204.             break;
  205.         default:
  206.             break;
  207.     }
  208.     return BaseWndProc(DIALOG, wnd, msg, p1, p2);
  209. }
  210.  
  211. int DialogBox(WINDOW wnd, DBOX *db,
  212.     int (*wndproc)(struct window *, enum messages, PARAM, PARAM))
  213. {
  214.     int rtn;
  215.     WINDOW Dwnd;
  216.     CTLWINDOW *ct;
  217.     WINDOW oldFocus = inFocus;
  218.     Dwnd = CreateWindow(DIALOG,
  219.                         db->dwnd.title,
  220.                         db->dwnd.x,
  221.                         db->dwnd.y,
  222.                         db->dwnd.h,
  223.                         db->dwnd.w,
  224.                         db,
  225.                         wnd,
  226.                         wndproc,
  227.                         NOCLIP);
  228.     ct = db->ctl;
  229.     while (ct->class)    {
  230.         if (ct->class != TEXT &&
  231.                 ct->class != RADIOBUTTON &&
  232.                     ct->class != CHECKBOX)    {
  233.             WINDOW cwnd;
  234.             int attrib = 0;
  235.             ct->vtext = ct->itext;
  236.             if (ct->class == EDITBOX && ct->dwnd.h > 1)
  237.                 attrib |= (MULTILINE | HASBORDER);
  238.             if (ct->class == LISTBOX)
  239.                 attrib |= HASBORDER;
  240.             cwnd = CreateWindow(ct->class,
  241.                                 ct->dwnd.title,
  242.                                 ct->dwnd.x+GetClientLeft(Dwnd),
  243.                                 ct->dwnd.y+GetClientTop(Dwnd),
  244.                                 ct->dwnd.h,
  245.                                 ct->dwnd.w,
  246.                                 NULL,
  247.                                 Dwnd,
  248.                                 ControlProc,
  249.                                 attrib);
  250.             ct->wnd = cwnd;
  251.             if (Dwnd->dFocus == NULLWND)
  252.                 Dwnd->dFocus = cwnd;
  253.             if (ct->itext)    {
  254.                 char txt[SCREENWIDTH];
  255.                 memset(txt, '\0', sizeof txt);
  256.                  CopyCommand(txt, ct->itext, FALSE, WndBackground(cwnd));
  257.                 SendMessage(cwnd, ADDTEXT, LPARAM(txt), 0);
  258.             }
  259.         }
  260.         else if (ct->class == TEXT && ct->itext != NULL)    {
  261.             int len = strlen(ct->itext)+1;
  262.             ct->vtext = malloc(len);
  263.             strncpy(ct->vtext, ct->itext, len);
  264.         }
  265.         else if (ct->class == RADIOBUTTON || ct->class == CHECKBOX)
  266.             ct->vtext = ct->itext;
  267.         ct++;
  268.     }
  269.     SendMessage(Dwnd->dFocus, SETFOCUS, TRUE, 0);
  270.     SendMessage(Dwnd, SHOW_WINDOW, 0, 0);
  271.     SendMessage(Dwnd, INITIATE_DIALOG, 0, 0);
  272.     SendMessage(Dwnd, CAPTURE_MOUSE, 0, 0);
  273.     SendMessage(Dwnd, CAPTURE_KEYBOARD, 0, 0);
  274.     while (dispatch_message())
  275.         ;
  276.     rtn = Dwnd->ReturnCode == ID_OK;
  277.     SendMessage(Dwnd, RELEASE_MOUSE, 0, 0);
  278.     SendMessage(Dwnd, RELEASE_KEYBOARD, 0, 0);
  279.     SendMessage(Dwnd, CLOSE_WINDOW, TRUE, 0);
  280.     SendMessage(oldFocus, SETFOCUS, TRUE, TRUE);
  281.     if (rtn)    {
  282.         ct = db->ctl;
  283.         while (ct->class)    {
  284.             if (ct->class == RADIOBUTTON || ct->class == CHECKBOX)
  285.                 ct->itext = ct->vtext;
  286.             ct++;
  287.         }
  288.     }
  289.     return rtn;
  290. }
  291.  
  292. static int inFocusCommand(DBOX *db)
  293. {
  294.     CTLWINDOW *ct = db->ctl;
  295.     while (ct->class)    {
  296.         if (ct->wnd == inFocus)
  297.             return ct->command;
  298.         ct++;
  299.     }
  300.     return -1;
  301. }
  302.  
  303. static 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. WINDOW ControlWindow(DBOX *db, enum commands cmd)
  316. {
  317.     CTLWINDOW *ct = db->ctl;
  318.     while (ct->class)    {
  319.         if (ct->class != TEXT && cmd == ct->command)
  320.             return ct->wnd;
  321.         ct++;
  322.     }
  323.     return NULLWND;
  324. }
  325.  
  326. CTLWINDOW *ControlBox(DBOX *db, WINDOW wnd)
  327. {
  328.     CTLWINDOW *ct = db->ctl;
  329.     while (ct->class)    {
  330.         if (ct->class != TEXT && wnd == ct->wnd)
  331.             return ct;
  332.         ct++;
  333.     }
  334.     return NULL;
  335. }
  336.  
  337. void PushRadioButton(DBOX *db, enum commands cmd)
  338. {
  339.     CTLWINDOW *ct = FindCommand(db, cmd, RADIOBUTTON);
  340.     if (ct != NULL)    {
  341.         SetRadioButton(NULLWND, db, ct);
  342.         ct->itext = ON;
  343.     }
  344. }
  345.  
  346. #define MAXRADIOS 50
  347.  
  348. static struct {
  349.     CTLWINDOW *rct;
  350. } rbs[MAXRADIOS];
  351.  
  352. static void SetRadioButton(WINDOW wnd, DBOX *db, CTLWINDOW *ct)
  353. {
  354.     CTLWINDOW *ctt = db->ctl;
  355.     int i;
  356.  
  357.     /* --- clear all the radio buttons
  358.                 in this group on the dialog box --- */
  359.  
  360.     /* -------- build a table of all radio buttons at the
  361.             same x vector ---------- */
  362.     for (i = 0; i < MAXRADIOS; i++)
  363.         rbs[i].rct = NULL;
  364.     while (ctt->class)    {
  365.         if (ctt->class == RADIOBUTTON)
  366.             if (ct->dwnd.x == ctt->dwnd.x)
  367.                 rbs[ctt->dwnd.y].rct = ctt;
  368.         ctt++;
  369.     }
  370.  
  371.     /* ----- find the start of the radiobutton group ---- */
  372.     i = ct->dwnd.y;
  373.     while (i >= 0 && rbs[i].rct != NULL)
  374.         --i;
  375.     /* ---- ignore everthing before the group ------ */
  376.     while (i >= 0)
  377.         rbs[i--].rct = NULL;
  378.  
  379.     /* ----- find the end of the radiobutton group ---- */
  380.     i = ct->dwnd.y;
  381.     while (i < MAXRADIOS && rbs[i].rct != NULL)
  382.         i++;
  383.     /* ---- ignore everthing past the group ------ */
  384.     while (i < MAXRADIOS)
  385.         rbs[i++].rct = NULL;
  386.  
  387.     for (i = 0; i < MAXRADIOS; i++)    {
  388.         if (rbs[i].rct != NULL)    {
  389.             rbs[i].rct->vtext = OFF;
  390.             if (wnd != NULLWND)
  391.                 SendMessage(wnd, PAINT, 0, LPARAM(rbs[i].rct));
  392.         }
  393.     }
  394.     ct->vtext = ON;
  395.     if (wnd != NULLWND)
  396.         SendMessage(wnd, PAINT, 0, LPARAM(ct));
  397. }
  398.  
  399. int RadioButtonSetting(DBOX *db, enum commands cmd)
  400. {
  401.     CTLWINDOW *ct = FindCommand(db, cmd, RADIOBUTTON);
  402.     if (ct != NULL)
  403.         return (ct->vtext != NULL);
  404.     return FALSE;
  405. }
  406.  
  407. void SetCheckBox(DBOX *db, enum commands cmd)
  408. {
  409.     CTLWINDOW *ct = FindCommand(db, cmd, CHECKBOX);
  410.     if (ct != NULL)
  411.         ct->itext = ON;
  412. }
  413.  
  414. void ClearCheckBox(DBOX *db, enum commands cmd)
  415. {
  416.     CTLWINDOW *ct = FindCommand(db, cmd, CHECKBOX);
  417.     if (ct != NULL)
  418.         ct->itext = ON;
  419. }
  420.  
  421. int CheckBoxSetting(DBOX *db, enum commands cmd)
  422. {
  423.     CTLWINDOW *ct = FindCommand(db, cmd, CHECKBOX);
  424.     if (ct != NULL)
  425.         return (ct->itext != NULL);
  426.     return FALSE;
  427. }
  428.  
  429. static void InvertCheckBox(WINDOW wnd, CTLWINDOW *ct)
  430. {
  431.     if (ct->vtext == ON)
  432.         ct->vtext = OFF;
  433.     else
  434.         ct->vtext = ON;
  435.     SendMessage(wnd, PAINT, 0, LPARAM(ct));
  436. }
  437.  
  438. void PutItemText(WINDOW wnd, enum commands cmd, char *text)
  439. {
  440.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd, EDITBOX);
  441.  
  442.     if (ct == NULL)
  443.         ct = FindCommand(wnd->extension, cmd, TEXT);
  444.     if (ct != NULL)        {
  445.         switch (ct->class)    {
  446.             case EDITBOX:
  447.                 SendMessage(ct->wnd, EB_PUTTEXT, LPARAM(text), 0);
  448.                 SendMessage(ct->wnd, PAINT, 0, 0);
  449.                 break;
  450.             case TEXT:    {
  451.                 ct->vtext = realloc(ct->vtext, strlen(text)+1);
  452.                 strcpy(ct->vtext, text);
  453.                 SendMessage(wnd, PAINT, 0, LPARAM(ct));
  454.                 break;
  455.             }
  456.             default:
  457.                 break;
  458.         }
  459.     }
  460. }
  461.  
  462. void GetItemText(WINDOW wnd, enum commands cmd, char *text, int len)
  463. {
  464.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd, EDITBOX);
  465.  
  466.     if (ct == NULL)
  467.         ct = FindCommand(wnd->extension, cmd, TEXT);
  468.     if (ct != NULL)    {
  469.         switch (ct->class)    {
  470.             case EDITBOX:
  471.                 SendMessage(ct->wnd, EB_GETTEXT, LPARAM(text), len);
  472.                 break;
  473.             case TEXT:
  474.                 strncpy(text, ct->vtext, len);
  475.                 break;
  476.             default:
  477.                 break;
  478.         }
  479.     }
  480. }
  481.  
  482. void GetDlgListText(WINDOW wnd, char *text, enum commands cmd)
  483. {
  484.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd, LISTBOX);
  485.     int sel = SendMessage(ct->wnd, LB_CURRENTSELECTION, 0, 0);
  486.     SendMessage(ct->wnd, LB_GETTEXT, LPARAM(text), sel);
  487. }
  488.  
  489. int DlgDirList(WINDOW wnd, char *fspec,
  490.                 enum commands nameid, enum commands pathid,
  491.                 unsigned attrib)
  492. {
  493.     int ax, criterr = 1;
  494.     struct ffblk ff;
  495.     CTLWINDOW *ct = FindCommand(wnd->extension, nameid, LISTBOX);
  496.     WINDOW lwnd;
  497.  
  498.     CreatePath(path, fspec, TRUE, TRUE);
  499.  
  500.     if (ct != NULL)    {
  501.         lwnd = ct->wnd;
  502.         SendMessage(ct->wnd, CLEARTEXT, 0, 0);
  503.  
  504.         if (attrib & 0x8000)    {
  505.             union REGS regs;
  506.             char drname[15];
  507.             int cd, dr;
  508.  
  509. #ifdef MSC
  510.             _dos_getdrive(&cd);
  511.             cd -= 1;
  512. #else
  513.             cd = getdisk();
  514. #endif
  515.             for (dr = 0; dr < 26; dr++)    {
  516.                 unsigned ndr;
  517.                 setdisk(dr);
  518. #ifdef MSC
  519.                 _dos_getdrive(&ndr);
  520.                 ndr -= 1;
  521. #else
  522.                 ndr = getdisk();
  523. #endif
  524.                 if (ndr == dr)    {
  525.                     /* ------- test for remapped B drive ------- */
  526.                     if (dr == 1)    {
  527.                         regs.x.ax = 0x440e;        /* IOCTL function 14 */
  528.                         regs.h.bl = dr+1;
  529.                         int86(DOS, ®s, ®s);
  530.                         if (regs.h.al != 0)
  531.                             continue;
  532.                     }
  533.  
  534.                     sprintf(drname, "[%c:]", dr+'A');
  535.  
  536.                     /* ------ test for network or RAM disk ---- */
  537.                     regs.x.ax = 0x4409;        /* IOCTL function 9 */
  538.                     regs.h.bl = dr+1;
  539.                     int86(DOS, ®s, ®s);
  540.                     if (!regs.x.cflag)    {
  541.                         if (regs.x.dx & 0x1000)
  542.                             strcat(drname, " (Network)");
  543.                         else if (regs.x.dx == 0x0800)
  544.                             strcat(drname, " (RAMdisk)");
  545.                     }
  546.                     SendMessage(ct->wnd, ADDTEXT, LPARAM(drname), 0);
  547.                 }
  548.             }
  549.             setdisk(cd);
  550.         }
  551.  
  552.         while (criterr == 1)    {
  553.             ax = findfirst(path, &ff, attrib & 0x3f);
  554.             criterr = TestCriticalError();
  555.         }
  556.         if (criterr)
  557.             return FALSE;
  558.         while (ax == 0)    {
  559.             if (!((attrib & 0x4000) &&
  560.                     (ff.ff_attrib & (attrib & 0x3f)) == 0) &&
  561.                         strcmp(ff.ff_name, "."))    {
  562.                 char fname[15];
  563.                 sprintf(fname, (ff.ff_attrib & 0x10) ?
  564.                                 "[%s]" : "%s" , ff.ff_name);
  565.                 SendMessage(ct->wnd, ADDTEXT, LPARAM(fname), 0);
  566.             }
  567.             ax = findnext(&ff);
  568.         }
  569.  
  570. #ifdef INCLUDE_SCROLLBARS
  571.         if (lwnd->wlines > ClientHeight(lwnd))
  572.             AddAttribute(lwnd, VSCROLLBAR);
  573.         else
  574.             ClearAttribute(lwnd, VSCROLLBAR);
  575. #endif
  576.         PostMessage(lwnd, SHOW_WINDOW, 0, 0);
  577.     }
  578.  
  579.     if (pathid)    {
  580.         fnmerge(path, drive, dir, NULL, NULL);
  581.         PutItemText(wnd, pathid, path);
  582.     }
  583.  
  584.     return TRUE;
  585. }
  586.  
  587. static void dbShortcutKeys(WINDOW wnd, DBOX *db, int ky)
  588. {
  589.     int i;
  590.     CTLWINDOW *ct;
  591.  
  592.     for (i = 0; i < 36; i++)
  593.         if ((char) ky == altconvert[i])
  594.             break;
  595.     if (i < 36)    {
  596.         ct = db->ctl;
  597.         while (ct->class)    {
  598.             char *cp = ct->vtext;
  599.             while (*cp)    {
  600.                 if (*cp == SHORTCUTCHAR)    {
  601.                     int ch;
  602.                     if (i < 26)
  603.                         ch = 'a' + i;
  604.                     else
  605.                         ch = '0' + i - 26;
  606.                     if (tolower(*(cp+1)) == ch)    {
  607.                         if (ct->class == TEXT)    {
  608.                             enum commands Tcmd = ct->command;
  609.                             /* --- find the associated control --- */
  610.                             ct = db->ctl;
  611.                             while (ct->class)    {
  612.                                 if (ct->class != TEXT)
  613.                                     if (ct->command == Tcmd)
  614.                                         break;
  615.                                 ct++;
  616.                             }
  617.                         }
  618.                         if (ct->class == RADIOBUTTON)
  619.                             SetRadioButton(wnd, db, ct);
  620.                         else if (ct->class == CHECKBOX)
  621.                             InvertCheckBox(wnd, ct);
  622.                         else if (ct->class)
  623.                             SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  624.                         return;
  625.                     }
  626.                 }
  627.                 cp++;
  628.             }
  629.             ct++;
  630.         }
  631.     }
  632. }
  633.  
  634. /* generic window processor used by all dialog box control windows */
  635. static int ControlProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  636. {
  637.     DBOX *db = GetParent(wnd)->extension;
  638.     switch (msg)    {
  639.         case KEYBOARD:
  640.             if (GetClass(wnd) == EDITBOX && !isMultiLine(wnd))    {
  641.                 if ((int) p1 == '\r')    {
  642.                     SendMessage(GetParent(wnd), COMMAND, ID_OK, 0);
  643.                     return TRUE;
  644.                 }
  645.             }
  646.             break;
  647.         case SETFOCUS:
  648.             if (GetClass(wnd) != BUTTON)    {
  649.                 if (p1)    {
  650.                     DefaultWndProc(wnd, msg, p1, p2);
  651.                     SendMessage(GetParent(wnd), COMMAND,
  652.                         inFocusCommand(db), ENTERFOCUS);
  653.                     return TRUE;
  654.                 }
  655.                 else 
  656.                     SendMessage(GetParent(wnd), COMMAND,
  657.                         inFocusCommand(db), LEAVEFOCUS);
  658.             }
  659.             break;
  660.         default:
  661.             break;
  662.     }
  663.     return DefaultWndProc(wnd, msg, p1, p2);
  664. }
  665.  
  666. #endif
  667.  
  668. /* ----- Create unambiguous path from file spec, filling in the
  669.      drive and directory if incomplete. Optionally change to
  670.      the new drive and subdirectory ------ */
  671. void CreatePath(char *path, char *fspec, int InclName, int Change)
  672. {
  673.     int cm = 0;
  674.         
  675.     *drive = *dir = *name = *ext = '\0';
  676. #ifndef MSC
  677.     cm =
  678. #endif
  679.     fnsplit(fspec, drive, dir, name, ext);
  680.     if (!InclName)
  681.         *name = *ext = '\0';
  682.     *drive = toupper(*drive);
  683.  
  684. #ifdef MSC
  685.     if (*ext)
  686.         cm |= EXTENSION;
  687.     if (InclName && *name)
  688.         cm |= FILENAME;
  689.     if (*dir)
  690.         cm |= DIRECTORY;
  691.     if (*drive)
  692.         cm |= DRIVE;
  693. #endif
  694.  
  695.     if (Change)    {
  696.         if (cm & DRIVE)
  697.             setdisk(*drive - 'A');
  698.         if (cm & DIRECTORY)    {
  699.             char *cp = dir+strlen(dir)-1;
  700.             if (*cp == '\\')
  701.                 *cp = '\0';
  702.             chdir(dir);
  703.         }
  704.     }
  705.  
  706.  
  707.     if (!(cm & DRIVE))    {
  708. #ifdef MSC
  709.         _dos_getdrive((unsigned *)drive);
  710.         *drive -= 1;
  711. #else
  712.         *drive = getdisk();
  713. #endif
  714.         *drive += 'A';
  715.     }
  716.  
  717.     if (!(cm & DIRECTORY))    {
  718.         getcwd(dir, sizeof dir);
  719.         memmove(dir, dir+2, strlen(dir+1));
  720.     }
  721.  
  722.     if (InclName)    {
  723.         if (!(cm & FILENAME))
  724.             strcpy(name, "*");
  725.         if (!(cm & EXTENSION))
  726.             strcpy(ext, ".*");
  727.     }
  728.     else
  729.         *name = *ext = '\0';
  730.     if (dir[strlen(dir)-1] != '\\')
  731.         strcat(dir, "\\");
  732.     memset(path, 0, sizeof path);
  733.     fnmerge(path, drive, dir, name, ext);
  734. }
  735.  
  736. static void ChangeFocus(WINDOW wnd, int direc)
  737. {
  738.     DBOX *db = wnd->extension;
  739.      CTLWINDOW *ct = db->ctl;
  740.      CTLWINDOW *ctt;
  741.  
  742.     while (ct->class)    {
  743.         if (ct->wnd == inFocus)
  744.             break;
  745.         ct++;
  746.     }
  747.     if (ct->class)    {
  748.         ctt = ct;
  749.         do    {
  750.             if (direc)    {
  751.                 ct++;
  752.                 if (ct->class == 0)
  753.                     ct = db->ctl;
  754.             }
  755.             else    {
  756.                 if (ct == db->ctl)
  757.                     while (ct->class)
  758.                         ct++;
  759.                 --ct;
  760.             }
  761.             if (ct->wnd != NULLWND)    {
  762.                 SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  763.                 break;
  764.             }
  765.         } while (ct != ctt);
  766.     }
  767. }
  768.