home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 24 / CD_ASCQ_24_0995.iso / vrac / dflt20.zip / NORMAL.C < prev    next >
Text File  |  1995-01-06  |  34KB  |  1,117 lines

  1. /* ------------- normal.c ------------ */
  2.  
  3. #include "dflat.h"
  4.  
  5. #ifdef INCLUDE_MULTI_WINDOWS
  6. static void near PaintOverLappers(WINDOW wnd);
  7. static void near PaintUnderLappers(WINDOW wnd);
  8. #endif
  9.  
  10. static BOOL InsideWindow(WINDOW, int, int);
  11. static void TerminateMoveSize(void);
  12. static void SaveBorder(RECT);
  13. static void RestoreBorder(RECT);
  14. static void GetVideoBuffer(WINDOW);
  15. static void PutVideoBuffer(WINDOW);
  16. #ifdef INCLUDE_MINIMIZE
  17. static RECT PositionIcon(WINDOW);
  18. #endif
  19. static void near dragborder(WINDOW, int, int);
  20. static void near sizeborder(WINDOW, int, int);
  21. static int px = -1, py = -1;
  22. static int diff;
  23. static struct window dwnd = {DUMMY, NULL, NormalProc,
  24.                                 {-1,-1,-1,-1}};
  25. static int *Bsave;
  26. static int Bht, Bwd;
  27. BOOL WindowMoving;
  28. BOOL WindowSizing;
  29. /* -------- array of class definitions -------- */
  30. CLASSDEFS classdefs[] = {
  31.     #undef ClassDef
  32.     #define ClassDef(c,b,p,a) {b,p,a},
  33.     #include "classes.h"
  34. };
  35. WINDOW HiddenWindow;
  36.  
  37. /* --------- CREATE_WINDOW Message ---------- */
  38. static void CreateWindowMsg(WINDOW wnd)
  39. {
  40.     AppendWindow(wnd);
  41.     if (!SendMessage(NULL, MOUSE_INSTALLED, 0, 0))
  42.         ClearAttribute(wnd, VSCROLLBAR | HSCROLLBAR);
  43.     if (TestAttribute(wnd, SAVESELF) && isVisible(wnd))
  44.         GetVideoBuffer(wnd);
  45. }
  46.  
  47. /* --------- SHOW_WINDOW Message ---------- */
  48. static void ShowWindowMsg(WINDOW wnd, PARAM p1, PARAM p2)
  49. {
  50.     if (GetParent(wnd) == NULL || isVisible(GetParent(wnd)))    {
  51.         WINDOW cwnd;
  52.         if (TestAttribute(wnd, SAVESELF) &&
  53.                         wnd->videosave == NULL)
  54.             GetVideoBuffer(wnd);
  55.         SetVisible(wnd);
  56.         SendMessage(wnd, PAINT, 0, TRUE);
  57.         SendMessage(wnd, BORDER, 0, 0);
  58.         /* --- show the children of this window --- */
  59.         cwnd = FirstWindow(wnd);
  60.         while (cwnd != NULL)    {
  61.             if (cwnd->condition != ISCLOSING)
  62.                 SendMessage(cwnd, SHOW_WINDOW, p1, p2);
  63.             cwnd = NextWindow(cwnd);
  64.         }
  65.     }
  66. }
  67.  
  68. /* --------- HIDE_WINDOW Message ---------- */
  69. static void HideWindowMsg(WINDOW wnd)
  70. {
  71.     if (isVisible(wnd))    {
  72.         ClearVisible(wnd);
  73.         /* --- paint what this window covered --- */
  74.         if (TestAttribute(wnd, SAVESELF))
  75.             PutVideoBuffer(wnd);
  76. #ifdef INCLUDE_MULTI_WINDOWS
  77.         else
  78.             PaintOverLappers(wnd);
  79. #endif
  80.         wnd->wasCleared = FALSE;
  81.     }
  82. }
  83.  
  84. /* --------- KEYBOARD Message ---------- */
  85. static BOOL KeyboardMsg(WINDOW wnd, PARAM p1, PARAM p2)
  86. {
  87.     if (WindowMoving || WindowSizing)    {
  88.         /* -- move or size a window with keyboard -- */
  89.         int x, y;
  90.         x=WindowMoving?GetLeft(&dwnd):GetRight(&dwnd);
  91.         y=WindowMoving?GetTop(&dwnd):GetBottom(&dwnd);
  92.         switch ((int)p1)    {
  93.             case ESC:
  94.                 TerminateMoveSize();
  95.                 return TRUE;
  96.             case UP:
  97.                 if (y)
  98.                     --y;
  99.                 break;
  100.             case DN:
  101.                 if (y < SCREENHEIGHT-1)
  102.                     y++;
  103.                 break;
  104.             case FWD:
  105.                 if (x < SCREENWIDTH-1)
  106.                     x++;
  107.                 break;
  108.             case BS:
  109.                 if (x)
  110.                     --x;
  111.                 break;
  112.             case '\r':
  113.                 SendMessage(wnd,BUTTON_RELEASED,x,y);
  114.             default:
  115.                 return TRUE;
  116.         }
  117.         /* -- use the mouse functions to move/size - */
  118.         SendMessage(wnd, MOUSE_CURSOR, x, y);
  119.         SendMessage(wnd, MOUSE_MOVED, x, y);
  120.         return TRUE;
  121.     }
  122.     switch ((int)p1)    {
  123.         case F1:
  124.             SendMessage(wnd, COMMAND, ID_HELP, 0);
  125.             return TRUE;
  126.         case ' ':
  127.             if ((int)p2 & ALTKEY)
  128.                 if (TestAttribute(wnd, HASTITLEBAR))
  129.                     if (TestAttribute(wnd, CONTROLBOX))
  130.                         BuildSystemMenu(wnd);
  131.             return TRUE;
  132.         case CTRL_F4:
  133.             if (TestAttribute(wnd, CONTROLBOX))    {
  134.                 SendMessage(wnd, CLOSE_WINDOW, 0, 0);
  135.                 SkipApplicationControls();
  136.                 return TRUE;
  137.             }
  138.             break;
  139.         default:
  140.             break;
  141.     }
  142.     return FALSE;
  143. }
  144.  
  145. /* --------- COMMAND Message ---------- */
  146. static void CommandMsg(WINDOW wnd, PARAM p1)
  147. {
  148.     switch ((int)p1)    {
  149.         case ID_HELP:
  150.             DisplayHelp(wnd,ClassNames[GetClass(wnd)]);
  151.             break;
  152. #ifdef INCLUDE_RESTORE
  153.         case ID_SYSRESTORE:
  154.             SendMessage(wnd, RESTORE, 0, 0);
  155.             break;
  156. #endif
  157.         case ID_SYSMOVE:
  158.             SendMessage(wnd, CAPTURE_MOUSE, TRUE,
  159.                 (PARAM) &dwnd);
  160.             SendMessage(wnd, CAPTURE_KEYBOARD, TRUE,
  161.                 (PARAM) &dwnd);
  162.             SendMessage(wnd, MOUSE_CURSOR,
  163.                 GetLeft(wnd), GetTop(wnd));
  164.             WindowMoving = TRUE;
  165.             dragborder(wnd, GetLeft(wnd), GetTop(wnd));
  166.             break;
  167.         case ID_SYSSIZE:
  168.             SendMessage(wnd, CAPTURE_MOUSE, TRUE,
  169.                 (PARAM) &dwnd);
  170.             SendMessage(wnd, CAPTURE_KEYBOARD, TRUE,
  171.                 (PARAM) &dwnd);
  172.             SendMessage(wnd, MOUSE_CURSOR,
  173.                 GetRight(wnd), GetBottom(wnd));
  174.             WindowSizing = TRUE;
  175.             dragborder(wnd, GetLeft(wnd), GetTop(wnd));
  176.             break;
  177. #ifdef INCLUDE_MINIMIZE
  178.         case ID_SYSMINIMIZE:
  179.             SendMessage(wnd, MINIMIZE, 0, 0);
  180.             break;
  181. #endif
  182. #ifdef INCLUDE_MAXIMIZE
  183.         case ID_SYSMAXIMIZE:
  184.             SendMessage(wnd, MAXIMIZE, 0, 0);
  185.             break;
  186. #endif
  187.         case ID_SYSCLOSE:
  188.             SendMessage(wnd, CLOSE_WINDOW, 0, 0);
  189.             SkipApplicationControls();
  190.             break;
  191.         default:
  192.             break;
  193.     }
  194. }
  195.  
  196. /* --------- SETFOCUS Message ---------- */
  197. static void SetFocusMsg(WINDOW wnd, PARAM p1)
  198. {
  199.     RECT rc = {0,0,0,0};
  200.     if (p1 && wnd != NULL && inFocus != wnd)    {
  201.         WINDOW This, thispar;
  202.         WINDOW that = NULL, thatpar = NULL;
  203.  
  204.         WINDOW cwnd = wnd, fwnd = GetParent(wnd);
  205.         /* ---- post focus in ancestors ---- */
  206.         while (fwnd != NULL)    {
  207.             fwnd->childfocus = cwnd;
  208.             cwnd = fwnd;
  209.             fwnd = GetParent(fwnd);
  210.         }
  211.         /* ---- de-post focus in self and children ---- */
  212.         fwnd = wnd;
  213.         while (fwnd != NULL)    {
  214.             cwnd = fwnd->childfocus;
  215.             fwnd->childfocus = NULL;
  216.             fwnd = cwnd;
  217.         }
  218.  
  219.         This = wnd;
  220.         that = thatpar = inFocus;
  221.  
  222.         /* ---- find common ancestor of prev focus and this window --- */
  223.         while (thatpar != NULL)    {
  224.             thispar = wnd;
  225.             while (thispar != NULL)    {
  226.                 if (This == CaptureMouse || This == CaptureKeyboard)    {
  227.                     /* ---- don't repaint if this window has capture ---- */
  228.                     that = thatpar = NULL;
  229.                     break;
  230.                 }
  231.                 if (thispar == thatpar)    {
  232.                     /* ---- don't repaint if SAVESELF window had focus ---- */
  233.                     if (This != that && TestAttribute(that, SAVESELF))
  234.                         that = thatpar = NULL;
  235.                     break;
  236.                 }
  237.                 This = thispar;
  238.                 thispar = GetParent(thispar);
  239.             }
  240.             if (thispar != NULL)
  241.                 break;
  242.             that = thatpar;
  243.             thatpar = GetParent(thatpar);
  244.         }
  245.         if (inFocus != NULL)
  246.             SendMessage(inFocus, SETFOCUS, FALSE, 0);
  247.         inFocus = wnd;
  248.         if (that != NULL && isVisible(wnd))    {
  249.             rc = subRectangle(WindowRect(that), WindowRect(This));
  250.             if (!ValidRect(rc))    {
  251.                 if (ApplicationWindow != NULL)    {
  252.                     WINDOW fwnd = FirstWindow(ApplicationWindow);
  253.                     while (fwnd != NULL)    {
  254.                         if (!isAncestor(wnd, fwnd))    {
  255.                             rc = subRectangle(WindowRect(wnd),WindowRect(fwnd));
  256.                             if (ValidRect(rc))
  257.                                 break;
  258.                         }
  259.                         fwnd = NextWindow(fwnd);
  260.                     }
  261.                 }
  262.             }
  263.         }
  264.         if (that != NULL && !ValidRect(rc) && isVisible(wnd))
  265.             This = NULL;
  266.         ReFocus(wnd);
  267.         if (This != NULL &&
  268.                 (!isVisible(This) || !TestAttribute(This, SAVESELF)))    {
  269.             wnd->wasCleared = FALSE;
  270.             SendMessage(This, SHOW_WINDOW, 0, 0);
  271.         }
  272.         else if (!isVisible(wnd))
  273.             SendMessage(wnd, SHOW_WINDOW, 0, 0);
  274.         else 
  275.             SendMessage(wnd, BORDER, 0, 0);
  276.     }
  277.     else if (!p1 && inFocus == wnd)    {
  278.         /* -------- clearing focus --------- */
  279.         inFocus = NULL;
  280.         SendMessage(wnd, BORDER, 0, 0);
  281.     }
  282. }
  283.  
  284. /* --------- DOUBLE_CLICK Message ---------- */
  285. static void DoubleClickMsg(WINDOW wnd, PARAM p1, PARAM p2)
  286. {
  287.     int mx = (int) p1 - GetLeft(wnd);
  288.     int my = (int) p2 - GetTop(wnd);
  289.     if (!WindowSizing && !WindowMoving)    {
  290.         if (HitControlBox(wnd, mx, my))    {
  291.             PostMessage(wnd, CLOSE_WINDOW, 0, 0);
  292.             SkipApplicationControls();
  293.         }
  294.     }
  295. }
  296.  
  297. /* --------- LEFT_BUTTON Message ---------- */
  298. static void LeftButtonMsg(WINDOW wnd, PARAM p1, PARAM p2)
  299. {
  300.     int mx = (int) p1 - GetLeft(wnd);
  301.     int my = (int) p2 - GetTop(wnd);
  302.     if (WindowSizing || WindowMoving)
  303.         return;
  304.     if (HitControlBox(wnd, mx, my))    {
  305.         BuildSystemMenu(wnd);
  306.         return;
  307.     }
  308.     if (my == 0 && mx > -1 && mx < WindowWidth(wnd))  {
  309.         /* ---------- hit the top border -------- */
  310.         if (TestAttribute(wnd, MINMAXBOX) &&
  311.                 TestAttribute(wnd, HASTITLEBAR))  {
  312.             if (mx == WindowWidth(wnd)-2)    {
  313.                 if (wnd->condition != ISRESTORED)
  314.                     /* --- hit the restore box --- */
  315.                     SendMessage(wnd, RESTORE, 0, 0);
  316. #ifdef INCLUDE_MAXIMIZE
  317.                 else
  318.                     /* --- hit the maximize box --- */
  319.                     SendMessage(wnd, MAXIMIZE, 0, 0);
  320. #endif
  321.                 return;
  322.             }
  323. #ifdef INCLUDE_MINIMIZE
  324.             if (mx == WindowWidth(wnd)-3)    {
  325.                 /* --- hit the minimize box --- */
  326.                 if (wnd->condition != ISMINIMIZED)
  327.                     SendMessage(wnd, MINIMIZE, 0, 0);
  328.                 return;
  329.             }
  330. #endif
  331.         }
  332. #ifdef INCLUDE_MAXIMIZE
  333.         if (wnd->condition == ISMAXIMIZED)
  334.             return;
  335. #endif
  336.         if (TestAttribute(wnd, MOVEABLE))    {
  337.             WindowMoving = TRUE;
  338.             px = mx;
  339.             py = my;
  340.             diff = (int) mx;
  341.             SendMessage(wnd, CAPTURE_MOUSE, TRUE,
  342.                 (PARAM) &dwnd);
  343.             dragborder(wnd, GetLeft(wnd), GetTop(wnd));
  344.         }
  345.         return;
  346.     }
  347.     if (mx == WindowWidth(wnd)-1 &&
  348.             my == WindowHeight(wnd)-1)    {
  349.         /* ------- hit the resize corner ------- */
  350. #ifdef INCLUDE_MINIMIZE
  351.         if (wnd->condition == ISMINIMIZED)
  352.             return;
  353. #endif
  354.         if (!TestAttribute(wnd, SIZEABLE))
  355.             return;
  356. #ifdef INCLUDE_MAXIMIZE
  357.         if (wnd->condition == ISMAXIMIZED)    {
  358.             if (GetParent(wnd) == NULL)
  359.                 return;
  360.             if (TestAttribute(GetParent(wnd),HASBORDER))
  361.                 return;
  362.             /* ----- resizing a maximized window over a
  363.                     borderless parent ----- */
  364.             wnd = GetParent(wnd);
  365.             if (!TestAttribute(wnd, SIZEABLE))
  366.                 return;
  367.         }
  368. #endif
  369.         WindowSizing = TRUE;
  370.         SendMessage(wnd, CAPTURE_MOUSE,
  371.             TRUE, (PARAM) &dwnd);
  372.         dragborder(wnd, GetLeft(wnd), GetTop(wnd));
  373.     }
  374. }
  375.  
  376. /* --------- MOUSE_MOVED Message ---------- */
  377. static BOOL MouseMovedMsg(WINDOW wnd, PARAM p1, PARAM p2)
  378. {
  379.     if (WindowMoving)    {
  380.         int leftmost = 0, topmost = 0,
  381.             bottommost = SCREENHEIGHT-2,
  382.             rightmost = SCREENWIDTH-2;
  383.         int x = (int) p1 - diff;
  384.         int y = (int) p2;
  385.         if (GetParent(wnd) != NULL &&
  386.                 !TestAttribute(wnd, NOCLIP))    {
  387.             WINDOW wnd1 = GetParent(wnd);
  388.             topmost    = GetClientTop(wnd1);
  389.             leftmost   = GetClientLeft(wnd1);
  390.             bottommost = GetClientBottom(wnd1);
  391.             rightmost  = GetClientRight(wnd1);
  392.         }
  393.         if (x < leftmost || x > rightmost ||
  394.                 y < topmost || y > bottommost)    {
  395.             x = max(x, leftmost);
  396.             x = min(x, rightmost);
  397.             y = max(y, topmost);
  398.             y = min(y, bottommost);
  399.             SendMessage(NULL,MOUSE_CURSOR,x+diff,y);
  400.         }
  401.         if (x != px || y != py)    {
  402.             px = x;
  403.             py = y;
  404.             dragborder(wnd, x, y);
  405.         }
  406.         return TRUE;
  407.     }
  408.     if (WindowSizing)    {
  409.         sizeborder(wnd, (int) p1, (int) p2);
  410.         return TRUE;
  411.     }
  412.     return FALSE;
  413. }
  414.  
  415. #ifdef INCLUDE_MAXIMIZE
  416. /* --------- MAXIMIZE Message ---------- */
  417. static void MaximizeMsg(WINDOW wnd)
  418. {
  419.     RECT rc = {0, 0, 0, 0};
  420.     RECT holdrc;
  421.     holdrc = wnd->RestoredRC;
  422.     rc.rt = SCREENWIDTH-1;
  423.     rc.bt = SCREENHEIGHT-1;
  424.     if (GetParent(wnd))
  425.         rc = ClientRect(GetParent(wnd));
  426.     wnd->oldcondition = wnd->condition;
  427.     wnd->condition = ISMAXIMIZED;
  428.     wnd->wasCleared = FALSE;
  429.     SendMessage(wnd, HIDE_WINDOW, 0, 0);
  430.     SendMessage(wnd, MOVE,
  431.         RectLeft(rc), RectTop(rc));
  432.     SendMessage(wnd, SIZE,
  433.         RectRight(rc), RectBottom(rc));
  434.     if (wnd->restored_attrib == 0)
  435.         wnd->restored_attrib = wnd->attrib;
  436.     ClearAttribute(wnd, SHADOW);
  437.     SendMessage(wnd, SHOW_WINDOW, 0, 0);
  438.     wnd->RestoredRC = holdrc;
  439. }
  440. #endif
  441.  
  442. #ifdef INCLUDE_MINIMIZE
  443. /* --------- MINIMIZE Message ---------- */
  444. static void MinimizeMsg(WINDOW wnd)
  445. {
  446.     RECT rc;
  447.     RECT holdrc;
  448.  
  449.     holdrc = wnd->RestoredRC;
  450.     rc = PositionIcon(wnd);
  451.     wnd->oldcondition = wnd->condition;
  452.     wnd->condition = ISMINIMIZED;
  453.     wnd->wasCleared = FALSE;
  454.     SendMessage(wnd, HIDE_WINDOW, 0, 0);
  455.     SendMessage(wnd, MOVE,
  456.         RectLeft(rc), RectTop(rc));
  457.     SendMessage(wnd, SIZE,
  458.         RectRight(rc), RectBottom(rc));
  459.     if (wnd == inFocus)
  460.         SetNextFocus();
  461.     if (wnd->restored_attrib == 0)
  462.         wnd->restored_attrib = wnd->attrib;
  463.     ClearAttribute(wnd,
  464.         SHADOW | SIZEABLE | HASMENUBAR |
  465.         VSCROLLBAR | HSCROLLBAR);
  466.     SendMessage(wnd, SHOW_WINDOW, 0, 0);
  467.     wnd->RestoredRC = holdrc;
  468. }
  469. #endif
  470.  
  471. #ifdef INCLUDE_RESTORE
  472. /* --------- RESTORE Message ---------- */
  473. static void RestoreMsg(WINDOW wnd)
  474. {
  475.     RECT holdrc;
  476.     holdrc = wnd->RestoredRC;
  477.     wnd->oldcondition = wnd->condition;
  478.     wnd->condition = ISRESTORED;
  479.     wnd->wasCleared = FALSE;
  480.     SendMessage(wnd, HIDE_WINDOW, 0, 0);
  481.     wnd->attrib = wnd->restored_attrib;
  482.     wnd->restored_attrib = 0;
  483.     SendMessage(wnd, MOVE, wnd->RestoredRC.lf,
  484.         wnd->RestoredRC.tp);
  485.     wnd->RestoredRC = holdrc;
  486.     SendMessage(wnd, SIZE, wnd->RestoredRC.rt,
  487.         wnd->RestoredRC.bt);
  488.     if (wnd != inFocus)
  489.         SendMessage(wnd, SETFOCUS, TRUE, 0);
  490.     else
  491.         SendMessage(wnd, SHOW_WINDOW, 0, 0);
  492. }
  493. #endif
  494.  
  495. /* --------- MOVE Message ---------- */
  496. static void MoveMsg(WINDOW wnd, PARAM p1, PARAM p2)
  497. {
  498.     WINDOW cwnd;
  499.     BOOL wasVisible = isVisible(wnd);
  500.     int xdif = (int) p1 - wnd->rc.lf;
  501.     int ydif = (int) p2 - wnd->rc.tp;
  502.  
  503.     if (xdif == 0 && ydif == 0)
  504.         return;
  505.     wnd->wasCleared = FALSE;
  506.     if (wasVisible)
  507.         SendMessage(wnd, HIDE_WINDOW, 0, 0);
  508.     wnd->rc.lf = (int) p1;
  509.     wnd->rc.tp = (int) p2;
  510.     wnd->rc.rt = GetLeft(wnd)+WindowWidth(wnd)-1;
  511.     wnd->rc.bt = GetTop(wnd)+WindowHeight(wnd)-1;
  512.     if (wnd->condition == ISRESTORED)
  513.         wnd->RestoredRC = wnd->rc;
  514.  
  515.     cwnd = FirstWindow(wnd);
  516.     while (cwnd != NULL)    {
  517.         SendMessage(cwnd, MOVE, cwnd->rc.lf+xdif, cwnd->rc.tp+ydif);
  518.         cwnd = NextWindow(cwnd);
  519.     }
  520.     if (wasVisible)
  521.         SendMessage(wnd, SHOW_WINDOW, 0, 0);
  522. }
  523.  
  524. /* --------- SIZE Message ---------- */
  525. static void SizeMsg(WINDOW wnd, PARAM p1, PARAM p2)
  526. {
  527.     BOOL wasVisible = isVisible(wnd);
  528.     WINDOW cwnd;
  529.     RECT rc;
  530.     int xdif = (int) p1 - wnd->rc.rt;
  531.     int ydif = (int) p2 - wnd->rc.bt;
  532.  
  533.     if (xdif == 0 && ydif == 0)
  534.         return;
  535.     wnd->wasCleared = FALSE;
  536.     if (wasVisible)
  537.         SendMessage(wnd, HIDE_WINDOW, 0, 0);
  538.     wnd->rc.rt = (int) p1;
  539.     wnd->rc.bt = (int) p2;
  540.     wnd->ht = GetBottom(wnd)-GetTop(wnd)+1;
  541.     wnd->wd = GetRight(wnd)-GetLeft(wnd)+1;
  542.  
  543.     if (wnd->condition == ISRESTORED)
  544.         wnd->RestoredRC = WindowRect(wnd);
  545.  
  546. #ifdef INCLUDE_MAXIMIZE
  547.     rc = ClientRect(wnd);
  548.  
  549.     cwnd = FirstWindow(wnd);
  550.     while (cwnd != NULL)    {
  551.         if (cwnd->condition == ISMAXIMIZED)
  552.             SendMessage(cwnd, SIZE, RectRight(rc), RectBottom(rc));
  553.         cwnd = NextWindow(cwnd);
  554.     }
  555.  
  556. #endif
  557.     if (wasVisible)
  558.         SendMessage(wnd, SHOW_WINDOW, 0, 0);
  559. }
  560.  
  561. /* --------- CLOSE_WINDOW Message ---------- */
  562. static void CloseWindowMsg(WINDOW wnd)
  563. {
  564.     WINDOW cwnd;
  565.     wnd->condition = ISCLOSING;
  566.     /* ----------- hide this window ------------ */
  567.     SendMessage(wnd, HIDE_WINDOW, 0, 0);
  568.  
  569.     /* --- close the children of this window --- */
  570.     cwnd = LastWindow(wnd);
  571.     while (cwnd != NULL)    {
  572.         if (inFocus == cwnd)
  573.             inFocus = wnd;
  574.         SendMessage(cwnd,CLOSE_WINDOW,0,0);
  575.         cwnd = LastWindow(wnd);
  576.     }
  577.  
  578.     /* ----- release captured resources ------ */
  579.     if (wnd->PrevClock != NULL)
  580.         SendMessage(wnd, RELEASE_CLOCK, 0, 0);
  581.     if (wnd->PrevMouse != NULL)
  582.         SendMessage(wnd, RELEASE_MOUSE, 0, 0);
  583.     if (wnd->PrevKeyboard != NULL)
  584.         SendMessage(wnd, RELEASE_KEYBOARD, 0, 0);
  585.  
  586.     /* --- change focus if this window had it -- */
  587.     if (wnd == inFocus)
  588.         SetPrevFocus();
  589.     /* -- free memory allocated to this window - */
  590.     if (wnd->title != NULL)
  591.         free(wnd->title);
  592.     if (wnd->videosave != NULL)
  593.         free(wnd->videosave);
  594.     /* -- remove window from parent's list of children -- */
  595.     RemoveWindow(wnd);
  596.     if (wnd == inFocus)
  597.         inFocus = NULL;
  598.     free(wnd);
  599. }
  600.  
  601. /* ---- Window-processing module for NORMAL window class ---- */
  602. int NormalProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  603. {
  604.     switch (msg)    {
  605.         case CREATE_WINDOW:
  606.             CreateWindowMsg(wnd);
  607.             break;
  608.         case SHOW_WINDOW:
  609.             ShowWindowMsg(wnd, p1, p2);
  610.             break;
  611.         case HIDE_WINDOW:
  612.             HideWindowMsg(wnd);
  613.             break;
  614.         case DISPLAY_HELP:
  615.             return DisplayHelp(wnd, (char *)p1);
  616.         case INSIDE_WINDOW:
  617.             return InsideWindow(wnd, (int) p1, (int) p2);
  618.         case KEYBOARD:
  619.             if (KeyboardMsg(wnd, p1, p2))
  620.                 return TRUE;
  621.             /* ------- fall through ------- */
  622.         case ADDSTATUS:
  623.         case SHIFT_CHANGED:
  624.             if (GetParent(wnd) != NULL)
  625.                 PostMessage(GetParent(wnd), msg, p1, p2);
  626.             break;
  627.         case PAINT:
  628.             if (isVisible(wnd))    {
  629. #ifdef INCLUDE_MULTI_WINDOWS
  630.                 if (wnd->wasCleared)
  631.                     PaintUnderLappers(wnd);
  632.                 else
  633. #endif
  634.                 {
  635.                     wnd->wasCleared = TRUE;
  636.                     ClearWindow(wnd, (RECT *)p1, ' ');
  637.                 }
  638.             }
  639.             break;
  640.         case BORDER:
  641.             if (isVisible(wnd))    {
  642.                 if (TestAttribute(wnd, HASBORDER))
  643.                     RepaintBorder(wnd, (RECT *)p1);
  644.                 else if (TestAttribute(wnd, HASTITLEBAR))
  645.                     DisplayTitle(wnd, (RECT *)p1);
  646.             }
  647.             break;
  648.         case COMMAND:
  649.             CommandMsg(wnd, p1);
  650.             break;
  651.         case SETFOCUS:
  652.             SetFocusMsg(wnd, p1);
  653.             break;
  654.         case DOUBLE_CLICK:
  655.             DoubleClickMsg(wnd, p1, p2);
  656.             break;
  657.         case LEFT_BUTTON:
  658.             LeftButtonMsg(wnd, p1, p2);
  659.             break;
  660.         case MOUSE_MOVED:
  661.             if (MouseMovedMsg(wnd, p1, p2))
  662.                 return TRUE;
  663.             break;
  664.         case BUTTON_RELEASED:
  665.             if (WindowMoving || WindowSizing)    {
  666.                 if (WindowMoving)
  667.                     PostMessage(wnd,MOVE,dwnd.rc.lf,dwnd.rc.tp);
  668.                 else
  669.                     PostMessage(wnd,SIZE,dwnd.rc.rt,dwnd.rc.bt);
  670.                 TerminateMoveSize();
  671.             }
  672.             break;
  673. #ifdef INCLUDE_MAXIMIZE
  674.         case MAXIMIZE:
  675.             if (wnd->condition != ISMAXIMIZED)
  676.                 MaximizeMsg(wnd);
  677.             break;
  678. #endif
  679. #ifdef INCLUDE_MINIMIZE
  680.         case MINIMIZE:
  681.             if (wnd->condition != ISMINIMIZED)
  682.                 MinimizeMsg(wnd);
  683.             break;
  684. #endif
  685. #ifdef INCLUDE_RESTORE
  686.         case RESTORE:
  687.             if (wnd->condition != ISRESTORED)    {
  688. #ifdef INCLUDE_MAXIMIZE
  689.                 if (wnd->oldcondition == ISMAXIMIZED)
  690.                     SendMessage(wnd, MAXIMIZE, 0, 0);
  691.                 else
  692. #endif
  693.                     RestoreMsg(wnd);
  694.             }
  695.             break;
  696. #endif
  697.         case MOVE:
  698.             MoveMsg(wnd, p1, p2);
  699.             break;
  700.         case SIZE:    {
  701.             SizeMsg(wnd, p1, p2);
  702.             break;
  703.         }
  704.         case CLOSE_WINDOW:
  705.             CloseWindowMsg(wnd);
  706.             break;
  707.         default:
  708.             break;
  709.     }
  710.     return TRUE;
  711. }
  712. #ifdef INCLUDE_MINIMIZE
  713. /* ---- compute lower right icon space in a rectangle ---- */
  714. static RECT LowerRight(RECT prc)
  715. {
  716.     RECT rc;
  717.     RectLeft(rc) = RectRight(prc) - ICONWIDTH;
  718.     RectTop(rc) = RectBottom(prc) - ICONHEIGHT;
  719.     RectRight(rc) = RectLeft(rc)+ICONWIDTH-1;
  720.     RectBottom(rc) = RectTop(rc)+ICONHEIGHT-1;
  721.     return rc;
  722. }
  723. /* ----- compute a position for a minimized window icon ---- */
  724. static RECT PositionIcon(WINDOW wnd)
  725. {
  726.     WINDOW pwnd = GetParent(wnd);
  727.     RECT rc;
  728.     RectLeft(rc) = SCREENWIDTH-ICONWIDTH;
  729.     RectTop(rc) = SCREENHEIGHT-ICONHEIGHT;
  730.     RectRight(rc) = SCREENWIDTH-1;
  731.     RectBottom(rc) = SCREENHEIGHT-1;
  732.     if (pwnd != NULL)    {
  733.         RECT prc = WindowRect(pwnd);
  734.         WINDOW cwnd = FirstWindow(pwnd);
  735.         rc = LowerRight(prc);
  736.         /* - search for icon available location - */
  737.         while (cwnd != NULL)    {
  738.             if (cwnd->condition == ISMINIMIZED)    {
  739.                 RECT rc1;
  740.                 rc1 = WindowRect(cwnd);
  741.                 if (RectLeft(rc1) == RectLeft(rc) &&
  742.                         RectTop(rc1) == RectTop(rc))    {
  743.                     RectLeft(rc) -= ICONWIDTH;
  744.                     RectRight(rc) -= ICONWIDTH;
  745.                     if (RectLeft(rc) < RectLeft(prc)+1)   {
  746.                         RectLeft(rc) =
  747.                             RectRight(prc)-ICONWIDTH;
  748.                         RectRight(rc) =
  749.                             RectLeft(rc)+ICONWIDTH-1;
  750.                         RectTop(rc) -= ICONHEIGHT;
  751.                         RectBottom(rc) -= ICONHEIGHT;
  752.                         if (RectTop(rc) < RectTop(prc)+1)
  753.                             return LowerRight(prc);
  754.                     }
  755.                     break;
  756.                 }
  757.             }
  758.             cwnd = NextWindow(cwnd);
  759.         }
  760.     }
  761.     return rc;
  762. }
  763. #endif
  764. /* ----- terminate the move or size operation ----- */
  765. static void TerminateMoveSize(void)
  766. {
  767.     px = py = -1;
  768.     diff = 0;
  769.     SendMessage(&dwnd, RELEASE_MOUSE, TRUE, 0);
  770.     SendMessage(&dwnd, RELEASE_KEYBOARD, TRUE, 0);
  771.     RestoreBorder(dwnd.rc);
  772.     WindowMoving = WindowSizing = FALSE;
  773. }
  774. /* ---- build a dummy window border for moving or sizing --- */
  775. static void near dragborder(WINDOW wnd, int x, int y)
  776. {
  777.     RestoreBorder(dwnd.rc);
  778.     /* ------- build the dummy window -------- */
  779.     dwnd.rc.lf = x;
  780.     dwnd.rc.tp = y;
  781.     dwnd.rc.rt = dwnd.rc.lf+WindowWidth(wnd)-1;
  782.     dwnd.rc.bt = dwnd.rc.tp+WindowHeight(wnd)-1;
  783.     dwnd.ht = WindowHeight(wnd);
  784.     dwnd.wd = WindowWidth(wnd);
  785.     dwnd.parent = GetParent(wnd);
  786.     dwnd.attrib = VISIBLE | HASBORDER | NOCLIP;
  787.     InitWindowColors(&dwnd);
  788.     SaveBorder(dwnd.rc);
  789.     RepaintBorder(&dwnd, NULL);
  790. }
  791. /* ---- write the dummy window border for sizing ---- */
  792. static void near sizeborder(WINDOW wnd, int rt, int bt)
  793. {
  794.     int leftmost = GetLeft(wnd)+10;
  795.     int topmost = GetTop(wnd)+3;
  796.     int bottommost = SCREENHEIGHT-1;
  797.     int rightmost  = SCREENWIDTH-1;
  798.     if (GetParent(wnd))    {
  799.         bottommost = min(bottommost,
  800.             GetClientBottom(GetParent(wnd)));
  801.         rightmost  = min(rightmost,
  802.             GetClientRight(GetParent(wnd)));
  803.     }
  804.     rt = min(rt, rightmost);
  805.     bt = min(bt, bottommost);
  806.     rt = max(rt, leftmost);
  807.     bt = max(bt, topmost);
  808.     SendMessage(NULL, MOUSE_CURSOR, rt, bt);
  809.  
  810.     if (rt != px || bt != py)
  811.         RestoreBorder(dwnd.rc);
  812.  
  813.     /* ------- change the dummy window -------- */
  814.     dwnd.ht = bt-dwnd.rc.tp+1;
  815.     dwnd.wd = rt-dwnd.rc.lf+1;
  816.     dwnd.rc.rt = rt;
  817.     dwnd.rc.bt = bt;
  818.     if (rt != px || bt != py)    {
  819.         px = rt;
  820.         py = bt;
  821.         SaveBorder(dwnd.rc);
  822.         RepaintBorder(&dwnd, NULL);
  823.     }
  824. }
  825. #ifdef INCLUDE_MULTI_WINDOWS
  826. /* ----- adjust a rectangle to include the shadow ----- */
  827. static RECT adjShadow(WINDOW wnd)
  828. {
  829.     RECT rc;
  830.     rc = wnd->rc;
  831.     if (TestAttribute(wnd, SHADOW))    {
  832.         if (RectRight(rc) < SCREENWIDTH-1)
  833.             RectRight(rc)++;           
  834.         if (RectBottom(rc) < SCREENHEIGHT-1)
  835.             RectBottom(rc)++;
  836.     }
  837.     return rc;
  838. }
  839. /* --- repaint a rectangular subsection of a window --- */
  840. static void near PaintOverLap(WINDOW wnd, RECT rc)
  841. {
  842.     if (isVisible(wnd))    {
  843.         int isBorder, isTitle, isData;
  844.         isBorder = isTitle = FALSE;
  845.         isData = TRUE;
  846.         if (TestAttribute(wnd, HASBORDER))    {
  847.             isBorder =  RectLeft(rc) == 0 &&
  848.                         RectTop(rc) < WindowHeight(wnd);
  849.             isBorder |= RectLeft(rc) < WindowWidth(wnd) &&
  850.                         RectRight(rc) >= WindowWidth(wnd)-1 &&
  851.                         RectTop(rc) < WindowHeight(wnd);
  852.             isBorder |= RectTop(rc) == 0 &&
  853.                         RectLeft(rc) < WindowWidth(wnd);
  854.             isBorder |= RectTop(rc) < WindowHeight(wnd) &&
  855.                         RectBottom(rc) >= WindowHeight(wnd)-1 &&
  856.                         RectLeft(rc) < WindowWidth(wnd);
  857.         }
  858.         else if (TestAttribute(wnd, HASTITLEBAR))
  859.             isTitle = RectTop(rc) == 0 &&
  860.                       RectRight(rc) > 0 &&
  861.                       RectLeft(rc)<WindowWidth(wnd)-BorderAdj(wnd);
  862.  
  863.         if (RectLeft(rc) >= WindowWidth(wnd)-BorderAdj(wnd))
  864.             isData = FALSE;
  865.         if (RectTop(rc) >= WindowHeight(wnd)-BottomBorderAdj(wnd))
  866.             isData = FALSE;
  867.         if (TestAttribute(wnd, HASBORDER))    {
  868.             if (RectRight(rc) == 0)
  869.                 isData = FALSE;
  870.             if (RectBottom(rc) == 0)
  871.                 isData = FALSE;
  872.         }
  873.         if (TestAttribute(wnd, SHADOW))
  874.             isBorder |= RectRight(rc) == WindowWidth(wnd) ||
  875.                         RectBottom(rc) == WindowHeight(wnd);
  876.         if (isData)    {
  877.             wnd->wasCleared = FALSE;
  878.             SendMessage(wnd, PAINT, (PARAM) &rc, TRUE);
  879.         }
  880.         if (isBorder)
  881.             SendMessage(wnd, BORDER, (PARAM) &rc, 0);
  882.         else if (isTitle)
  883.             DisplayTitle(wnd, &rc);
  884.     }
  885. }
  886. /* ------ paint the part of a window that is overlapped
  887.             by another window that is being hidden ------- */
  888. static void PaintOver(WINDOW wnd)
  889. {
  890.     RECT wrc, rc;
  891.     wrc = adjShadow(HiddenWindow);
  892.     rc = adjShadow(wnd);
  893.     rc = subRectangle(rc, wrc);
  894.     if (ValidRect(rc))
  895.         PaintOverLap(wnd, RelativeWindowRect(wnd, rc));
  896. }
  897. /* --- paint the overlapped parts of all children --- */
  898. static void PaintOverChildren(WINDOW pwnd)
  899. {
  900.     WINDOW cwnd = FirstWindow(pwnd);
  901.     while (cwnd != NULL)    {
  902.         if (cwnd != HiddenWindow)    {
  903.             PaintOver(cwnd);
  904.             PaintOverChildren(cwnd);
  905.         }
  906.         cwnd = NextWindow(cwnd);
  907.     }
  908. }
  909. /* -- recursive overlapping paint of parents -- */
  910. static void PaintOverParents(WINDOW wnd)
  911. {
  912.     WINDOW pwnd = GetParent(wnd);
  913.     if (pwnd != NULL)    {
  914.         PaintOverParents(pwnd);
  915.         PaintOver(pwnd);
  916.         PaintOverChildren(pwnd);
  917.     }
  918. }
  919. /* - paint the parts of all windows that a window is over - */
  920. static void near PaintOverLappers(WINDOW wnd)
  921. {
  922.     HiddenWindow = wnd;
  923.     PaintOverParents(wnd);
  924. }
  925. /* --- paint those parts of a window that are overlapped --- */
  926. static void near PaintUnderLappers(WINDOW wnd)
  927. {
  928.     WINDOW hwnd = NextWindow(wnd);
  929.     while (hwnd != NULL)    {
  930.         /* ------- test only at document window level ------ */
  931.         WINDOW pwnd = GetParent(hwnd);
  932. /*        if (pwnd == NULL || GetClass(pwnd) == APPLICATION)  */  {
  933.             /* ---- don't bother testing self ----- */
  934.             if (isVisible(hwnd) && hwnd != wnd)    {
  935.                 /* --- see if other window is descendent --- */
  936.                 while (pwnd != NULL)    {
  937.                     if (pwnd == wnd)
  938.                         break;
  939.                     pwnd = GetParent(pwnd);
  940.                 }
  941.                 /* ----- don't test descendent overlaps ----- */
  942.                 if (pwnd == NULL)    {
  943.                     /* -- see if other window is ancestor --- */
  944.                     pwnd = GetParent(wnd);
  945.                     while (pwnd != NULL)    {
  946.                         if (pwnd == hwnd)
  947.                             break;
  948.                         pwnd = GetParent(pwnd);
  949.                     }
  950.                     /* --- don't test ancestor overlaps --- */
  951.                     if (pwnd == NULL)    {
  952.                         HiddenWindow = GetAncestor(hwnd);
  953.                         ClearVisible(HiddenWindow);
  954.                         PaintOver(wnd);
  955.                         SetVisible(HiddenWindow);
  956.                     }
  957.                 }
  958.             }
  959.         }
  960.         hwnd = NextWindow(hwnd);
  961.     }
  962.     /* --------- repaint all children of this window
  963.         the same way ----------- */
  964.     hwnd = FirstWindow(wnd);
  965.     while (hwnd != NULL)    {
  966.         PaintUnderLappers(hwnd);
  967.         hwnd = NextWindow(hwnd);
  968.     }
  969. }
  970. #endif /* #ifdef INCLUDE_MULTI_WINDOWS */
  971.  
  972. /* --- save video area to be used by dummy window border --- */
  973. static void SaveBorder(RECT rc)
  974. {
  975.     RECT lrc;
  976.     int i;
  977.     int *cp;
  978.     Bht = RectBottom(rc) - RectTop(rc) + 1;
  979.     Bwd = RectRight(rc) - RectLeft(rc) + 1;
  980.     Bsave = DFrealloc(Bsave, (Bht + Bwd) * 4);
  981.  
  982.     lrc = rc;
  983.     RectBottom(lrc) = RectTop(lrc);
  984.     getvideo(lrc, Bsave);
  985.     RectTop(lrc) = RectBottom(lrc) = RectBottom(rc);
  986.     getvideo(lrc, Bsave + Bwd);
  987.     cp = Bsave + Bwd * 2;
  988.     for (i = 1; i < Bht-1; i++)    {
  989.         *cp++ = GetVideoChar(RectLeft(rc),RectTop(rc)+i);
  990.         *cp++ = GetVideoChar(RectRight(rc),RectTop(rc)+i);
  991.     }
  992. }
  993. /* ---- restore video area used by dummy window border ---- */
  994. static void RestoreBorder(RECT rc)
  995. {
  996.     if (Bsave != NULL)    {
  997.         RECT lrc;
  998.         int i;
  999.         int *cp;
  1000.         lrc = rc;
  1001.         RectBottom(lrc) = RectTop(lrc);
  1002.         storevideo(lrc, Bsave);
  1003.         RectTop(lrc) = RectBottom(lrc) = RectBottom(rc);
  1004.         storevideo(lrc, Bsave + Bwd);
  1005.         cp = Bsave + Bwd * 2;
  1006.         for (i = 1; i < Bht-1; i++)    {
  1007.             PutVideoChar(RectLeft(rc),RectTop(rc)+i, *cp++);
  1008.             PutVideoChar(RectRight(rc),RectTop(rc)+i, *cp++);
  1009.         }
  1010.         free(Bsave);
  1011.         Bsave = NULL;
  1012.     }
  1013. }
  1014. /* ----- test if screen coordinates are in a window ---- */
  1015. static BOOL InsideWindow(WINDOW wnd, int x, int y)
  1016. {
  1017.     RECT rc;
  1018.     rc = WindowRect(wnd);
  1019.     if (!TestAttribute(wnd, NOCLIP))    {
  1020.         WINDOW pwnd = GetParent(wnd);
  1021.         while (pwnd != NULL)    {
  1022.             rc = subRectangle(rc, ClientRect(pwnd));
  1023.             pwnd = GetParent(pwnd);
  1024.         }
  1025.     }
  1026.     return InsideRect(x, y, rc);
  1027. }
  1028.  
  1029. BOOL isDerivedFrom(WINDOW wnd, CLASS Class)
  1030. {
  1031.     CLASS tclass = GetClass(wnd);
  1032.     while (tclass != -1)    {
  1033.         if (tclass == Class)
  1034.             return TRUE;
  1035.         tclass = (classdefs[tclass].base);
  1036.     }
  1037.     return FALSE;
  1038. }
  1039.  
  1040. /* -- find the oldest document window ancestor of a window -- */
  1041. WINDOW GetAncestor(WINDOW wnd)
  1042. {
  1043.     if (wnd != NULL)    {
  1044.         while (GetParent(wnd) != NULL)    {
  1045.             if (GetClass(GetParent(wnd)) == APPLICATION)
  1046.                 break;
  1047.             wnd = GetParent(wnd);
  1048.         }
  1049.     }
  1050.     return wnd;
  1051. }
  1052.  
  1053. BOOL isVisible(WINDOW wnd)
  1054. {
  1055.     while (wnd != NULL)    {
  1056.         if (isHidden(wnd))
  1057.             return FALSE;
  1058.         wnd = GetParent(wnd);
  1059.     }
  1060.     return TRUE;
  1061. }
  1062.  
  1063. /* -- adjust a window's rectangle to clip it to its parent - */
  1064. static RECT near ClipRect(WINDOW wnd)
  1065. {
  1066.     RECT rc;
  1067.     rc = WindowRect(wnd);
  1068.     if (TestAttribute(wnd, SHADOW))    {
  1069.         RectBottom(rc)++;
  1070.         RectRight(rc)++;
  1071.     }
  1072.     return ClipRectangle(wnd, rc);
  1073. }
  1074.  
  1075. /* -- get the video memory that is to be used by a window -- */
  1076. static void GetVideoBuffer(WINDOW wnd)
  1077. {
  1078.     RECT rc;
  1079.     int ht;
  1080.     int wd;
  1081.  
  1082.     rc = ClipRect(wnd);
  1083.     ht = RectBottom(rc) - RectTop(rc) + 1;
  1084.     wd = RectRight(rc) - RectLeft(rc) + 1;
  1085.     wnd->videosave = DFrealloc(wnd->videosave, (ht * wd * 2));
  1086.     get_videomode();
  1087.     getvideo(rc, wnd->videosave);
  1088. }
  1089.  
  1090. /* -- put the video memory that is used by a window -- */
  1091. static void PutVideoBuffer(WINDOW wnd)
  1092. {
  1093.     if (wnd->videosave != NULL)    {
  1094.         RECT rc;
  1095.         rc = ClipRect(wnd);
  1096.         get_videomode();
  1097.         storevideo(rc, wnd->videosave);
  1098.         free(wnd->videosave);
  1099.         wnd->videosave = NULL;
  1100.     }
  1101. }
  1102.  
  1103. /* ------- return TRUE if awnd is an ancestor of wnd ------- */
  1104. BOOL isAncestor(WINDOW wnd, WINDOW awnd)
  1105. {
  1106.     while (wnd != NULL)    {
  1107.         if (wnd == awnd)
  1108.             return TRUE;
  1109.         wnd = GetParent(wnd);
  1110.     }
  1111.     return FALSE;
  1112. }
  1113.  
  1114.  
  1115.  
  1116. 
  1117.