|
|
1.1 root 1: /***************************************************************************
2: * *
3: * MODULE : track.c *
4: * *
5: * PURPOSE : Generic tracking code. *
6: * *
7: ***************************************************************************/
8: #include <windows.h>
9: #include "track.h"
10:
11: RECT rcTrack;
12: RECT rcDelta;
13: POINT ptOrg;
14: POINT ptPrev;
15: DWORD 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 APIENTRY TrackingWndProc(HWND hwnd, DWORD 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: DWORD 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
1.1.1.2 ! root 141: MoveToEx(hdc, prcOld->left, prcOld->top, NULL);
1.1 root 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) {
1.1.1.2 ! root 147: MoveToEx(hdc, prcNew->left, prcNew->top, NULL);
1.1 root 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 APIENTRY TrackingWndProc(
167: HWND hwnd,
168: DWORD 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 == (short)LOWORD(lParam) && ptPrev.y == (short)HIWORD(lParam))
178: return 0;
179: CopyRect(&rcNow, &rcTrack);
180: if (fsTrack & TF_LEFT)
181: rcNow.left = (short)LOWORD(lParam) + rcDelta.left;
182: if (fsTrack & TF_RIGHT)
183: rcNow.right = (short)LOWORD(lParam) + rcDelta.right;
184: if (fsTrack & TF_TOP)
185: rcNow.top = (short)HIWORD(lParam) + rcDelta.top;
186: if (fsTrack & TF_BOTTOM)
187: rcNow.bottom = (short)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);
1.1.1.2 ! root 224: ((ptPrev).x = ((*((POINTS *)&(lParam)))).x, (ptPrev).y = ((*((POINTS *)&(lParam)))).y);
1.1 root 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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.