TRACK.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:9k
源码类别:

Windows编程

开发平台:

Visual C++

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