Rxdice.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:9k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 1995 AO ROSNO                   }
  6. {         Copyright (c) 1997, 1998 Master-Bank          }
  7. {                                                       }
  8. {*******************************************************}
  9. unit RXDice;
  10. interface
  11. {$I RX.INC}
  12. uses SysUtils, {$IFDEF WIN32} Windows, {$ELSE} WinTypes, WinProcs, {$ENDIF}
  13.   Classes, Graphics, Messages, Controls, Forms, StdCtrls, ExtCtrls, Menus,
  14.   RxTimer, VCLUtils;
  15. type
  16.   TRxDiceValue = 1..6;
  17. { TRxDice }
  18.   TRxDice = class(TCustomControl)
  19.   private
  20.     { Private declarations }
  21.     FActive: Boolean;
  22.     FAutoSize: Boolean;
  23.     FBitmap: TBitmap;
  24.     FInterval: Cardinal;
  25.     FAutoStopInterval: Cardinal;
  26.     FOnChange: TNotifyEvent;
  27.     FRotate: Boolean;
  28.     FShowFocus: Boolean;
  29.     FTimer: TRxTimer;
  30.     FTickCount: Longint;
  31.     FValue: TRxDiceValue;
  32.     FOnStart: TNotifyEvent;
  33.     FOnStop: TNotifyEvent;
  34.     procedure CMFocusChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED;
  35.     procedure WMSize(var Message: TWMSize); message WM_SIZE;
  36.     procedure CreateBitmap;
  37.     procedure SetAutoSize(Value: Boolean);
  38.     procedure SetInterval(Value: Cardinal);
  39.     procedure SetRotate(Value: Boolean);
  40.     procedure SetShowFocus(Value: Boolean);
  41.     procedure SetValue(Value: TRxDiceValue);
  42.     procedure TimerExpired(Sender: TObject);
  43.   protected
  44.     { Protected declarations }
  45.     function GetPalette: HPALETTE; override;
  46.     procedure AdjustSize; {$IFDEF RX_D4} override; {$ENDIF}
  47.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  48.       X, Y: Integer); override;
  49.     procedure Paint; override;
  50.     procedure Change; dynamic;
  51.     procedure DoStart; dynamic;
  52.     procedure DoStop; dynamic;
  53.   public
  54.     { Public declarations }
  55.     constructor Create(AOwner: TComponent); override;
  56.     destructor Destroy; override;
  57.     procedure RandomValue;
  58.   published
  59.     { Published declarations }
  60.     property Align;
  61.     property AutoSize: Boolean read FAutoSize write SetAutoSize default True;
  62.     property AutoStopInterval: Cardinal read FAutoStopInterval write FAutoStopInterval default 0;
  63.     property Color;
  64.     property Cursor;
  65.     property DragMode;
  66.     property DragCursor;
  67.     property Enabled;
  68.     property Interval: Cardinal read FInterval write SetInterval default 60;
  69.     property ParentColor;
  70.     property ParentShowHint;
  71.     property PopupMenu;
  72.     property Rotate: Boolean read FRotate write SetRotate;
  73.     property ShowFocus: Boolean read FShowFocus write SetShowFocus;
  74.     property ShowHint;
  75. {$IFDEF RX_D4}
  76.     property Anchors;
  77.     property Constraints;
  78.     property DragKind;
  79. {$ENDIF}
  80.     property TabOrder;
  81.     property TabStop;
  82.     property Value: TRxDiceValue read FValue write SetValue default 1;
  83.     property Visible;
  84.     property OnClick;
  85.     property OnDblClick;
  86.     property OnEnter;
  87.     property OnExit;
  88.     property OnMouseMove;
  89.     property OnMouseDown;
  90.     property OnMouseUp;
  91.     property OnKeyDown;
  92.     property OnKeyUp;
  93.     property OnKeyPress;
  94.     property OnDragOver;
  95.     property OnDragDrop;
  96.     property OnEndDrag;
  97. {$IFDEF WIN32}
  98.     property OnStartDrag;
  99. {$ENDIF}
  100. {$IFDEF RX_D5}
  101.     property OnContextPopup;
  102. {$ENDIF}
  103.     property OnChange: TNotifyEvent read FOnChange write FOnChange;
  104.     property OnStart: TNotifyEvent read FOnStart write FOnStart;
  105.     property OnStop: TNotifyEvent read FOnStop write FOnStop;
  106. {$IFDEF RX_D4}
  107.     property OnEndDock;
  108.     property OnStartDock;
  109. {$ENDIF}
  110.   end;
  111. implementation
  112. {$IFDEF WIN32}
  113.  {$R *.R32}
  114. {$ELSE}
  115.  {$R *.R16}
  116. {$ENDIF}
  117. const
  118.   ResName: array [TRxDiceValue] of PChar =
  119.    ('DICE1', 'DICE2', 'DICE3', 'DICE4', 'DICE5', 'DICE6');
  120. { TRxDice }
  121. constructor TRxDice.Create(AOwner: TComponent);
  122. begin
  123.   inherited Create(AOwner);
  124.   Randomize;
  125.   ControlStyle := [csClickEvents, csSetCaption, csCaptureMouse,
  126.     csOpaque, csDoubleClicks];
  127.   FValue := 1;
  128.   FInterval := 60;
  129.   CreateBitmap;
  130.   FAutoSize := True;
  131.   Width := FBitmap.Width + 2;
  132.   Height := FBitmap.Height + 2;
  133. end;
  134. destructor TRxDice.Destroy;
  135. begin
  136.   FOnChange := nil;
  137.   if FBitmap <> nil then FBitmap.Free;
  138.   inherited Destroy;
  139. end;
  140. function TRxDice.GetPalette: HPALETTE;
  141. begin
  142.   if FBitmap <> nil then Result := FBitmap.Palette
  143.   else Result := 0;
  144. end;
  145. procedure TRxDice.RandomValue;
  146. var
  147.   Val: Byte;
  148. begin
  149.   Val := Random(6) + 1;
  150.   if Val = Byte(FValue) then begin
  151.     if Val = 1 then Inc(Val)
  152.     else Dec(Val);
  153.   end;
  154.   SetValue(TRxDiceValue(Val));
  155. end;
  156. procedure TRxDice.DoStart;
  157. begin
  158.   if Assigned(FOnStart) then FOnStart(Self);
  159. end;
  160. procedure TRxDice.DoStop;
  161. begin
  162.   if Assigned(FOnStop) then FOnStop(Self);
  163. end;
  164. procedure TRxDice.CMFocusChanged(var Message: TCMFocusChanged);
  165. var
  166.   Active: Boolean;
  167. begin
  168.   with Message do Active := (Sender = Self);
  169.   if Active <> FActive then begin
  170.     FActive := Active;
  171.     if FShowFocus then Invalidate;
  172.   end;
  173.   inherited;
  174. end;
  175. procedure TRxDice.WMSize(var Message: TWMSize);
  176. begin
  177.   inherited;
  178. {$IFNDEF RX_D4}
  179.   AdjustSize;
  180. {$ENDIF}
  181. end;
  182. procedure TRxDice.CreateBitmap;
  183. begin
  184.   if FBitmap = nil then FBitmap := TBitmap.Create;
  185.   FBitmap.Handle := LoadBitmap(HInstance, ResName[FValue]);
  186. end;
  187. procedure TRxDice.AdjustSize;
  188. var
  189.   MinSide: Integer;
  190. begin
  191.   if not (csReading in ComponentState) then begin
  192.     if AutoSize and Assigned(FBitmap) and (FBitmap.Width > 0) and
  193.       (FBitmap.Height > 0) then
  194.         SetBounds(Left, Top, FBitmap.Width + 2, FBitmap.Height + 2)
  195.     else begin
  196.       { Adjust aspect ratio if control size changed }
  197.       MinSide := Width;
  198.       if Height < Width then MinSide := Height;
  199.       SetBounds(Left, Top, MinSide, MinSide);
  200.     end;
  201.   end;
  202. end;
  203. procedure TRxDice.MouseDown(Button: TMouseButton;
  204.   Shift: TShiftState; X, Y: Integer);
  205. begin
  206.   if (Button = mbLeft) and TabStop and CanFocus then SetFocus;
  207.   inherited MouseDown(Button, Shift, X, Y);
  208. end;
  209. procedure TRxDice.Paint;
  210. var
  211.   ARect: TRect;
  212.   procedure DrawBitmap;
  213.   var
  214.     TmpImage: TBitmap;
  215.     IWidth, IHeight: Integer;
  216.     IRect: TRect;
  217.   begin
  218.     IWidth := FBitmap.Width;
  219.     IHeight := FBitmap.Height;
  220.     IRect := Rect(0, 0, IWidth, IHeight);
  221.     TmpImage := TBitmap.Create;
  222.     try
  223.       TmpImage.Width := IWidth;
  224.       TmpImage.Height := IHeight;
  225.       TmpImage.Canvas.Brush.Color := Self.Brush.Color;
  226.       TmpImage.Canvas.BrushCopy(IRect, FBitmap, IRect, FBitmap.TransparentColor);
  227.       InflateRect(ARect, -1, -1);
  228.       Canvas.StretchDraw(ARect, TmpImage);
  229.     finally
  230.       TmpImage.Free;
  231.     end;
  232.   end;
  233. begin
  234.   ARect := ClientRect;
  235.   if FBitmap <> nil then DrawBitmap;
  236.   if Focused and FShowFocus and TabStop and not (csDesigning in ComponentState) then
  237.   begin
  238.     Canvas.DrawFocusRect(ARect);
  239.   end;
  240. end;
  241. procedure TRxDice.TimerExpired(Sender: TObject);
  242. var
  243.   ParentForm: TCustomForm;
  244.   Now: Longint;
  245. begin
  246.   RandomValue;
  247.   if not FRotate then begin
  248.     FTimer.Free;
  249.     FTimer := nil;
  250.     if (csDesigning in ComponentState) then begin
  251.       ParentForm := GetParentForm(Self);
  252.       if ParentForm <> nil then ParentForm.Designer.Modified;
  253.     end;
  254.     DoStop;
  255.   end
  256.   else if AutoStopInterval > 0 then begin
  257.     Now := GetTickCount;
  258. {$IFDEF RX_D4}
  259.     if (Now - FTickCount >= Integer(AutoStopInterval))
  260. {$ELSE}
  261.     if (Now - FTickCount >= AutoStopInterval)
  262. {$ENDIF}
  263.       or (Now < FTickCount) then Rotate := False;
  264.   end;
  265. end;
  266. procedure TRxDice.Change;
  267. begin
  268.   if Assigned(FOnChange) then FOnChange(Self);
  269. end;
  270. procedure TRxDice.SetValue(Value: TRxDiceValue);
  271. begin
  272.   if FValue <> Value then begin
  273.     FValue := Value;
  274.     CreateBitmap;
  275.     Invalidate;
  276.     Change;
  277.   end;
  278. end;
  279. procedure TRxDice.SetAutoSize(Value: Boolean);
  280. begin
  281.   if Value <> FAutoSize then begin
  282.     FAutoSize := Value;
  283.     AdjustSize;
  284.     Invalidate;
  285.   end;
  286. end;
  287. procedure TRxDice.SetInterval(Value: Cardinal);
  288. begin
  289.   if FInterval <> Value then begin
  290.     FInterval := Value;
  291.     if FTimer <> nil then FTimer.Interval := FInterval;
  292.   end;
  293. end;
  294. procedure TRxDice.SetRotate(Value: Boolean);
  295. begin
  296.   if FRotate <> Value then begin
  297.     if Value then begin
  298.       if FTimer = nil then FTimer := TRxTimer.Create(Self);
  299.       try
  300.         with FTimer do begin
  301.           OnTimer := TimerExpired;
  302.           Interval := FInterval;
  303.           Enabled := True;
  304.         end;
  305.         FRotate := Value;
  306.         FTickCount := GetTickCount;
  307.         DoStart;
  308.       except
  309.         FTimer.Free;
  310.         FTimer := nil;
  311.         raise;
  312.       end;
  313.     end
  314.     else FRotate := Value;
  315.   end;
  316. end;
  317. procedure TRxDice.SetShowFocus(Value: Boolean);
  318. begin
  319.   if FShowFocus <> Value then begin
  320.     FShowFocus := Value;
  321.     if not (csDesigning in ComponentState) then Invalidate;
  322.   end;
  323. end;
  324. end.