home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / windows / dflat.zip / DIALBOX.C < prev    next >
Text File  |  1991-02-18  |  13KB  |  568 lines

  1. /* ----------------- dialbox.c -------------- */
  2.  
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <stdlib.h>
  6. #ifdef MSC
  7. #include <direct.h>
  8. #else
  9. #include <dir.h>
  10. #endif
  11. #include <dos.h>
  12. #include <io.h>
  13. #include "dflat.h"
  14.  
  15. static int inFocusCommand(DBOX *);
  16. static void SetRadioButton(WINDOW, DBOX *, CTLWINDOW *);
  17. static void dbShortcutKeys(WINDOW, DBOX *, int);
  18. static int ControlProc(WINDOW, MESSAGE, PARAM, PARAM);
  19.  
  20. static int SysMenuOpen = FALSE;
  21.  
  22. int DialogProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  23. {
  24.     int rtn;
  25.     DBOX *db;
  26.     CTLWINDOW *ct;
  27.  
  28.     db = wnd->extension;
  29.  
  30.     switch (msg)    {
  31.         case SETFOCUS:
  32.             if (p1)
  33.                 return TRUE;
  34.             break;
  35.         case LEFT_BUTTON:
  36.             if (WindowSizing || WindowMoving)
  37.                 return FALSE;
  38.             if (HitControlBox(wnd, p1-GetLeft(wnd), p2-GetTop(wnd)))    {
  39.                 PostMessage(wnd, KEYBOARD, ' ', ALTKEY);
  40.                 return TRUE;
  41.             }
  42.             ct = db->ctl;
  43.             while (ct->class)    {
  44.                 if (ct->class == RADIOBUTTON)    {
  45.                     int mx = (int) p1 - GetClientLeft(wnd);
  46.                     int my = (int) p2 - GetClientTop(wnd);
  47.                     if (my == ct->dwnd.y && mx == ct->dwnd.x+1)
  48.                         SetRadioButton(wnd, db, ct);
  49.                 }
  50.                 ct++;
  51.             }
  52.             break;
  53.         case PAINT:
  54.             if (!isVisible(wnd))
  55.                 break;
  56.             if (!p2)
  57.                 BaseWndProc(DIALOG, wnd, msg, p1, p2);
  58.             ct = p2 ? (CTLWINDOW *) p2 : db->ctl;
  59.             while (ct->class)    {
  60.                 if (ct->class == RADIOBUTTON)    {
  61.                     char rb[] = "( )";
  62.                     if (ct->itext)
  63.                         rb[1] = 7;
  64.                     SetClassColors(BUTTON);
  65.                     writeline(wnd, rb, ct->dwnd.x, ct->dwnd.y, FALSE);
  66.                 }
  67.                 else if (ct->class == TEXT && ct->vtext != NULL)    {
  68.                     char txt[100];
  69.                     char *cp = ct->vtext;
  70.                     int len = min(ct->dwnd.h, MsgHeight(cp));
  71.                     int i;
  72.                     for (i = 0; i < len; i++)    {
  73.                         int mlen, dif;
  74.                         char *np = strchr(cp, '\n');
  75.                         memset(txt, ' ', sizeof txt);
  76.                          mlen = CopyCommand(txt, cp, FALSE, WndBackground(wnd));
  77.                         if (np == NULL)
  78.                             dif = mlen - strlen(cp);
  79.                         else
  80.                             dif = mlen - (int) (np - cp);
  81.                         txt[ct->dwnd.w + 1 + dif] = '\0';
  82.                         SetStandardColor(wnd);
  83.                         writeline(wnd, txt, ct->dwnd.x, ct->dwnd.y+i, FALSE);
  84.                         if ((cp = strchr(cp, '\n')) != NULL)
  85.                             cp++;
  86.                     }
  87.                 }
  88.                 ct++;
  89.                 if (p2)
  90.                     break;
  91.             }
  92.             return TRUE;
  93.         case KEYBOARD:
  94.             switch ((int)p1)    {
  95.                 case '\t':
  96.                 case ALT_F6:
  97.                     SetNextFocus(inFocus, FALSE);
  98.                     break;
  99.                 case ' ':
  100.                     if ((p2 & ALTKEY) && TestAttribute(wnd, CONTROLBOX))    {
  101.                         wnd->dFocus = inFocus;
  102.                         SysMenuOpen = TRUE;
  103.                         BuildSystemMenu(wnd);
  104.                     }
  105.                     break;
  106.                 case ALT_F4:
  107.                 case ESC:
  108.                     if (!(WindowMoving || WindowSizing))
  109.                         SendMessage(wnd, COMMAND, ID_CANCEL, 0);
  110.                 case UP:
  111.                 case DN:
  112.                 case BS:
  113.                 case FWD:
  114.                 case '\r':
  115.                     if (WindowMoving || WindowSizing)
  116.                         return BaseWndProc(DIALOG, wnd, msg, p1, p2);
  117.                     break;
  118.                 default:
  119.                     /* ------ search all the shortcut keys ----- */
  120.                     dbShortcutKeys(wnd, db, (int) p1);
  121.                     break;
  122.             }
  123.             return TRUE;
  124.         case CLOSE_POPDOWN:
  125.             SysMenuOpen = FALSE;
  126.             break;
  127.         case BUTTON_RELEASED:
  128.             if (!WindowMoving && !WindowSizing)
  129.                 break;
  130.             rtn = BaseWndProc(DIALOG, wnd, msg, p1, p2);
  131.             SendMessage(wnd->dFocus, SETFOCUS, TRUE, 0);
  132.             return rtn;
  133.         case LB_SELECTION:
  134.         case LB_CHOOSE:
  135.             if (SysMenuOpen)
  136.                 return TRUE;
  137.             SendMessage(wnd, COMMAND, inFocusCommand(db), msg);
  138.             break;
  139.         case COMMAND:
  140.             switch ((int) p1)    {
  141.                 case ID_OK:
  142.                 case ID_CANCEL:
  143.                     wnd->ReturnCode = (int) p1;
  144.                     PostMessage(wnd, ENDDIALOG, 0, 0);
  145.                     return TRUE;
  146.                 default:
  147.                     break;
  148.             }
  149.             break;
  150.         case CLOSE_WINDOW:
  151.             ct = db->ctl;
  152.             while (ct->class)    {
  153.                 if (ct->vtext != NULL && ct->class == TEXT)    {
  154.                     free(ct->vtext);
  155.                     ct->vtext = NULL;
  156.                 }
  157.                 ct++;
  158.             }
  159.             break;
  160.         default:
  161.             break;
  162.     }
  163.     return BaseWndProc(DIALOG, wnd, msg, p1, p2);
  164. }
  165.  
  166. int DialogBox(DBOX *db,
  167.     int (*wndproc)(struct window *, enum messages, PARAM, PARAM))
  168. {
  169.     int rtn;
  170.     WINDOW Dwnd;
  171.     CTLWINDOW *ct;
  172.     WINDOW oldFocus = inFocus;
  173.     Dwnd = CreateWindow(DIALOG,
  174.                         db->dwnd.title,
  175.                         db->dwnd.x,
  176.                         db->dwnd.y,
  177.                         db->dwnd.h,
  178.                         db->dwnd.w,
  179.                         db,
  180.                         NULLWND,
  181.                         wndproc,
  182.                         0);
  183.     ct = db->ctl;
  184.     while (ct->class)    {
  185.         if (ct->class != TEXT && ct->class != RADIOBUTTON)    {
  186.             WINDOW cwnd;
  187.             int attrib = 0;
  188.             ct->vtext = ct->itext;
  189.             if ((ct->class == EDITBOX || ct->class == LISTBOX)
  190.                     && ct->dwnd.h > 1)
  191.                 attrib |= (MULTILINE | HASBORDER);
  192.             cwnd = CreateWindow(ct->class,
  193.                                 ct->dwnd.title,
  194.                                 ct->dwnd.x+GetClientLeft(Dwnd),
  195.                                 ct->dwnd.y+GetClientTop(Dwnd),
  196.                                 ct->dwnd.h,
  197.                                 ct->dwnd.w,
  198.                                 ct,
  199.                                 Dwnd,
  200.                                 ControlProc,
  201.                                 attrib);
  202.             ct->wnd = cwnd;
  203.             if (Dwnd->dFocus == NULLWND)
  204.                 Dwnd->dFocus = cwnd;
  205.             if (ct->itext)    {
  206.                 char txt[SCREENWIDTH];
  207.                 memset(txt, '\0', sizeof txt);
  208.                  CopyCommand(txt, ct->itext, FALSE, WndBackground(cwnd));
  209.                 SendMessage(cwnd, ADDTEXT, (PARAM) txt, 0);
  210.             }
  211.         }
  212.         else if (ct->class == TEXT && ct->itext != NULL)    {
  213.             int len = strlen(ct->itext)+1;
  214.             ct->vtext = malloc(len);
  215.             strncpy(ct->vtext, ct->itext, len);
  216.         }
  217.         ct++;
  218.     }
  219.     SendMessage(Dwnd->dFocus, SETFOCUS, TRUE, 0);
  220.     SendMessage(Dwnd, SHOW_WINDOW, 0, 0);
  221.     SendMessage(Dwnd, INITIATE_DIALOG, 0, 0);
  222.     SendMessage(Dwnd, CAPTURE_MOUSE, 0, 0);
  223.     SendMessage(Dwnd, CAPTURE_KEYBOARD, 0, 0);
  224.     while (dispatch_message())
  225.         ;
  226.     rtn = Dwnd->ReturnCode == ID_OK;
  227.     SendMessage(Dwnd, RELEASE_MOUSE, 0, 0);
  228.     SendMessage(Dwnd, RELEASE_KEYBOARD, 0, 0);
  229.     SendMessage(Dwnd, CLOSE_WINDOW, 0, 0);
  230.     SendMessage(oldFocus, SETFOCUS, TRUE, TRUE);
  231.     return rtn;
  232. }
  233.  
  234. static int inFocusCommand(DBOX *db)
  235. {
  236.     CTLWINDOW *ct = db->ctl;
  237.     while (ct->class)    {
  238.         if (ct->wnd == inFocus)
  239.             return ct->command;
  240.         ct++;
  241.     }
  242.     return -1;
  243. }
  244.  
  245. static CTLWINDOW *FindCommand(DBOX *db, enum commands cmd)
  246. {
  247.     CTLWINDOW *ct = db->ctl;
  248.     while (ct->class)    {
  249.         if (cmd == ct->command)
  250.             return ct;
  251.         ct++;
  252.     }
  253.     return NULL;
  254. }
  255.  
  256. void PushRadioButton(DBOX *db, enum commands cmd)
  257. {
  258.     CTLWINDOW *ct = FindCommand(db, cmd);
  259.     SetRadioButton(NULL, db, ct);
  260. }
  261.  
  262. static void SetRadioButton(WINDOW wnd, DBOX *db, CTLWINDOW *ct)
  263. {
  264.     CTLWINDOW *ctt = db->ctl;
  265.     while (ctt->class)    {
  266.         if (ctt->class == RADIOBUTTON)    {
  267.             ctt->itext = OFF;
  268.             if (wnd != NULLWND)
  269.                 SendMessage(wnd, PAINT, 0, (PARAM) ctt);
  270.         }
  271.         ctt++;
  272.     }
  273.     ct->itext = ON;
  274.     if (wnd != NULLWND)    {
  275.         SendMessage(wnd, PAINT, 0, (PARAM) ct);
  276.         PostMessage(GetParent(wnd), COMMAND, ct->command, 0);
  277.     }
  278. }
  279.  
  280. int RadioButtonSetting(DBOX *db, enum commands cmd)
  281. {
  282.     CTLWINDOW *ct = FindCommand(db, cmd);
  283.     if (ct != NULL && ct->class == RADIOBUTTON)
  284.         return (ct->itext != NULL);
  285.     return FALSE;
  286. }
  287.  
  288. void PutItemText(WINDOW wnd, enum commands cmd, char *text)
  289. {
  290.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd);
  291.     if (ct != NULL)        {
  292.         switch (ct->class)    {
  293.             case EDITBOX:
  294.                 SendMessage(ct->wnd, EB_PUTTEXT, (PARAM) text, 0);
  295.                 SendMessage(ct->wnd, PAINT, 0, 0);
  296.                 break;
  297.             case TEXT:    {
  298.                 ct->vtext = realloc(ct->vtext, strlen(text)+1);
  299.                 strcpy(ct->vtext, text);
  300.                 SendMessage(wnd, PAINT, 0, (PARAM) ct);
  301.                 break;
  302.             }
  303.             default:
  304.                 break;
  305.         }
  306.     }
  307. }
  308.  
  309. void GetItemText(WINDOW wnd, enum commands cmd, char *text, int len)
  310. {
  311.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd);
  312.     if (ct != NULL)    {
  313.         switch (ct->class)    {
  314.             case EDITBOX:
  315.                 SendMessage(ct->wnd, EB_GETTEXT, (PARAM) text, len);
  316.                 break;
  317.             case TEXT:
  318.                 strncpy(text, ct->vtext, len);
  319.                 break;
  320.             default:
  321.                 break;
  322.         }
  323.     }
  324. }
  325.  
  326. void GetDlgListText(WINDOW wnd, char *text, enum commands cmd)
  327. {
  328.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd);
  329.     int sel = SendMessage(ct->wnd, LB_CURRENTSELECTION, 0, 0);
  330.     SendMessage(ct->wnd, LB_GETTEXT, (PARAM) text, sel);
  331. }
  332.  
  333. int DlgDirList(WINDOW wnd, char *fspec,
  334.                 enum commands nameid, enum commands pathid,
  335.                 unsigned attrib)
  336. {
  337.     static char drive[MAXDRIVE] = " :";
  338.     static char dir[MAXDIR];
  339.     static char path[MAXPATH];
  340.     static char name[MAXFILE];
  341.     static char ext[MAXEXT];
  342.     int cm;
  343.     int ax, criterr = 1;
  344.     struct ffblk ff;
  345.     CTLWINDOW *ct = FindCommand(wnd->extension, nameid);
  346.     WINDOW lwnd;
  347.  
  348.     cm =
  349. #ifdef MSC
  350.          0;
  351. #endif
  352.     fnsplit(fspec, drive, dir, name, ext);
  353.     *drive = toupper(*drive);
  354.  
  355. #ifdef MSC
  356.     if (*ext)
  357.         cm |= EXTENSION;
  358.     if (*name)
  359.         cm |= FILENAME;
  360.     if (*dir)
  361.         cm |= DIRECTORY;
  362.     if (*drive)
  363.         cm |= DRIVE;
  364. #endif
  365.  
  366.     if (cm & DRIVE)
  367.         setdisk(*drive - 'A');
  368.     if (cm & DIRECTORY)    {
  369.         char *cp = dir+strlen(dir)-1;
  370.         if (*cp == '\\')
  371.             *cp = '\0';
  372.         chdir(dir);
  373.     }
  374.  
  375.     if (!(cm & DRIVE))    {
  376. #ifdef MSC
  377.         _dos_getdrive((unsigned *)drive);
  378.         *drive -= 1;
  379. #else
  380.         *drive = getdisk();
  381. #endif
  382.         *drive += 'A';
  383.     }
  384.  
  385.     getcwd(dir, sizeof dir);
  386.  
  387.     if ((attrib & 0x10) || !(cm & FILENAME))
  388.         strcpy(name, "*");
  389.     if ((attrib & 0x10) || !(cm & EXTENSION))
  390.         strcpy(ext, ".*");
  391.     fnmerge(path, drive, dir+2, name, ext);
  392.  
  393.     if (ct != NULL)    {
  394.  
  395.         lwnd = ct->wnd;
  396.         SendMessage(ct->wnd, CLEARTEXT, 0, 0);
  397.  
  398.         if (attrib & 0x8000)    {
  399.             union REGS regs;
  400.             char drname[15];
  401.             int cd, dr;
  402.  
  403. #ifdef MSC
  404.             _dos_getdrive(&cd);
  405.             cd -= 1;
  406. #else
  407.             cd = getdisk();
  408. #endif
  409.             for (dr = 0; dr < 26; dr++)    {
  410.                 unsigned ndr;
  411.                 setdisk(dr);
  412. #ifdef MSC
  413.                 _dos_getdrive(&ndr);
  414.                 ndr -= 1;
  415. #else
  416.                 ndr = getdisk();
  417. #endif
  418.                 if (ndr == dr)    {
  419.                     /* ------- test for remapped B drive ------- */
  420.                     if (dr == 1)    {
  421.                         regs.x.ax = 0x440e;        /* IOCTL function 14 */
  422.                         regs.h.bl = dr+1;
  423.                         int86(DOS, ®s, ®s);
  424.                         if (regs.h.al != 0)
  425.                             continue;
  426.                     }
  427.  
  428.                     sprintf(drname, "[%c:]", dr+'A');
  429.  
  430.                     /* ------ test for network or RAM disk ---- */
  431.                     regs.x.ax = 0x4409;        /* IOCTL function 9 */
  432.                     regs.h.bl = dr+1;
  433.                     int86(DOS, ®s, ®s);
  434.                     if (!regs.x.cflag)    {
  435.                         if (regs.x.dx & 0x1000)
  436.                             strcat(drname, " (Network)");
  437.                         else if (regs.x.dx == 0x0800)
  438.                             strcat(drname, " (RAMdisk)");
  439.                     }
  440.                     SendMessage(ct->wnd, ADDTEXT, (PARAM) drname, 0);
  441.                 }
  442.             }
  443.             setdisk(cd);
  444.         }
  445.  
  446.         while (criterr == 1)    {
  447.             ax = findfirst(path, &ff, attrib & 0x3f);
  448.             criterr = TestCriticalError();
  449.         }
  450.         if (criterr)
  451.             return FALSE;
  452.         while (ax == 0)    {
  453.             if (!((attrib & 0x4000) &&
  454.                     (ff.ff_attrib & (attrib & 0x3f)) == 0) &&
  455.                         strcmp(ff.ff_name, "."))    {
  456.                 char fname[15];
  457.                 sprintf(fname, (ff.ff_attrib & 0x10) ?
  458.                                 "[%s]" : "%s" , ff.ff_name);
  459.                 SendMessage(ct->wnd, ADDTEXT, (PARAM) fname, 0);
  460.             }
  461.             ax = findnext(&ff);
  462.         }
  463.  
  464.         if (lwnd->wlines > ClientHeight(lwnd))
  465.             AddAttribute(lwnd, VSCROLLBAR);
  466.         else
  467.             ClearAttribute(lwnd, VSCROLLBAR);
  468.         PostMessage(lwnd, SHOW_WINDOW, 0, 0);
  469.     }
  470.  
  471.     if (pathid)    {
  472.         fnmerge(path, drive, dir+2, NULL, NULL);
  473.         PutItemText(wnd, pathid, path);
  474.     }
  475.  
  476.     return TRUE;
  477. }
  478.  
  479. int MsgHeight(char *msg)
  480. {
  481.     int h = 1;
  482.     while ((msg = strchr(msg, '\n')) != NULL)    {
  483.         h++;
  484.         msg++;
  485.     }
  486.     return h;
  487. }
  488.  
  489. int MsgWidth(char *msg)
  490. {
  491.     int w = 0;
  492.     char *cp = msg;
  493.     while ((cp = strchr(msg, '\n')) != NULL)    {
  494.         w = max(w, (int) (cp-msg));
  495.         msg = cp+1;
  496.     }
  497.     return w == 0 ? strlen(msg) : w;
  498. }
  499.  
  500. static void dbShortcutKeys(WINDOW wnd, DBOX *db, int ky)
  501. {
  502.     int i;
  503.     CTLWINDOW *ct;
  504.  
  505.     for (i = 0; i < 36; i++)
  506.         if ((char) ky == altconvert[i])
  507.             break;
  508.     if (i < 36)    {
  509.         ct = db->ctl;
  510.         while (ct->class)    {
  511.             char *cp = ct->vtext;
  512.             while (*cp)    {
  513.                 if (*cp == SHORTCUTCHAR)    {
  514.                     int ch;
  515.                     if (i < 26)
  516.                         ch = 'a' + i;
  517.                     else
  518.                         ch = '0' + i - 26;
  519.                     if (tolower(*(cp+1)) == ch)    {
  520.                         if (ct->class == TEXT)
  521.                             ct++;
  522.                         if (ct->class == RADIOBUTTON)
  523.                             SetRadioButton(wnd, db, ct);
  524.                         else
  525.                             SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  526.                         return;
  527.                     }
  528.                 }
  529.                 cp++;
  530.             }
  531.             ct++;
  532.         }
  533.     }
  534. }
  535.  
  536. /* generic window processor used by all dialog box control windows */
  537. static int ControlProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  538. {
  539.     DBOX *db = GetParent(wnd)->extension;
  540.     switch (msg)    {
  541.         case KEYBOARD:
  542.             if (GetClass(wnd) == EDITBOX && !isMultiLine(wnd))    {
  543.                 if ((int) p1 == '\r')    {
  544.                     SendMessage(GetParent(wnd), COMMAND, ID_OK, 0);
  545.                     return TRUE;
  546.                 }
  547.             }
  548.             break;
  549.         case SETFOCUS:
  550.             if (GetClass(wnd) != BUTTON)    {
  551.                 if (p1)    {
  552.                     DefaultWndProc(wnd, msg, p1, p2);
  553.                     SendMessage(GetParent(wnd), COMMAND,
  554.                         inFocusCommand(db), ENTERFOCUS);
  555.                     return TRUE;
  556.                 }
  557.                 else 
  558.                     SendMessage(GetParent(wnd), COMMAND,
  559.                         inFocusCommand(db), LEAVEFOCUS);
  560.             }
  561.             break;
  562.         default:
  563.             break;
  564.     }
  565.     return DefaultWndProc(wnd, msg, p1, p2);
  566. }
  567.  
  568.