home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 24 / CD_ASCQ_24_0995.iso / vrac / dflt20.zip / HELPBOX.C < prev    next >
Text File  |  1994-05-05  |  19KB  |  624 lines

  1. /* ------------ helpbox.c ----------- */
  2.  
  3. #include "dflat.h"
  4. #include "htree.h"
  5.  
  6. extern DBOX HelpBox;
  7.  
  8. /* -------- strings of D-Flat classes for calling default
  9.       help text collections -------- */
  10. char *ClassNames[] = {
  11.     #undef ClassDef
  12.     #define ClassDef(c,b,p,a) #c,
  13.     #include "classes.h"
  14.     NULL
  15. };
  16.  
  17. #define MAXHEIGHT (SCREENHEIGHT-10)
  18. #define MAXHELPKEYWORDS 50  /* --- maximum keywords in a window --- */
  19. #define MAXHELPSTACK 100
  20.  
  21. static struct helps *FirstHelp;
  22. static struct helps *ThisHelp;
  23. static int HelpCount;
  24. static char HelpFileName[9];
  25.  
  26. static int HelpStack[MAXHELPSTACK];
  27. static int stacked;
  28.  
  29. /* --- keywords in the current help text -------- */
  30. static struct keywords {
  31.     struct helps *hkey;
  32.     int lineno;
  33.     int off1, off2, off3;
  34.     char isDefinition;
  35. } KeyWords[MAXHELPKEYWORDS];
  36. static struct keywords *thisword;
  37. static int keywordcount;
  38.  
  39. static FILE *helpfp;
  40. static char hline [160];
  41. static BOOL Helping;
  42.  
  43. static void SelectHelp(WINDOW, struct helps *, BOOL);
  44. static void ReadHelp(WINDOW);
  45. static struct helps *FindHelp(char *);
  46. static void DisplayDefinition(WINDOW, char *);
  47. static void BestFit(WINDOW, DIALOGWINDOW *);
  48.  
  49. /* ------------- CREATE_WINDOW message ------------ */
  50. static void CreateWindowMsg(WINDOW wnd)
  51. {
  52.     Helping = TRUE;
  53.     GetClass(wnd) = HELPBOX;
  54.     InitWindowColors(wnd);
  55.     if (ThisHelp != NULL)
  56.         ThisHelp->hwnd = wnd;
  57. }
  58.  
  59. /* ------------- COMMAND message ------------ */
  60. static BOOL CommandMsg(WINDOW wnd, PARAM p1)
  61. {
  62.     switch ((int)p1)    {
  63.         case ID_PREV:
  64.             if (ThisHelp  != NULL)
  65.                 SelectHelp(wnd, FirstHelp+(ThisHelp->prevhlp), TRUE);
  66.             return TRUE;
  67.         case ID_NEXT:
  68.             if (ThisHelp != NULL)
  69.                 SelectHelp(wnd, FirstHelp+(ThisHelp->nexthlp), TRUE);
  70.             return TRUE;
  71.         case ID_BACK:
  72.             if (stacked)
  73.                 SelectHelp(wnd, FirstHelp+HelpStack[--stacked], FALSE);
  74.             return TRUE;
  75.         default:
  76.             break;
  77.     }
  78.     return FALSE;
  79. }
  80.  
  81. /* ------------- KEYBOARD message ------------ */
  82. static BOOL KeyboardMsg(WINDOW wnd, PARAM p1)
  83. {
  84.     WINDOW cwnd;
  85.  
  86.     cwnd = ControlWindow(wnd->extension, ID_HELPTEXT);
  87.     if (cwnd == NULL || inFocus != cwnd)
  88.         return FALSE;
  89.     switch ((int)p1)    {
  90.         case '\r':
  91.             if (keywordcount)
  92.                 if (thisword != NULL)    {
  93.                     char *hp = thisword->hkey->hname;
  94.                     if (thisword->isDefinition)
  95.                         DisplayDefinition(GetParent(wnd), hp);
  96.                     else
  97.                         SelectHelp(wnd, thisword->hkey, TRUE);
  98.                 }
  99.             return TRUE;
  100.         case '\t':
  101.             if (!keywordcount)
  102.                 return TRUE;
  103.             if (thisword == NULL ||
  104.                     ++thisword == KeyWords+keywordcount)
  105.                 thisword = KeyWords;
  106.             break;
  107.         case SHIFT_HT:
  108.             if (!keywordcount)
  109.                 return TRUE;
  110.             if (thisword == NULL || thisword == KeyWords)
  111.                 thisword = KeyWords+keywordcount;
  112.             --thisword;
  113.             break;;
  114.         default:
  115.             return FALSE;
  116.     }
  117.     if (thisword->lineno < cwnd->wtop ||
  118.             thisword->lineno >=
  119.                 cwnd->wtop + ClientHeight(cwnd))  {
  120.         int distance = ClientHeight(cwnd)/2;
  121.         do    {
  122.             cwnd->wtop = thisword->lineno-distance;
  123.             distance /= 2;
  124.         }
  125.         while (cwnd->wtop < 0);
  126.     }
  127.     SendMessage(cwnd, PAINT, 0, 0);
  128.     return TRUE;
  129. }
  130.  
  131. /* ---- window processing module for the HELPBOX ------- */
  132. int HelpBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  133. {
  134.     switch (msg)    {
  135.         case CREATE_WINDOW:
  136.             CreateWindowMsg(wnd);
  137.             break;
  138.         case INITIATE_DIALOG:
  139.             ReadHelp(wnd);
  140.             break;
  141.         case COMMAND:
  142.             if (p2 != 0)
  143.                 break;
  144.             if (CommandMsg(wnd, p1))
  145.                 return TRUE;
  146.             break;
  147.         case KEYBOARD:
  148.             if (WindowMoving)
  149.                 break;
  150.             if (KeyboardMsg(wnd, p1))
  151.                 return TRUE;
  152.             break;
  153.         case CLOSE_WINDOW:
  154.             if (ThisHelp != NULL)
  155.                 ThisHelp->hwnd = NULL;
  156.             Helping = FALSE;
  157.             break;
  158.         default:
  159.             break;
  160.     }
  161.     return BaseWndProc(HELPBOX, wnd, msg, p1, p2);
  162. }
  163.  
  164. /* ---- PAINT message for the helpbox text editbox ---- */
  165. static int PaintMsg(WINDOW wnd, PARAM p1, PARAM p2)
  166. {
  167.     int rtn;
  168.     if (thisword != NULL)    {
  169.         WINDOW pwnd = GetParent(wnd);
  170.         char *cp;
  171.         cp = TextLine(wnd, thisword->lineno);
  172.         cp += thisword->off1;
  173.         *(cp+1) =
  174.             (pwnd->WindowColors[SELECT_COLOR][FG] & 255) | 0x80;
  175.         *(cp+2) =
  176.             (pwnd->WindowColors[SELECT_COLOR][BG] & 255) | 0x80;
  177.         rtn = DefaultWndProc(wnd, PAINT, p1, p2);
  178.         *(cp+1) =
  179.             (pwnd->WindowColors[HILITE_COLOR][FG] & 255) | 0x80;
  180.         *(cp+2) =
  181.             (pwnd->WindowColors[HILITE_COLOR][BG] & 255) | 0x80;
  182.         return rtn;
  183.     }
  184.     return DefaultWndProc(wnd, PAINT, p1, p2);
  185. }
  186.  
  187. /* ---- LEFT_BUTTON message for the helpbox text editbox ---- */
  188. static int LeftButtonMsg(WINDOW wnd, PARAM p1, PARAM p2)
  189. {
  190.     int rtn, mx, my, i;
  191.  
  192.     rtn = DefaultWndProc(wnd, LEFT_BUTTON, p1, p2);
  193.     mx = (int)p1 - GetClientLeft(wnd);
  194.     my = (int)p2 - GetClientTop(wnd);
  195.     my += wnd->wtop;
  196.     thisword = KeyWords;
  197.     for (i = 0; i < keywordcount; i++)    {
  198.         if (my == thisword->lineno)    {
  199.             if (mx >= thisword->off2 &&
  200.                         mx < thisword->off3)    {
  201.                 SendMessage(wnd, PAINT, 0, 0);
  202.                 if (thisword->isDefinition)    {
  203.                     WINDOW pwnd = GetParent(wnd);
  204.                     if (pwnd != NULL)
  205.                         DisplayDefinition(GetParent(pwnd),
  206.                             thisword->hkey->hname);
  207.                 }
  208.                 break;
  209.             }
  210.         }
  211.         thisword++;
  212.     }
  213.     if (i == keywordcount)
  214.         thisword = NULL;
  215.     return rtn;
  216. }
  217.  
  218. /* --- window processing module for HELPBOX's text EDITBOX -- */
  219. int HelpTextProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  220. {
  221.     switch (msg)    {
  222.         case KEYBOARD:
  223.             break;
  224.         case PAINT:
  225.             return PaintMsg(wnd, p1, p2);
  226.         case LEFT_BUTTON:
  227.             return LeftButtonMsg(wnd, p1, p2);
  228.         case DOUBLE_CLICK:
  229.             PostMessage(wnd, KEYBOARD, '\r', 0);
  230.             break;
  231.         default:
  232.             break;
  233.     }
  234.     return DefaultWndProc(wnd, msg, p1, p2);
  235. }
  236.  
  237. /* -------- read the help text into the editbox ------- */
  238. static void ReadHelp(WINDOW wnd)
  239. {
  240.     WINDOW cwnd = ControlWindow(wnd->extension, ID_HELPTEXT);
  241.     int linectr = 0;
  242.     if (cwnd == NULL)
  243.         return;
  244.     thisword = KeyWords;
  245.     keywordcount = 0;
  246.     cwnd->wndproc = HelpTextProc;
  247.     SendMessage(cwnd, CLEARTEXT, 0, 0);
  248.     /* ----- read the help text ------- */
  249.     while (TRUE)    {
  250.         unsigned char *cp = hline, *cp1;
  251.         int colorct = 0;
  252.         if (GetHelpLine(hline) == NULL)
  253.             break;
  254.         if (*hline == '<')
  255.             break;
  256.         hline[strlen(hline)-1] = '\0';
  257.         /* --- add help text to the help window --- */
  258.         while (cp != NULL)    {
  259.             if ((cp = strchr(cp, '[')) != NULL)    {
  260.                 /* ----- hit a new key word ----- */
  261.                 if (*(cp+1) != '.' && *(cp+1) != '*')    {
  262.                     cp++;
  263.                     continue;
  264.                 }
  265.                 thisword->lineno = cwnd->wlines;
  266.                 thisword->off1 = (int) (cp - hline);
  267.                 thisword->off2 = thisword->off1 - colorct * 4;
  268.                 thisword->isDefinition = *(cp+1) == '*';
  269.                 colorct++;
  270.                 *cp++ = CHANGECOLOR;
  271.                 *cp++ =
  272.             (wnd->WindowColors [HILITE_COLOR] [FG] & 255) | 0x80;
  273.                 *cp++ =
  274.             (wnd->WindowColors [HILITE_COLOR] [BG] & 255) | 0x80;
  275.                 cp1 = cp;
  276.                 if ((cp = strchr(cp, ']')) != NULL)    {
  277.                     if (thisword != NULL)
  278.                         thisword->off3 =
  279.                             thisword->off2 + (int) (cp - cp1);
  280.                     *cp++ = RESETCOLOR;
  281.                 }
  282.                 if ((cp = strchr(cp, '<')) != NULL)    {
  283.                     char *cp1 = strchr(cp, '>');
  284.                     if (cp1 != NULL)    {
  285.                         char hname[80];
  286.                         int len = (int) (cp1 - cp);
  287.                         memset(hname, 0, 80);
  288.                         strncpy(hname, cp+1, len-1);
  289.                         thisword->hkey = FindHelp(hname);
  290.                         memmove(cp, cp1+1, strlen(cp1));
  291.                     }
  292.                 }
  293.                 thisword++;
  294.                 keywordcount++;
  295.             }
  296.         }
  297.         PutItemText(wnd, ID_HELPTEXT, hline);
  298.         /* -- display help text as soon as window is full -- */
  299.         if (++linectr == ClientHeight(cwnd))    {
  300.             struct keywords *holdthis = thisword;
  301.             thisword = NULL;
  302.             SendMessage(cwnd, PAINT, 0, 0);
  303.             thisword = holdthis;
  304.         }
  305.         if (linectr > ClientHeight(cwnd) &&
  306.                 !TestAttribute(cwnd, VSCROLLBAR))    {
  307.             AddAttribute(cwnd, VSCROLLBAR);
  308.             SendMessage(cwnd, BORDER, 0, 0);
  309.         }
  310.     }
  311.     thisword = NULL;
  312. }
  313.  
  314. /* ---- compute the displayed length of a help text line --- */
  315. static int HelpLength(char *s)
  316. {
  317.     int len = strlen(s);
  318.     char *cp = strchr(s, '[');
  319.     while (cp != NULL)    {
  320.         len -= 4;
  321.         cp = strchr(cp+1, '[');
  322.     }
  323.     cp = strchr(s, '<');
  324.     while (cp != NULL)    {
  325.         char *cp1 = strchr(cp, '>');
  326.         if (cp1 != NULL)
  327.             len -= (int) (cp1-cp)+1;
  328.         cp = strchr(cp1, '<');
  329.     }
  330.     return len;
  331. }
  332.  
  333. /* ----------- load the help text file ------------ */
  334. void LoadHelpFile(char *fname)
  335. {
  336.     long where;
  337.     int i;
  338.     if (Helping)
  339.         return;
  340.     UnLoadHelpFile();
  341.     if ((helpfp = OpenHelpFile(fname, "rb")) == NULL)
  342.         return;
  343.     strcpy(HelpFileName, fname);
  344.     fseek(helpfp, - (long) sizeof(long), SEEK_END);
  345.     fread(&where, sizeof(long), 1, helpfp);
  346.     fseek(helpfp, where, SEEK_SET);
  347.     fread(&HelpCount, sizeof(int), 1, helpfp);
  348.     FirstHelp = DFcalloc(sizeof(struct helps) * HelpCount, 1);
  349.     for (i = 0; i < HelpCount; i++)    {
  350.         int len;
  351.         fread(&len, sizeof(int), 1, helpfp);
  352.         if (len)    {
  353.             (FirstHelp+i)->hname = DFcalloc(len+1, 1);
  354.             fread((FirstHelp+i)->hname, len+1, 1, helpfp);
  355.         }
  356.         fread(&len, sizeof(int), 1, helpfp);
  357.         if (len)    {
  358.             (FirstHelp+i)->comment = DFcalloc(len+1, 1);
  359.             fread((FirstHelp+i)->comment, len+1, 1, helpfp);
  360.         }
  361.         fread(&(FirstHelp+i)->hptr, sizeof(int)*5+sizeof(long), 1, helpfp);
  362.     }
  363.     fclose(helpfp);
  364.     helpfp = NULL;
  365. }
  366.  
  367. /* ------ free the memory used by the help file table ------ */
  368. void UnLoadHelpFile(void)
  369. {
  370.     int i;
  371.     for (i = 0; i < HelpCount; i++)    {
  372.         free((FirstHelp+i)->comment);
  373.         free((FirstHelp+i)->hname);
  374.     }
  375.     free(FirstHelp);
  376.     FirstHelp = NULL;
  377.     free(HelpTree);
  378.     HelpTree = NULL;
  379. }
  380.  
  381. static void BuildHelpBox(WINDOW wnd)
  382. {
  383.     int offset, i;
  384.  
  385.     /* -- seek to the first line of the help text -- */
  386.     SeekHelpLine(ThisHelp->hptr, ThisHelp->bit);
  387.     /* ----- read the title ----- */
  388.     GetHelpLine(hline);
  389.     hline[strlen(hline)-1] = '\0';
  390.     free(HelpBox.dwnd.title);
  391.     HelpBox.dwnd.title = DFmalloc(strlen(hline)+1);
  392.     strcpy(HelpBox.dwnd.title, hline);
  393.     /* ----- set the height and width ----- */
  394.     HelpBox.dwnd.h = min(ThisHelp->hheight, MAXHEIGHT)+7;
  395.     HelpBox.dwnd.w = max(45, ThisHelp->hwidth+6);
  396.     /* ------ position the help window ----- */
  397.     if (wnd != NULL)
  398.         BestFit(wnd, &HelpBox.dwnd);
  399.     /* ------- position the command buttons ------ */
  400.     HelpBox.ctl[0].dwnd.w = max(40, ThisHelp->hwidth+2);
  401.     HelpBox.ctl[0].dwnd.h =
  402.                 min(ThisHelp->hheight, MAXHEIGHT)+2;
  403.     offset = (HelpBox.dwnd.w-40) / 2;
  404.     for (i = 1; i < 5; i++)    {
  405.            HelpBox.ctl[i].dwnd.y =
  406.                    min(ThisHelp->hheight, MAXHEIGHT)+3;
  407.            HelpBox.ctl[i].dwnd.x = (i-1) * 10 + offset;
  408.     }
  409.     /* ---- disable ineffective buttons ---- */
  410.     if (ThisHelp->nexthlp == -1)
  411.         DisableButton(&HelpBox, ID_NEXT);
  412.     else
  413.         EnableButton(&HelpBox, ID_NEXT);
  414.     if (ThisHelp->prevhlp == -1)
  415.         DisableButton(&HelpBox, ID_PREV);
  416.     else 
  417.         EnableButton(&HelpBox, ID_PREV);
  418. }
  419.  
  420. /* ----- select a new help window from its name ----- */
  421. static void SelectHelp(WINDOW wnd, struct helps *newhelp, BOOL recall)
  422. {
  423.     if (newhelp != NULL)    {
  424.         int i, x, y;
  425.         SendMessage(wnd, HIDE_WINDOW, 0, 0);
  426.         if (recall && stacked < MAXHELPSTACK)
  427.             HelpStack[stacked++] = ThisHelp-FirstHelp;
  428.         ThisHelp = newhelp;
  429.         SendMessage(GetParent(wnd), DISPLAY_HELP, (PARAM) ThisHelp->hname, 0);
  430.         if (stacked)
  431.             EnableButton(&HelpBox, ID_BACK);
  432.         else 
  433.             DisableButton(&HelpBox, ID_BACK);
  434.         BuildHelpBox(NULL);
  435.         AddTitle(wnd, HelpBox.dwnd.title);
  436.         /* --- reposition and resize the help window --- */
  437.         HelpBox.dwnd.x = (SCREENWIDTH-HelpBox.dwnd.w)/2;
  438.         HelpBox.dwnd.y = (SCREENHEIGHT-HelpBox.dwnd.h)/2;
  439.         SendMessage(wnd, MOVE, HelpBox.dwnd.x, HelpBox.dwnd.y);
  440.         SendMessage(wnd, SIZE,
  441.                         HelpBox.dwnd.x + HelpBox.dwnd.w - 1,
  442.                         HelpBox.dwnd.y + HelpBox.dwnd.h - 1);
  443.         /* --- reposition the controls --- */
  444.         for (i = 0; i < 5; i++)    {
  445.             WINDOW cwnd = HelpBox.ctl[i].wnd;
  446.             x = HelpBox.ctl[i].dwnd.x+GetClientLeft(wnd);
  447.             y = HelpBox.ctl[i].dwnd.y+GetClientTop(wnd);
  448.             SendMessage(cwnd, MOVE, x, y);
  449.             if (i == 0)    {
  450.                 x += HelpBox.ctl[i].dwnd.w - 1;
  451.                 y += HelpBox.ctl[i].dwnd.h - 1;
  452.                 SendMessage(cwnd, SIZE, x, y);
  453.             }
  454.         }
  455.         /* --- read the help text into the help window --- */
  456.         ReadHelp(wnd);
  457.         ReFocus(wnd);
  458.         SendMessage(wnd, SHOW_WINDOW, 0, 0);
  459.     }
  460. }
  461. /* ---- strip tildes from the help name ---- */
  462. static void StripTildes(char *fh, char *hp)
  463. {
  464.     while (*hp)    {
  465.         if (*hp != '~')
  466.             *fh++ = *hp;
  467.         hp++;
  468.     }
  469.     *fh = '\0';
  470. }
  471. /* --- return the comment associated with a help window --- */
  472. char *HelpComment(char *Help)
  473. {
  474.     char FixedHelp[30];
  475.     StripTildes(FixedHelp, Help);
  476.     if ((ThisHelp = FindHelp(FixedHelp)) != NULL)
  477.         return ThisHelp->comment;
  478.     return NULL;
  479. }
  480. /* ---------- display help text ----------- */
  481. BOOL DisplayHelp(WINDOW wnd, char *Help)
  482. {
  483.     char FixedHelp[30];
  484.     BOOL rtn = FALSE;
  485.  
  486.     if (Helping)
  487.         return TRUE;
  488.     StripTildes(FixedHelp, Help);
  489.     stacked = 0;
  490.     wnd->isHelping++;
  491.     if ((ThisHelp = FindHelp(FixedHelp)) != NULL)    {
  492.         if ((helpfp = OpenHelpFile(HelpFileName, "rb")) != NULL)    {
  493.             BuildHelpBox(wnd);
  494.             DisableButton(&HelpBox, ID_BACK);
  495.             /* ------- display the help window ----- */
  496.             DialogBox(NULL, &HelpBox, TRUE, HelpBoxProc);
  497.             free(HelpBox.dwnd.title);
  498.             HelpBox.dwnd.title = NULL;
  499.             fclose(helpfp);
  500.             helpfp = NULL;
  501.             rtn = TRUE;
  502.         }
  503.     }
  504.     --wnd->isHelping;
  505.     return rtn;
  506. }
  507.  
  508. /* ------- display a definition window --------- */
  509. static void DisplayDefinition(WINDOW wnd, char *def)
  510. {
  511.     WINDOW dwnd;
  512.     WINDOW hwnd = wnd;
  513.     int y;
  514.     struct helps *HoldThisHelp;
  515.  
  516.     HoldThisHelp = ThisHelp;
  517.     if (GetClass(wnd) == POPDOWNMENU)
  518.         hwnd = GetParent(wnd);
  519.     y = GetClass(hwnd) == MENUBAR ? 2 : 1;
  520.     if ((ThisHelp = FindHelp(def)) != NULL)    {
  521.         dwnd = CreateWindow(
  522.                     TEXTBOX,
  523.                     NULL,
  524.                     GetClientLeft(hwnd),
  525.                     GetClientTop(hwnd)+y,
  526.                     min(ThisHelp->hheight, MAXHEIGHT)+3,
  527.                     ThisHelp->hwidth+2,
  528.                     NULL,
  529.                     wnd,
  530.                     NULL,
  531.                     HASBORDER | NOCLIP | SAVESELF);
  532.         if (dwnd != NULL)    {
  533.             clearBIOSbuffer();
  534.             /* ----- read the help text ------- */
  535.             SeekHelpLine(ThisHelp->hptr, ThisHelp->bit);
  536.             while (TRUE)    {
  537.                 clearBIOSbuffer();
  538.                 if (GetHelpLine(hline) == NULL)
  539.                     break;
  540.                 if (*hline == '<')
  541.                     break;
  542.                 hline[strlen(hline)-1] = '\0';
  543.                 SendMessage(dwnd,ADDTEXT,(PARAM)hline,0);
  544.             }
  545.             SendMessage(dwnd, SHOW_WINDOW, 0, 0);
  546.             SendMessage(NULL, WAITKEYBOARD, 0, 0);
  547.             SendMessage(NULL, WAITMOUSE, 0, 0);
  548.             SendMessage(dwnd, CLOSE_WINDOW, 0, 0);
  549.         }
  550.     }
  551.     ThisHelp = HoldThisHelp;
  552. }
  553.  
  554. /* ------ compare help names with wild cards ----- */
  555. static BOOL wildcmp(char *s1, char *s2)
  556. {
  557.     while (*s1 || *s2)    {
  558.         if (tolower(*s1) != tolower(*s2))
  559.             if (*s1 != '?' && *s2 != '?')
  560.                 return TRUE;
  561.         s1++, s2++;
  562.     }
  563.     return FALSE;
  564. }
  565.  
  566. /* --- ThisHelp = the help window matching specified name --- */
  567. static struct helps *FindHelp(char *Help)
  568. {
  569.     int i;
  570.     struct helps *thishelp = NULL;
  571.     for (i = 0; i < HelpCount; i++)    {
  572.         if (wildcmp(Help, (FirstHelp+i)->hname) == FALSE)    {
  573.             thishelp = FirstHelp+i;
  574.             break;
  575.         }
  576.     }
  577.     return thishelp;
  578. }
  579.  
  580. static int OverLap(int a, int b)
  581. {
  582.     int ov = a - b;
  583.     if (ov < 0)
  584.         ov = 0;
  585.     return ov;
  586. }
  587.  
  588. /* ----- compute the best location for a help dialogbox ----- */
  589. static void BestFit(WINDOW wnd, DIALOGWINDOW *dwnd)
  590. {
  591.     int above, below, right, left;
  592.     if (GetClass(wnd) == MENUBAR ||
  593.                 GetClass(wnd) == APPLICATION)    {
  594.         dwnd->x = dwnd->y = -1;
  595.         return;
  596.     }
  597.     /* --- compute above overlap ---- */
  598.     above = OverLap(dwnd->h, GetTop(wnd));
  599.     /* --- compute below overlap ---- */
  600.     below = OverLap(GetBottom(wnd), SCREENHEIGHT-dwnd->h);
  601.     /* --- compute right overlap ---- */
  602.     right = OverLap(GetRight(wnd), SCREENWIDTH-dwnd->w);
  603.     /* --- compute left  overlap ---- */
  604.     left = OverLap(dwnd->w, GetLeft(wnd));
  605.  
  606.     if (above < below)
  607.         dwnd->y = max(0, GetTop(wnd)-dwnd->h-2);
  608.     else
  609.         dwnd->y = min(SCREENHEIGHT-dwnd->h, GetBottom(wnd)+2);
  610.     if (right < left)
  611.         dwnd->x = min(GetRight(wnd)+2, SCREENWIDTH-dwnd->w);
  612.     else
  613.         dwnd->x = max(0, GetLeft(wnd)-dwnd->w-2);
  614.  
  615.     if (dwnd->x == GetRight(wnd)+2 ||
  616.             dwnd->x == GetLeft(wnd)-dwnd->w-2)
  617.         dwnd->y = -1;
  618.     if (dwnd->y ==GetTop(wnd)-dwnd->h-2 ||
  619.             dwnd->y == GetBottom(wnd)+2)
  620.         dwnd->x = -1;
  621. }
  622.  
  623. 
  624.