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