|
|
1.1 root 1: /*
2: ==============================================================================
3:
4: Application:
5:
6: Microsoft Windows NT (TM) Performance Monitor
7:
8: File:
9: intrline.c -- IntervalLine custom control.
10:
11: Copyright 1992, Microsoft Corporation. All Rights Reserved.
12: ==============================================================================
13: */
14:
15:
16: /*
17:
18:
19: Basic Information
20: -----------------
21:
22: An ILine (Interval Line) control is a horizontally-sliding device; the user
23: can slide the start position and end position independently by dragging
24: either "grab" bar, or move them simultaneously by dragging the center grab
25: bar. An ILine control is used in the Input Log dialog of Perfmon, but could
26: be used anywhere. The control allows the user to specify the start, end and
27: duration of playback within the range of previously-logged data.
28:
29:
30: ILine Parts
31: -----------
32:
33: iBeginValue iEndValue
34: | iStartValue iStopValue |
35: | | | |
36: v v v v
37: +------+-+---------------------------------------+-+-----------+
38: | |X| |X| |
39: | |X| |X| |
40: +------+-+---------------------------------------+-+-----------+
41: ^ ^ ^
42: Start grab bar Center grab bar Stop grab bar
43:
44:
45: ILine Terminology
46: -----------------
47:
48: All external routines are designated by the prefix ILine-.
49: Internal routines are designated by the prefix IL-.
50:
51: The suffix -Value represents an integer in the user-supplied domain.
52: The suffix -Pixel represents an integer location on the screen.
53:
54: Note that the range of the IntervalLine is represented by "Begin" and
55: "End", while the the currently selected interval is represented by
56: "Start" and "Stop".
57:
58:
59: Implementation Notes
60: --------------------
61:
62: ILine is a custom control, but does not have all the messages
63: normally associated with a full-fledged control type like "button".
64: In particular, it doesn't have a keyboard interface or ask it's parent
65: for color choices. It also doesn't have the functions needed for interfacing
66: with the dialog editor custom control menu.
67:
68: An ILine control is designed to work with an integer range of values
69: specified by the user of the control. These values should have meaning to
70: the caller. The caller can specify the minimum value of the range
71: (iBeginValue), the maximum value of the range (iEndValue), and the current
72: starting and stopping values (iStartValue and iStopValue).
73:
74: These values are set with a function-based interface. (ILSetXXX).
75:
76: The code distinguishes between the *values* for the begin, end, start, and
77: stop, and the *pixels* which represent locations on the control for these
78: values.
79:
80: Various bits of the control style allow for changing the control's
81: behavior.
82:
83: To allow for multiple ILine controls, all data used by each ILine
84: instance is allocated from the heap and associated with the control.
85: The allocation is done in OnCreate and the freeing in OnDestroy. The
86: instance data is contained in the ILINE structure. Each message handler
87: retrieves this instance data with the ILData function.
88:
89:
90: To Do:
91: ------
92:
93: Add a keyboard interface?
94: Add a double click interface?
95: Add a focus rect?
96: Support WM_CTLCOLOR?
97:
98: */
99:
100:
101: //==========================================================================//
102: // Includes //
103: //==========================================================================//
104:
105:
106: #include "perfmon.h"
107: #include "utils.h"
108: #include "intrline.h"
109: #include "pmemory.h" // for MemoryXXX (mallloc-type) routines
110:
111:
112: //==========================================================================//
113: // Constants //
114: //==========================================================================//
115:
116:
117: #define dwILineClassStyle (CS_HREDRAW | CS_VREDRAW)
118: #define iILineClassExtra (0)
119: #define iILineWindowExtra (sizeof (PILINE))
120: #define dwILineWindowStyle (WS_CHILD | WS_VISIBLE)
121:
122:
123: #define ILModeNone 0
124: #define ILModeLeft 1
125: #define ILModeCenter 2
126: #define ILModeRight 3
127:
128:
129: //==========================================================================//
130: // Typedefs //
131: //==========================================================================//
132:
133:
134: // The instance data for each IL window. One of these is allocated for each
135: // window in the window's OnCreate processing and free'd in OnDestroy.
136: typedef struct ILINESTRUCT
137: { // ILINE
138: int iBeginValue ; // user-supplied lowest range
139: int iEndValue ; // user-supplied highest range
140: int iStartValue ; // current start of selected interval
141: int iStopValue ; // current end of selected interval
142: int iGranularityValue ;
143: int iMinimumRangeValue ;
144:
145: RECT rectBorder ;
146: RECT rectLeftBk ;
147: RECT rectLeftGrab ;
148: RECT rectCenterGrab ;
149: RECT rectRightGrab ;
150: RECT rectRightBk ;
151:
152: HBRUSH hBrushBk ;
153:
154: POINTS ptsMouse ;
155: int iMode ; // who is being tracked?
156: } ILINE ;
157:
158: typedef ILINE *PILINE ;
159:
160:
161: //==========================================================================//
162: // Macros //
163: //==========================================================================//
164:
165:
166: // Width of the start and stob grab bars
167: #define ILGrabWidth() \
168: (xScrollThumbWidth)
169:
170:
171: // A rectangle is "drawable" if it has both nonzero width and height
172: #define RectDrawable(lpRect) \
173: ((lpRect->right - lpRect->left) && \
174: (lpRect->bottom - lpRect->top))
175:
176:
177: //======================================//
178: // ILine Accessor Macros //
179: //======================================//
180:
181: // These macros reference fields in the ILine structure and should be
182: // used in place of direct reference to the fields. This makes the code
183: // easier to read and allows modification of the underlying structure.
184:
185: // You can use these macros to both get and set the fields.
186:
187: #define ILBegin(pILine) \
188: (pILine->iBeginValue)
189:
190: #define ILEnd(pILine) \
191: (pILine->iEndValue)
192:
193: #define ILStart(pILine) \
194: (pILine->iStartValue)
195:
196: #define ILStop(pILine) \
197: (pILine->iStopValue)
198:
199: #define ILMode(pILine) \
200: (pILine->iMode)
201:
202:
203: //======================================//
204: // ILine Pseudo-Accessor Macros //
205: //======================================//
206:
207: // These macros are used to get values which don't correspond to a single
208: // field. You can get the value with these macros but can't set it.
209:
210: #define ILWidth(pILine) \
211: (pILine->rectBorder.right)
212:
213: #define ILRange(pILine) \
214: (ILEnd (pILine) - ILBegin (pILine))
215:
216: #define ILStartPixel(pILine) \
217: (pILine->rectLeftGrab.left)
218:
219: #define ILStopPixel(pILine) \
220: (pILine->rectRightGrab.right)
221:
222:
223: //==========================================================================//
224: // Local Functions //
225: //==========================================================================//
226:
227:
228: void static ILNotifyChange (HWND hWnd,
229: PILINE pILine)
230: { // ILNotifyChange
231: HWND hWndParent ;
232:
233: hWndParent = WindowParent (hWnd) ;
234:
235: if (hWndParent)
236: SendMessage (hWndParent, WM_COMMAND,
237: (WPARAM) WindowID (hWnd),
238: (LPARAM) hWnd) ;
239: } // ILNotifyChange
240:
241:
242: BOOL ILGrabRect (IN PILINE pILine,
243: OUT LPRECT lpRect)
244: /*
245: Effect: Return in lpRect the rectangle representing the position
246: of the grab bar currently being tracked.
247: */
248: { // ILGrabRect
249: switch (ILMode (pILine))
250: { // switch
251: case ILModeLeft:
252: *lpRect = pILine->rectLeftGrab ;
253: return (TRUE) ;
254: break ;
255:
256: case ILModeRight:
257: *lpRect = pILine->rectRightGrab ;
258: return (TRUE) ;
259: break ;
260:
261: case ILModeCenter:
262: *lpRect = pILine->rectCenterGrab ;
263: return (TRUE) ;
264: break ;
265:
266: case ILModeNone:
267: lpRect->left = 0 ;
268: lpRect->top = 0 ;
269: lpRect->right = 0 ;
270: lpRect->bottom = 0 ;
271: return (FALSE) ;
272: break ;
273: } // switch
274: } // ILGrabRect
275:
276:
277: PILINE ILData (HWND hWndIL)
278: {
279: return ((PILINE) GetWindowLong (hWndIL, 0)) ;
280: }
281:
282:
283: PILINE AllocateILData (HWND hWndIL)
284: {
285: PILINE pILine ;
286:
287: pILine = MemoryAllocate (sizeof (ILINE)) ;
288: SetWindowLong (hWndIL, 0, (LONG) pILine) ;
289:
290: return (pILine) ;
291: }
292:
293:
294: void static DrawGrab (HDC hDC,
295: LPRECT lpRectGrab,
296: BOOL bDown)
297: { // DrawGrab
298: if (!RectDrawable (lpRectGrab))
299: return ;
300:
301: if (bDown)
302: ThreeDConcave1 (hDC,
303: lpRectGrab->left,
304: lpRectGrab->top,
305: lpRectGrab->right,
306: lpRectGrab->bottom) ;
307: else
308: ThreeDConvex1 (hDC,
309: lpRectGrab->left,
310: lpRectGrab->top,
311: lpRectGrab->right,
312: lpRectGrab->bottom) ;
313: } // DrawGrab
314:
315:
316: int ILValueToPixel (PILINE pILine,
317: int iValue)
318: {
319: int xPixel ;
320:
321: if (ILRange (pILine))
322: xPixel = MulDiv (iValue, ILWidth (pILine), ILRange (pILine)) ;
323: else
324: xPixel = 0 ;
325:
326: return (PinExclusive (xPixel, 0, pILine->rectBorder.right)) ;
327: }
328:
329:
330: int ILPixelToValue (PILINE pILine,
331: int xPixel)
332: {
333: int iValue ;
334:
335: if (ILWidth (pILine))
336: iValue = MulDiv (xPixel, ILRange (pILine), ILWidth (pILine)) ;
337: else
338: iValue = 0 ;
339:
340: return (PinInclusive (iValue, ILBegin (pILine), ILEnd (pILine))) ;
341: }
342:
343:
344: void static ILCalcPositions (HWND hWnd,
345: PILINE pILine)
346: /*
347: Effect: Determine and set all of the physical rectangles of ILine,
348: based on the current size of the ILine window and the
349: current logical Start, Stop, Begin, and End values.
350: */
351: { // ILCalcPositions
352: int xStart, xStop ;
353: int yHeight ;
354:
355: GetClientRect (hWnd, &pILine->rectBorder) ;
356: yHeight = pILine->rectBorder.bottom ;
357:
358: xStart = ILValueToPixel (pILine, ILStart (pILine)) ;
359: xStop = ILValueToPixel (pILine, ILStop (pILine)) ;
360:
361: pILine->rectLeftBk.left = 1 ;
362: pILine->rectLeftBk.top = 1 ;
363: pILine->rectLeftBk.right = xStart ;
364: pILine->rectLeftBk.bottom = yHeight - 1 ;
365:
366: pILine->rectLeftGrab.left = xStart ;
367: pILine->rectLeftGrab.top = 1 ;
368: pILine->rectLeftGrab.right = xStart + ILGrabWidth () ;
369: pILine->rectLeftGrab.bottom = yHeight - 1 ;
370:
371: pILine->rectRightBk.left = xStop ;
372: pILine->rectRightBk.top = 1 ;
373: pILine->rectRightBk.right = pILine->rectBorder.right - 1 ;
374: pILine->rectRightBk.bottom = yHeight - 1 ;
375:
376: pILine->rectRightGrab.left = xStop - ILGrabWidth () ;
377: pILine->rectRightGrab.top = 1 ;
378: pILine->rectRightGrab.right = xStop ;
379: pILine->rectRightGrab.bottom = yHeight - 1 ;
380:
381: pILine->rectCenterGrab.left = pILine->rectLeftGrab.right ;
382: pILine->rectCenterGrab.top = 1 ;
383: pILine->rectCenterGrab.right = pILine->rectRightGrab.left ;
384: pILine->rectCenterGrab.bottom = yHeight - 1 ;
385:
386: if (pILine->rectLeftGrab.right > pILine->rectRightGrab.left)
387: {
388: pILine->rectLeftGrab.right = pILine->rectLeftGrab.left +
389: (xStop - xStart) / 2 ;
390: pILine->rectRightGrab.left = pILine->rectLeftGrab.right ;
391: pILine->rectCenterGrab.left = 0 ;
392: pILine->rectCenterGrab.right = 0 ;
393: }
394: } // ILCalcPositions
395:
396:
397: void static ILDraw (HDC hDC,
398: PILINE pILine,
399: LPRECT lpRectUpdate)
400: /*
401: Effect: Draw the image of pILine on hDC. Draw at least the
402: portions within rectUpdate.
403:
404: Called By: OnPaint, OnMouseMove.
405: */
406: { // ILDraw
407:
408: //=============================//
409: // Draw Border //
410: //=============================//
411:
412: FrameRect (hDC, &pILine->rectBorder, GetStockObject (BLACK_BRUSH)) ;
413:
414: //=============================//
415: // Draw Background //
416: //=============================//
417:
418: FillRect (hDC, &pILine->rectLeftBk, pILine->hBrushBk) ;
419: FillRect (hDC, &pILine->rectRightBk, pILine->hBrushBk) ;
420:
421: //=============================//
422: // Draw Range Grabs //
423: //=============================//
424:
425: DrawGrab (hDC, &pILine->rectLeftGrab,
426: ILMode (pILine) == ILModeLeft) ;
427: DrawGrab (hDC, &pILine->rectRightGrab,
428: ILMode (pILine) == ILModeRight) ;
429:
430: //=============================//
431: // Draw Center Grab //
432: //=============================//
433:
434: DrawGrab (hDC, &pILine->rectCenterGrab,
435: ILMode (pILine) == ILModeCenter) ;
436: } // ILDraw
437:
438:
439: void ILPageLeftRight (HWND hWnd,
440: PILINE pILine,
441: BOOL bLeft)
442: { // ILPageLeftRight
443: int iStart, iStop, iMove ;
444: HDC hDC ;
445:
446: iStart = ILStart (pILine) ;
447: iStop = ILStop (pILine) ;
448:
449: if (ILRange (pILine) >= 10)
450: iMove = ILRange (pILine) / 10 ;
451: else
452: iMove = 1 ;
453:
454: if (bLeft)
455: iMove = -iMove ;
456:
457: iStart += iMove ;
458: iStop += iMove ;
459:
460: ILineSetStart (hWnd, iStart) ;
461: ILineSetStop (hWnd, iStop) ;
462:
463: hDC = GetDC (hWnd) ;
464: ILDraw (hDC, pILine, &pILine->rectBorder) ;
465: ReleaseDC (hWnd, hDC) ;
466:
467: ILNotifyChange (hWnd, pILine) ;
468: } // ILPageLeftRight
469:
470:
471: void StartGrab (HWND hWnd,
472: PILINE pILine)
473: { // StartGrab
474: RECT rectUpdate ;
475: HDC hDC ;
476:
477: SetCapture (hWnd) ;
478: ILGrabRect (pILine, &rectUpdate) ;
479:
480: hDC = GetDC (hWnd) ;
481: ILDraw (hDC, pILine, &rectUpdate) ;
482: ReleaseDC (hWnd, hDC) ;
483: } // StartGrab
484:
485:
486: void EndGrab (HWND hWnd,
487: PILINE pILine)
488: /*
489: Internals: Set the mode to null after getting the grab rectangle
490: so ILGrabRect knows which grab bar to get.
491: */
492: {
493: RECT rectUpdate ;
494: HDC hDC ;
495:
496: ReleaseCapture () ;
497:
498: ILGrabRect (pILine, &rectUpdate) ;
499: ILMode (pILine) = ILModeNone ;
500:
501: hDC = GetDC (hWnd) ;
502: ILDraw (hDC, pILine, &rectUpdate) ;
503: ReleaseDC (hWnd, hDC) ;
504: }
505:
506:
507: //==========================================================================//
508: // Message Handlers //
509: //==========================================================================//
510:
511:
512: void static OnPaint (HWND hWnd)
513: {
514: PAINTSTRUCT ps ;
515: HDC hDC ;
516: PILINE pILine ;
517:
518: pILine = ILData (hWnd) ;
519: hDC = BeginPaint (hWnd, &ps) ;
520:
521: ILDraw (hDC, pILine, &ps.rcPaint) ;
522:
523: EndPaint (hWnd, &ps) ;
524: }
525:
526:
527: void static OnCreate (HWND hWnd)
528: {
529: PILINE pILine ;
530:
531: pILine = AllocateILData (hWnd) ;
532: ILBegin (pILine) = 0 ;
533: ILEnd (pILine) = 100 ;
534: ILStart (pILine) = 0 ;
535: ILStop (pILine) = 100 ;
536: ILMode (pILine) = ILModeNone ;
537:
538: pILine->hBrushBk = CreateSolidBrush (crBlue) ;
539: ILCalcPositions (hWnd, pILine) ;
540: }
541:
542:
543: void static OnDestroy (HWND hWnd)
544: {
545: PILINE pILine ;
546:
547: pILine = ILData (hWnd) ;
548:
549: DeleteBrush (pILine->hBrushBk) ;
550: MemoryFree (pILine) ;
551: }
552:
553:
554: void static OnLButtonUp (HWND hWnd)
555: { // OnLButtonUp
556: PILINE pILine ;
557:
558: pILine = ILData (hWnd) ;
559:
560: if (ILMode (pILine) == ILModeNone)
561: return ;
562:
563: EndGrab (hWnd, pILine) ;
564: } // OnLButtonUp
565:
566:
567: void static OnMouseMove (HWND hWnd,
568: POINTS ptsMouse)
569: /*
570: Effect: Handle any actions needed when the mouse moves in the
571: ILine hWnd's client area or while the mouse is captured.
572: In particular, if we are tracking one of the grab bars,
573: determine if the mouse movement represents a logical value
574: change and move the grab bar accordingly.
575:
576: Called By: ILineWndProc, in response to a WM_MOUSEMOVE message.
577:
578: See Also: OnLButtonDown, OnLButtonUp.
579:
580: Note: This function has multiple return points.
581:
582: Note: Since we have captured the mouse, we receive mouse msgs
583: even when the mouse is outside our client area, but still
584: in client coordinates. Thus we can have negative mouse
585: coordinates. That is why we convert the lParam of the
586: mouse msg into a POINTS structure rather than 2 WORDS.
587:
588:
589: Internals: Remember that an IntervalLine can only take on integral
590: values in the user-supplied range. Therefore we do our
591: movement calculation in user values, not pixels. We
592: determine what the logical value would be for the previous
593: (last mouse move) and current mouse position. If these
594: LOGICAL values differ, we attempt an adjustment of the
595: grab bar by that logical amount. This way the grab
596: values assume on integral positions and the calculations
597: are simplified.
598:
599: If we calculated by pixel movement, and then shifted the
600: bar into the nearest integal position, we would encounter
601: rounding problems. In particular, when tracking the center
602: grab bar, if we moved both start and stop by the same
603: amount of PIXELS, then converted to LOGICAL values, we
604: might find our center bar shrinking and growing while
605: the bar moves.
606: */
607: {
608: int iMousePrevious, iMouseCurrent ;
609: int iMouseMove ;
610: PILINE pILine ;
611: HDC hDC ;
612:
613: //=============================//
614: // Are we tracking? //
615: //=============================//
616:
617: pILine = ILData (hWnd) ;
618: if (ILMode (pILine) == ILModeNone)
619: return ;
620:
621: //=============================//
622: // Calc LOGICAL mouse movement //
623: //=============================//
624:
625: ptsMouse.x = PinInclusive ((INT)ptsMouse.x,
626: (INT)pILine->rectBorder.left,
627: (INT)pILine->rectBorder.right) ;
628:
629: iMousePrevious = ILPixelToValue (pILine, pILine->ptsMouse.x) ;
630: iMouseCurrent = ILPixelToValue (pILine, ptsMouse.x) ;
631:
632: iMouseMove = iMouseCurrent - iMousePrevious ;
633: if (!iMouseMove)
634: return ;
635:
636: //=============================//
637: // Move grab bar positions //
638: //=============================//
639:
640: switch (ILMode (pILine))
641: { // switch
642: case ILModeLeft:
643: ILStart (pILine) += iMouseMove ;
644: ILStart (pILine) = min (ILStart (pILine), ILStop (pILine) - 1) ;
645: break ;
646:
647: case ILModeCenter:
648: // Before we slide the center grab bar we need to see if the
649: // desired movement amount would send either end out of bounds,
650: // and reduce the movement accordingly.
651:
652: if (ILStart (pILine) + iMouseMove < ILBegin (pILine))
653: iMouseMove = ILBegin (pILine) - ILStart (pILine) ;
654: if (ILStop (pILine) + iMouseMove > ILEnd (pILine))
655: iMouseMove = ILEnd (pILine) - ILStop (pILine) ;
656:
657: ILStart (pILine) += iMouseMove ;
658: ILStop (pILine) += iMouseMove ;
659: break ;
660:
661: case ILModeRight:
662: ILStop (pILine) += iMouseMove ;
663: ILStop (pILine) = max (ILStart (pILine) + 1, ILStop (pILine)) ;
664: break ;
665: } // switch
666:
667:
668: //=============================//
669: // Keep grab bars in range //
670: //=============================//
671:
672:
673: ILStart (pILine) = PinInclusive (ILStart (pILine),
674: ILBegin (pILine), ILEnd (pILine)) ;
675: ILStop (pILine) = PinInclusive (ILStop (pILine),
676: ILBegin (pILine), ILEnd (pILine)) ;
677:
678: //=============================//
679: // Determine pixel pos, draw //
680: //=============================//
681:
682: ILCalcPositions (hWnd, pILine) ;
683:
684: hDC = GetDC (hWnd) ;
685: ILDraw (hDC, pILine, &pILine->rectBorder) ;
686: ReleaseDC (hWnd, hDC) ;
687:
688: pILine->ptsMouse = ptsMouse ;
689: ILNotifyChange (hWnd, pILine) ;
690: } // OnMouseMove
691:
692:
693: void static OnLButtonDown (HWND hWnd,
694: POINTS ptsMouse)
695: {
696: PILINE pILine ;
697: POINT ptMouse ;
698:
699: pILine = ILData (hWnd) ;
700:
701: pILine->ptsMouse = ptsMouse ;
702: ptMouse.x = ptsMouse.x ;
703: ptMouse.y = ptsMouse.y ;
704:
705: if (PtInRect (&pILine->rectLeftBk, ptMouse))
706: ILPageLeftRight (hWnd, pILine, TRUE) ;
707:
708: else if (PtInRect (&pILine->rectRightBk, ptMouse))
709: ILPageLeftRight (hWnd, pILine, FALSE) ;
710:
711: else if (PtInRect (&pILine->rectLeftGrab, ptMouse))
712: {
713: ILMode (pILine) = ILModeLeft ;
714: StartGrab (hWnd, pILine) ;
715: }
716:
717: else if (PtInRect (&pILine->rectRightGrab, ptMouse))
718: {
719: ILMode (pILine) = ILModeRight ;
720: StartGrab (hWnd, pILine) ;
721: }
722:
723: else if (PtInRect (&pILine->rectCenterGrab, ptMouse))
724: {
725: ILMode (pILine) = ILModeCenter ;
726: StartGrab (hWnd, pILine) ;
727: }
728: }
729:
730:
731: void static OnSize (HWND hWnd, WORD xWidth, WORD yHeight)
732: { // OnSize
733: PILINE pILine ;
734:
735: pILine = ILData (hWnd) ;
736:
737: ILCalcPositions (hWnd, pILine) ;
738: } // OnSize
739:
740:
741: //==========================================================================//
742: // Exported Functions //
743: //==========================================================================//
744:
745:
746: LONG FAR PASCAL ILineWndProc (HWND hWnd,
747: unsigned msg,
748: WPARAM wParam,
749: LONG lParam)
750: /*
751: Note: This function must be declared in the application's
752: linker-definition file, perfmon.def file.
753: */
754: { // ILineWndProc
755: BOOL bCallDefWindowProc ;
756: POINTS ptsMouse ;
757: LONG lReturnValue ;
758:
759: bCallDefWindowProc = FALSE ;
760: lReturnValue = 0L ;
761:
762: switch (msg)
763: { // switch
764: case WM_CREATE:
765: OnCreate (hWnd) ;
766: break ;
767:
768: case WM_DESTROY:
769: OnDestroy (hWnd) ;
770: break ;
771:
772: case WM_LBUTTONDOWN:
773: // See the note in OnMouseMove for why we are using POINTS
774: ptsMouse = MAKEPOINTS (lParam) ;
775: OnLButtonDown (hWnd, ptsMouse) ;
776: break ;
777:
778: case WM_LBUTTONUP:
779: OnLButtonUp (hWnd) ;
780: break ;
781:
782: case WM_MOUSEMOVE:
783: // See the note in OnMouseMove for why we are using POINTS
784: ptsMouse = MAKEPOINTS (lParam) ;
785: OnMouseMove (hWnd, ptsMouse) ;
786: break ;
787:
788: case WM_PAINT:
789: OnPaint (hWnd) ;
790: break ;
791:
792: case WM_SIZE:
793: OnSize (hWnd, LOWORD (lParam), HIWORD (lParam)) ;
794:
795: default:
796: bCallDefWindowProc = TRUE ;
797: } // switch
798:
799: if (bCallDefWindowProc)
800: lReturnValue = DefWindowProc (hWnd, msg, wParam, lParam) ;
801:
802: return (lReturnValue) ;
803: } // ILineWndProc
804:
805:
806:
807: BOOL ILineInitializeApplication (void)
808: /*
809: Effect: Perform all initializations required before an application
810: can create an IntervalLine. In particular, register the
811: IntervalLine window class.
812:
813: Called By: The application, in its InitializeApplication routine.
814:
815: Returns: Whether the class could be registered.
816: */
817: { // ILineInitializeApplication
818: WNDCLASS wc ;
819:
820: wc.style = dwILineClassStyle ;
821: wc.lpfnWndProc = ILineWndProc ;
822: wc.cbClsExtra = iILineClassExtra ;
823: wc.cbWndExtra = iILineWindowExtra ;
824: wc.hInstance = hInstance ;
825: wc.hIcon = NULL ;
826: wc.hCursor = LoadCursor (NULL, IDC_ARROW) ;
827: wc.hbrBackground = NULL ;
828: wc.lpszMenuName = NULL ;
829: wc.lpszClassName = szILineClass ;
830:
831: return (RegisterClass (&wc)) ;
832: } // ILineInitializeApplication
833:
834:
835: void ILineSetRange (HWND hWnd, int iBegin, int iEnd)
836: { // ILineSetRange
837: PILINE pILine ;
838:
839: pILine = ILData (hWnd) ;
840:
841: ILBegin (pILine) = iBegin ;
842: ILEnd (pILine) = iEnd ;
843:
844: ILCalcPositions (hWnd, pILine) ;
845: } // ILineSetRange
846:
847:
848: void ILineSetStart (HWND hWnd, int iStart)
849: { // ILineSetStart
850: PILINE pILine ;
851:
852: pILine = ILData (hWnd) ;
853:
854: iStart = PinInclusive (iStart, ILBegin (pILine), ILEnd (pILine)) ;
855: ILStart (pILine) = iStart ;
856:
857: ILCalcPositions (hWnd, pILine) ;
858: } // ILineSetStart
859:
860:
861:
862: void ILineSetStop (HWND hWnd, int iStop)
863: { // ILineSetStop
864: PILINE pILine ;
865:
866: pILine = ILData (hWnd) ;
867:
868: iStop = PinInclusive (iStop, ILBegin (pILine), ILEnd (pILine)) ;
869: ILStop (pILine) = iStop ;
870:
871: ILCalcPositions (hWnd, pILine) ;
872: } // ILineSetStop
873:
874:
875: int ILineXStart (HWND hWnd)
876: {
877: PILINE pILine ;
878:
879: pILine = ILData (hWnd) ;
880:
881: return (pILine->rectLeftGrab.left) ;
882: }
883:
884:
885: int ILineXStop (HWND hWnd)
886: {
887: PILINE pILine ;
888:
889: pILine = ILData (hWnd) ;
890:
891: return (pILine->rectRightGrab.right) ;
892: }
893:
894:
895: int ILineStart (HWND hWnd)
896: {
897: PILINE pILine ;
898:
899: pILine = ILData (hWnd) ;
900:
901: return (ILStart (pILine)) ;
902: }
903:
904:
905: int ILineStop (HWND hWnd)
906: {
907: PILINE pILine ;
908:
909: pILine = ILData (hWnd) ;
910:
911: return (ILStop (pILine)) ;
912: }
913:
914:
915:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.