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