home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 19.ddi / SAMPLES / DDEML / CLIENT / TRACK.C_ / TRACK.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  8.7 KB  |  242 lines

  1. /***************************************************************************
  2.  *                                                                         *
  3.  *  MODULE      : track.c                                                  *
  4.  *                                                                         *
  5.  *  PURPOSE     : Generic tracking code.                                   *
  6.  *                                                                         *
  7.  ***************************************************************************/
  8. #include  "ddemlcl.h"
  9. #include "track.h"
  10.  
  11. RECT  rcTrack;
  12. RECT  rcDelta;
  13. POINT ptOrg;
  14. POINT ptPrev;
  15. WORD  fsTrack;
  16. RECT  rcBoundary;
  17. int cxMinTrack;
  18. int cyMinTrack;
  19.  
  20. VOID DrawTrackRect(HWND hwnd, LPRECT prcOld, LPRECT prcNew);
  21. VOID HorzUpdate(HDC hdc, int yOld, int yNew, int x1Old, int x1New, int x2Old,
  22.         int x2New);
  23. VOID VertUpdate(HDC hdc, int xOld, int xNew, int y1Old, int y1New, int y2Old,
  24.         int y2New);
  25. LONG FAR PASCAL __export TrackingWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  26.  
  27. /****************************************************************************
  28.  *                                                                          *
  29.  *  FUNCTION   : TrackRect()                                                *
  30.  *                                                                          *
  31.  *  PURPOSE    : Implements functionality similiar to the PM WinTrackRect() *
  32.  *                                                                          *
  33.  *  RETURNS    : TRUE on success, FALSE if tracking was canceled.           *
  34.  *               prcResult contains the resulting rectangle.                *
  35.  *                                                                          *
  36.  ****************************************************************************/
  37. BOOL TrackRect(
  38. HANDLE hInst,
  39. HWND   hwnd,        // bounding window
  40. int    left,        // rectangle to track in bounding window coords.
  41. int    top,
  42. int    right,
  43. int    bottom,
  44. int    cxMin,
  45. int    cyMin,
  46. WORD   fs,
  47. LPRECT prcResult)   // result rect in bounding window coords.
  48. {
  49.     static BOOL fTracking = 0;
  50.     FARPROC lpOrgWndProc, lpTrackWndProc;
  51.     HWND hwndOldCapture, hwndOldFocus;
  52.     MSG msg;
  53.  
  54.     if (fTracking)
  55.         return FALSE;
  56.  
  57.     fTracking = TRUE;
  58.  
  59.     lpOrgWndProc = (FARPROC)GetWindowLong(hwnd, GWL_WNDPROC);
  60.     lpTrackWndProc = MakeProcInstance((FARPROC)TrackingWndProc, hInst);
  61.     SetWindowLong(hwnd, GWL_WNDPROC, (DWORD)lpTrackWndProc);
  62.  
  63.     hwndOldCapture = GetCapture();
  64.     SetCapture(hwnd);
  65.  
  66.     hwndOldFocus = SetFocus(hwnd);
  67.     UpdateWindow(hwnd);
  68.  
  69.     GetCursorPos(&ptOrg);
  70.     ScreenToClient(hwnd, &ptOrg);
  71.  
  72.     if (fs & TF_SETPOINTERPOS) {
  73.  
  74.         if (fs & TF_LEFT && fs & TF_RIGHT)
  75.             ptOrg.x = (left + right) / 2;
  76.         else if (fs & TF_LEFT)
  77.             ptOrg.x = left;
  78.         else if (fs & TF_RIGHT)
  79.             ptOrg.x = right;
  80.  
  81.         if (fs & TF_TOP && fs & TF_BOTTOM)
  82.             ptOrg.y = (top + bottom) / 2;
  83.         else if (fs & TF_TOP)
  84.             ptOrg.y = top;
  85.         else if (fs & TF_BOTTOM)
  86.             ptOrg.y = bottom;
  87.  
  88.         ClientToScreen(hwnd, &ptOrg);
  89.         SetCursorPos(ptOrg.x, ptOrg.y);
  90.         ScreenToClient(hwnd, &ptOrg);
  91.     }
  92.  
  93.     ptPrev = ptOrg;
  94.     cxMinTrack = cxMin;
  95.     cyMinTrack = cyMin;
  96.     GetClientRect(hwnd, &rcBoundary);
  97.     fsTrack = fs;
  98.     SetRect(&rcTrack, left, top, right, bottom);
  99.     SetRect(&rcDelta, left - ptOrg.x, top - ptOrg.y, right - ptOrg.x,
  100.             bottom - ptOrg.y);
  101.     DrawTrackRect(hwnd, &rcTrack, NULL);
  102.  
  103.     while (GetMessage(&msg, NULL, NULL, NULL))
  104.         DispatchMessage(&msg);
  105.  
  106.     DrawTrackRect(hwnd, &rcTrack, NULL);
  107.  
  108.     SetWindowLong(hwnd, GWL_WNDPROC, (DWORD)lpOrgWndProc);
  109.     FreeProcInstance(lpTrackWndProc);
  110.  
  111.     SetFocus(hwndOldFocus);
  112.     SetCapture(hwndOldCapture);
  113.     CopyRect(prcResult, &rcTrack);
  114.  
  115.     fTracking = FALSE;
  116. }
  117.  
  118.  
  119.  
  120.  
  121.  
  122. /****************************************************************************
  123.  *                                                                          *
  124.  *  FUNCTION   : DrawTrackRect()                                            *
  125.  *                                                                          *
  126.  *  PURPOSE    : XOR draws whats needed to move a selection from prcOld to  *
  127.  *               prcNew.  If prcNew == NULL this is considered a            *
  128.  *               first-time draw or last time erase.                        *
  129.  *                                                                          *
  130.  ****************************************************************************/
  131. VOID DrawTrackRect(
  132. HWND hwnd,
  133. LPRECT prcOld,
  134. LPRECT prcNew)
  135. {
  136.     HDC hdc;
  137.  
  138.     hdc = GetDC(hwnd);
  139.     SetROP2(hdc, R2_NOT);
  140.         // erase/draw the whole thing
  141.         MoveTo(hdc, prcOld->left, prcOld->top);
  142.         LineTo(hdc, prcOld->right, prcOld->top);
  143.         LineTo(hdc, prcOld->right, prcOld->bottom);
  144.         LineTo(hdc, prcOld->left, prcOld->bottom);
  145.         LineTo(hdc, prcOld->left, prcOld->top);
  146.         if (prcNew) {
  147.             MoveTo(hdc, prcNew->left, prcNew->top);
  148.             LineTo(hdc, prcNew->right, prcNew->top);
  149.             LineTo(hdc, prcNew->right, prcNew->bottom);
  150.             LineTo(hdc, prcNew->left, prcNew->bottom);
  151.             LineTo(hdc, prcNew->left, prcNew->top);
  152.         }
  153.     ReleaseDC(hwnd, hdc);
  154. }
  155.  
  156.  
  157.  
  158. /****************************************************************************
  159.  *                                                                          *
  160.  *  FUNCTION   : TrackingWndProc()                                          *
  161.  *                                                                          *
  162.  *  PURPOSE    : Window procedure that subclasses the given parent window.  *
  163.  *               This handles the mouse tracking and rectangle updates.     *
  164.  *                                                                          *
  165.  ****************************************************************************/
  166. LONG FAR PASCAL __export TrackingWndProc(
  167. HWND hwnd,
  168. UINT msg,
  169. WPARAM wParam,
  170. LPARAM lParam)
  171. {
  172.     switch (msg) {
  173.     case WM_MOUSEMOVE:
  174.         {
  175.             RECT rcNow, rcTest;
  176.  
  177.             if (ptPrev.x == (int)LOWORD(lParam) && ptPrev.y == (int)HIWORD(lParam))
  178.                 return 0;
  179.             CopyRect(&rcNow, &rcTrack);
  180.             if (fsTrack & TF_LEFT)
  181.                 rcNow.left = (int)LOWORD(lParam) + rcDelta.left;
  182.             if (fsTrack & TF_RIGHT)
  183.                 rcNow.right = (int)LOWORD(lParam) + rcDelta.right;
  184.             if (fsTrack & TF_TOP)
  185.                 rcNow.top = (int)HIWORD(lParam) + rcDelta.top;
  186.             if (fsTrack & TF_BOTTOM)
  187.                 rcNow.bottom = (int)HIWORD(lParam) + rcDelta.bottom;
  188.  
  189.             if (rcNow.left > rcNow.right - cxMinTrack)
  190.                 if (fsTrack & TF_LEFT)
  191.                     rcNow.left = rcNow.right - cxMinTrack;
  192.                 else
  193.                     rcNow.right = rcNow.left + cxMinTrack;
  194.  
  195.             if (rcNow.top > rcNow.bottom - cyMinTrack)
  196.                 if (fsTrack & TF_TOP)
  197.                     rcNow.top = rcNow.bottom - cyMinTrack;
  198.                 else
  199.                     rcNow.bottom = rcNow.top + cyMinTrack;
  200.  
  201.             if (fsTrack & TF_ALLINBOUNDARY) {
  202.                 if ((fsTrack & TF_MOVE) == TF_MOVE) {
  203.                     IntersectRect(&rcTest, &rcNow, &rcBoundary);
  204.                     if (!EqualRect(&rcTest, &rcNow)) {
  205.                         if (rcNow.left < rcBoundary.left)
  206.                             OffsetRect(&rcNow, rcBoundary.left - rcNow.left, 0);
  207.                         if (rcNow.right > rcBoundary.right)
  208.                             OffsetRect(&rcNow, rcBoundary.right - rcNow.right, 0);
  209.                         if (rcNow.top < rcBoundary.top)
  210.                             OffsetRect(&rcNow, 0, rcBoundary.top - rcNow.top);
  211.                         if (rcNow.bottom > rcBoundary.bottom)
  212.                             OffsetRect(&rcNow, 0, rcBoundary.bottom - rcNow.bottom);
  213.                     }
  214.                 } else
  215.                     IntersectRect(&rcNow, &rcNow, &rcBoundary);
  216.             }
  217.  
  218.             if (EqualRect(&rcNow, &rcTrack))
  219.                 return 0;
  220.  
  221.             DrawTrackRect(hwnd, &rcTrack, &rcNow);
  222.  
  223.             CopyRect(&rcTrack, &rcNow);
  224.             ptPrev = MAKEPOINT(lParam);
  225.         }
  226.         break;
  227.  
  228.     case WM_LBUTTONUP:
  229.         SendMessage(hwnd, WM_MOUSEMOVE, wParam, lParam);
  230.         PostMessage(hwnd, WM_QUIT, 0, 0);       // pop out of modal loop
  231.         return 0;
  232.         break;
  233.  
  234.     default:
  235.     return(DefWindowProc(hwnd, msg, wParam, lParam));
  236.         break;
  237.     }
  238.     return 0;
  239. }
  240.  
  241.  
  242.