home *** CD-ROM | disk | FTP | other *** search
- { piectrl.pas -- Sample Pie-Shaped custom control by Tom Swan }
-
- {$N+} { Use math coprocessor and WIN87EM.DLL }
-
- library PieCtrl;
-
- uses WinTypes, WinProcs, Strings;
-
- const
- className = 'PieCtrl';
- extraBytes = 4; { Extra bytes in window instance }
- pie_Limit = 0; { Offset to instance Limit value }
- pie_Index = 2; { Offset to instance Index value }
- startAngle = 270.0; { Pie function's "straight up" angle }
-
- {$I piectrl.inc } { Include message identifiers }
-
- function Radians(W: Double): Double;
- begin
- Radians := Abs(Round(W) mod 360) * Pi / 180.0;
- end;
-
- function PieWndFn(HWindow: HWnd; Message: Word; WParam: Word;
- LParam: Longint): LongInt; export;
- var
- PS: TPaintStruct;
-
- procedure Paint(DC: HDC);
- var
- R: TRect;
- Brush: HBrush;
- THeight, Center: Word;
- DLimit, DIndex: Double;
- XEnd, YEnd, XStart, YStart: Integer;
- Percent, EndAngle, DRadius: Double;
- S: array[0 .. 5] of char;
- begin
- SaveDC(DC);
- GetClientRect(HWindow, R);
- if (R.right > R.bottom) then
- R.right := R.bottom
- else if (R.bottom > R.right) then
- R.bottom := R.right;
- DRadius := R.right;
- Center := R.right div 2;
- DLimit := SendMessage(HWindow, pie_GetLimit, 0, 0);
- DIndex := SendMessage(HWindow, pie_GetIndex, 0, 0);
- Percent := DIndex / DLimit;
- Str(100.0 * Percent:0:0, S);
- StrCat(S, '%');
- EndAngle := startAngle + (Percent * 360.0);
- XEnd := Center + Round(DRadius * Cos(Radians(EndAngle)));
- YEnd := Center + Round(DRadius * Sin(Radians(EndAngle)));
- XStart := Center + Round(DRadius * Cos(Radians(startAngle)));
- YStart := Center + Round(DRadius * Sin(Radians(startAngle)));
- Brush := SendMessage(GetParent(HWindow),
- wm_CtlColor, DC, MAKELONG(HWindow, pie_BackColor));
- SelectObject(DC, Brush);
- Pie(DC, R.left, R.top, R.right, R.bottom,
- XEnd, YEnd, XStart, YStart);
- if (DLimit <> DIndex) then
- begin
- Brush := SendMessage(GetParent(HWindow),
- wm_CtlColor, DC, MAKELONG(HWindow, pie_ForeColor));
- SelectObject(DC, Brush);
- Pie(DC, R.left, R.top, R.right, R.bottom,
- XStart, YStart, XEnd, YEnd);
- end;
- THeight := HIWORD(GetTextExtent(DC, S, 1));
- SetTextAlign(DC, ta_Center);
- TextOut(DC, Center, Center - THeight div 2, S, StrLen(S));
- RestoreDC(DC, -1);
- end;
-
- begin
- PieWndFn := 0; { Preset function result }
- case Message of
- wm_Create:
- begin
- SendMessage(HWindow, pie_SetLimit, 100, 0);
- SendMessage(HWindow, pie_SetIndex, 0, 0);
- end;
- wm_GetDlgCode:
- PieWndFn := dlgc_Static;
- wm_Paint:
- begin
- BeginPaint(HWindow, PS);
- Paint(PS.hDC);
- EndPaint(HWindow, PS);
- end;
- pie_SetLimit:
- begin
- SetWindowWord(HWindow, pie_Limit, WParam);
- InvalidateRect(HWindow, nil, false);
- UpdateWindow(HWindow);
- end;
- pie_GetLimit:
- begin
- PieWndFn := GetWindowWord(HWindow, pie_Limit);
- end;
- pie_SetIndex:
- begin
- SetWindowWord(HWindow, pie_Index, WParam);
- InvalidateRect(HWindow, nil, false);
- UpdateWindow(HWindow);
- end;
- pie_GetIndex:
- PieWndFn := GetWindowWord(HWindow, pie_Index);
- else
- PieWndFn := DefWindowProc(HWindow, Message, WParam, LParam);
- end;
- end;
-
- exports
- PieWndFn;
-
- var
- Class: TWndClass; { Control's window class }
- Chain: Pointer; { For hooking into exit chain }
-
- {$S-} { Turn off stack checking for DLL exit procedures }
- procedure PieExitProc; far;
- begin
- UnregisterClass(className, System.hInstance);
- ExitProc := Chain; { Continue exit procedure chain }
- end;
-
- begin
- Chain := ExitProc; { Preserve current exit path }
- ExitProc := @PieExitProc; { Link new procedure into chain }
- with Class do
- begin
- cbClsExtra := 0;
- cbWndExtra := extraBytes;
- hbrBackground := 0;
- hIcon := 0;
- hInstance := System.hInstance;
- hCursor := LoadCursor(0, idc_Arrow);
- lpfnWndProc := TFarProc(@PieWndFn);
- lpszClassName := className;
- lpszMenuName := nil;
- style := cs_HRedraw or cs_VRedraw or cs_GlobalClass;
- end;
- RegisterClass(Class);
- end.
-