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

Delphi控件源码

开发平台:

Delphi

  1. {========================================================================}
  2. {=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
  3. {========================================================================}
  4. {=                          All Rights Reserved                         =}
  5. {========================================================================}
  6. {=  D 01099 Dresden             = Fax.: +49 (0)351-8037944              =}
  7. {=  Loewenstr.7a                = info@swiftsoft.de                     =}
  8. {========================================================================}
  9. {=  Actual versions on http://www.swiftsoft.de/mmtools.html             =}
  10. {========================================================================}
  11. {=  This code is for reference purposes only and may not be copied or   =}
  12. {=  distributed in any format electronic or otherwise except one copy   =}
  13. {=  for backup purposes.                                                =}
  14. {=                                                                      =}
  15. {=  No Delphi Component Kit or Component individually or in a collection=}
  16. {=  subclassed or otherwise from the code in this unit, or associated   =}
  17. {=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
  18. {=  without express permission from SwiftSoft.                          =}
  19. {=                                                                      =}
  20. {=  For more licence informations please refer to the associated        =}
  21. {=  HelpFile.                                                           =}
  22. {========================================================================}
  23. {=  $Date: 09.07.98 - 15:28:53 $                                        =}
  24. {========================================================================}
  25. unit MMSwitch;
  26. {$I COMPILER.INC}
  27. interface
  28. uses
  29. {$IFDEF WIN32}
  30.     Windows,
  31. {$ELSE}
  32.     WinTypes,
  33.     WinProcs,
  34. {$ENDIF}
  35.     SysUtils, 
  36.     Messages, 
  37.     Classes, 
  38.     Graphics, 
  39.     Controls,
  40.     Buttons,
  41.     MMUtils,
  42.     MMString,
  43.     MMObj;
  44. type
  45.   TMMSwitchKind = (skHorizontal, skVertical);
  46.   {-- TMMSwitch ----------------------------------------------------------}
  47.   TMMSwitch = class(TMMCustomControl)
  48.   private
  49.     FStandardBit : Boolean;          { True if the standard bitmap is used}    
  50.     FGlyph       : TBitmap;          { this our glyph                     }
  51.     FNumGlyphs   : TNumGlyphs;       { number of glyphs in the bitmap     }
  52.     FSwitchRect  : TRect;            { current switch position            }
  53.     FCapture     : Boolean;          { Whether it's currently being moved }
  54.     FCapturePoint: TPoint;           { Position at start of capture.      }
  55.     FCaptureValue: Integer;          { Value at start of capture.         }
  56.     FKind        : TMMSwitchKind;    { skVertical or skHorizontal         }
  57.     FNumPositions: Integer;          { number of switch positions         }
  58.     FPosition    : Integer;          { current switch position            }
  59.     FOnChange    : TNotifyEvent;
  60.     procedure SetKind(aValue : TMMSwitchKind);
  61.     procedure SetNumPositions(aValue: integer);
  62.     procedure SetPosition(aValue: integer);
  63.     procedure SetGlyph(aValue: TBitmap);
  64.     procedure SetNumGlyphs(aValue: TNumGlyphs);
  65.     procedure LoadNewResource;
  66.     procedure AdjustSize(var W, H: Integer);
  67.     procedure AdjustBounds;
  68.     procedure DrawSwitch;
  69.     procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  70.     procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
  71.     procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
  72.     procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
  73.     {$IFDEF BUILD_ACTIVEX}
  74.     procedure WMSize(var Message: TWMSize); message WM_SIZE;
  75.     {$ENDIF}
  76.   protected
  77.     procedure Change; dynamic;
  78.     procedure Paint; override;
  79.     procedure Loaded; override;
  80.     procedure SetBounds(aLeft, aTop, aWidth, aHeight: Integer); override;
  81.     procedure Changed; override;
  82.     procedure MouseDown (Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  83.     procedure MouseUp (Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  84.     procedure MouseMove (Shift: TShiftState; X, Y: Integer); override;
  85.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  86.   public
  87.     constructor Create (AOwner : TComponent); override;
  88.     destructor  Destroy; override;
  89.   published
  90.     property OnClick;
  91.     property OnDragDrop;
  92.     property OnDragOver;
  93.     property OnEndDrag;
  94.     property OnEnter;
  95.     property OnExit;
  96.     property OnMouseDown;
  97.     property OnMouseMove;
  98.     property OnMouseUp;
  99.     property OnChange: TNotifyEvent read FOnChange write FOnChange;
  100.     property Bevel;
  101.     property Color;
  102.     property Enabled;
  103.     property HelpContext;
  104.     property Hint;
  105.     property ParentColor;
  106.     property ParentShowHint;
  107.     property ShowHint;
  108.     property TabStop default True;
  109.     property TabOrder;
  110.     property Tag;
  111.     property Visible;
  112.     property Width default 1;
  113.     property Height default 1;
  114.     property Kind: TMMSwitchKind read FKind write SetKind;
  115.     property NumPositions: integer read FNumPositions write SetNumPositions;
  116.     property Position: Integer read FPosition write SetPosition;
  117.     property Glyph: TBitmap read FGlyph write SetGlyph;
  118.     property NumGlyphs: TNumGlyphs read FNumGlyphs write SetNumGlyphs;
  119.   end;
  120. implementation
  121. {$IFDEF WIN32}
  122.   {$R MMSWITCH.D32}
  123. {$ELSE}
  124.   {$R MMSWITCH.D16}
  125. {$ENDIF}
  126. { these resources are available: }
  127. { 'H_SWITCH' }
  128. { 'V_SWITCH' }
  129. {-- TMMSwitch ------------------------------------------------------------}
  130. constructor TMMSwitch.Create (AOwner : TComponent);
  131. begin
  132.    inherited Create (AOwner);
  133.    FGlyph := TBitmap.Create;
  134.    FNumGlyphs := 1;
  135.    Width := 1;
  136.    Height := 1;
  137.    FKind := skVertical;
  138.    FNumPositions := 2;
  139.    FPosition := 0;
  140.    FOnChange := Nil;
  141.    FCapture := False;
  142.    TabStop := True;
  143.    LoadNewResource;
  144.    ErrorCode := ComponentRegistered(InitCode, Self, ClassName);
  145.    if (ErrorCode <> 0) then RegisterFailed(InitCode, Self , ClassName);
  146. end;
  147. {-- TMMSwitch ------------------------------------------------------------}
  148. destructor TMMSwitch.Destroy;
  149. begin
  150.    FGlyph.Free;
  151.    inherited Destroy
  152. end;
  153. {-- TMMSwitch ------------------------------------------------------------}
  154. procedure TMMSwitch.Change;
  155. begin
  156.    if not (csLoading in ComponentState) and 
  157.       not (csReading in ComponentState) then
  158.       if Assigned(FOnChange) then FOnChange(self);
  159. end;
  160. {-- TMMSwitch ------------------------------------------------------------}
  161. procedure TMMSwitch.LoadNewResource;
  162. var
  163.    Str1: array[0..80] of Char;
  164. begin
  165.    if (FKind = skVertical) then 
  166.       StrCopy(str1, 'V_SWITCH')
  167.    else 
  168.       StrCopy(str1, 'H_SWITCH');
  169.                                                       { load the resource }
  170.    FGlyph.Handle := LoadBitmap(HInstance, Str1);
  171.    FNumGlyphs := 3;
  172.    AdjustBounds;
  173.    FStandardBit := True;
  174. end;
  175. {-- TMMSwitch ------------------------------------------------------------}
  176. procedure TMMSwitch.SetGlyph(aValue: TBitmap);
  177. begin
  178.    if (aValue <> FGlyph) then
  179.    begin
  180.       if aValue <> Nil then
  181.       begin
  182.          FGlyph.Assign(aValue);
  183.          FStandardBit := False;
  184.          AdjustBounds;
  185.       end
  186.       else LoadNewResource;
  187.       Invalidate;
  188.    end;
  189. end;
  190. {-- TMMSwitch ------------------------------------------------------------}
  191. procedure TMMSwitch.SetNumGlyphs(aValue: TNumGlyphs);
  192. begin
  193.      if (aValue <> FNumGlyphs) then
  194.      begin
  195.         FNumGlyphs := aValue;
  196.         AdjustBounds;
  197.         Invalidate;
  198.      end;
  199. end;
  200. {-- TMMSwitch ------------------------------------------------------------}
  201. procedure TMMSwitch.CMEnabledChanged(var Message: TMessage);
  202. begin
  203.    Invalidate;
  204. end;
  205. {-- TMMSwitch ------------------------------------------------------------}
  206. procedure TMMSwitch.WMSetFocus(var Message: TWMSetFocus);
  207. begin
  208.      Invalidate;
  209. end;
  210. {-- TMMSwitch ------------------------------------------------------------}
  211. procedure TMMSwitch.WMKillFocus(var Message: TWMKillFocus);
  212. begin
  213.      Invalidate;
  214. end;
  215. {$IFDEF BUILD_ACTIVEX}
  216. {-- TMMSwitch ------------------------------------------------------------}
  217. procedure TMMSwitch.WMSize(var Message: TWMSize);
  218. begin
  219.    inherited;
  220.    AdjustBounds;
  221. end;
  222. {$ENDIF}
  223. {-- TMMSwitch ------------------------------------------------------------}
  224. procedure TMMSwitch.SetKind(aValue: TMMSwitchKind);
  225. begin
  226.    if (aValue <> FKind) then
  227.    begin
  228.       FKind := aValue;
  229.       if FStandardBit then LoadNewResource
  230.       else AdjustBounds;
  231.       Invalidate;
  232.    end;
  233.    {$IFDEF WIN32}
  234.    {$IFDEF TRIAL}
  235.    {$DEFINE _HACK1}
  236.    {$I MMHACK.INC}
  237.    {$ENDIF}
  238.    {$ENDIF}
  239. end;
  240. {-- TMMSwitch ------------------------------------------------------------}
  241. procedure TMMSwitch.SetNumPositions(aValue: integer);
  242. begin
  243.    if (aValue <> FNumPositions) and (aValue > 1) then
  244.    begin
  245.       FNumPositions := aValue;
  246.       FPosition := Min(FPosition, FNumPositions-1);
  247.       AdjustBounds;
  248.    end;
  249.    {$IFDEF WIN32}
  250.    {$IFDEF TRIAL}
  251.    {$DEFINE _HACK2}
  252.    {$I MMHACK.INC}
  253.    {$ENDIF}
  254.    {$ENDIF}
  255. end;
  256. {-- TMMSwitch ------------------------------------------------------------}
  257. procedure TMMSwitch.SetPosition(aValue: integer);
  258. begin
  259.    aValue := MinMax(aValue, 0, FNumPositions-1);
  260.    if aValue <> FPosition then
  261.    begin
  262.       FPosition := aValue;
  263.       Change;
  264.       if (csDesigning in ComponentState) then
  265.           Invalidate
  266.       else if Enabled then DrawSwitch;
  267.    end
  268. end;
  269. {-- TMMSwitch ------------------------------------------------------------}
  270. procedure TMMSwitch.KeyDown(var Key: Word; Shift: TShiftState);
  271. begin
  272.    inherited KeyDown(Key, Shift);
  273.    case Key of
  274.      VK_END  : Position := FNumPositions-1;
  275.      VK_HOME : Position := 0;
  276.      VK_UP   : if FKind = skVertical then Position := Position -1;
  277.      VK_DOWN : if FKind = skVertical then Position := Position + 1;
  278.      VK_LEFT : if FKind = skHorizontal then Position := Position - 1;
  279.      VK_RIGHT: if FKind = skHorizontal then Position := Position + 1;
  280.    end;
  281. end;
  282. {-- TMMSwitch ------------------------------------------------------------}
  283. procedure TMMSwitch.WMGetDlgCode(var Message: TWMGetDlgCode);
  284. begin
  285.    Message.Result := DLGC_WANTARROWS;
  286. end;
  287. {-- TMMSwitch ------------------------------------------------------------}
  288. procedure TMMSwitch.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  289. begin
  290.    inherited MouseDown(Button, Shift, X, Y);
  291.    if (Button = mbLeft) and Enabled then
  292.    begin
  293.       SetFocus;
  294.       if PtInRect(FSwitchRect, Point(X, Y)) then
  295.       begin
  296.          FCapture := True;
  297.          FCapturePoint := Point(X, Y);
  298.          FCaptureValue := FPosition;
  299.          Invalidate;
  300.       end
  301.       else
  302.       begin
  303.          if FKind = skVertical then
  304.             Position := (Y - BevelExtend) div FGlyph.Height
  305.          else
  306.             Position := (X - BevelExtend) div (FGlyph.Width div FNumGlyphs);
  307.       end;
  308.    end;
  309. end;
  310. {-- TMMSwitch ------------------------------------------------------------}
  311. procedure TMMSwitch.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  312. begin
  313.    inherited MouseUp(Button, Shift, X, Y);
  314.    if (Button = mbLeft) and FCapture then
  315.    begin
  316.       FCapture := False;
  317.       Invalidate;
  318.    end;
  319. end;
  320. {-- TMMSwitch ------------------------------------------------------------}
  321. procedure TMMSwitch.MouseMove(Shift: TShiftState; X, Y: Integer);
  322. begin
  323.    inherited MouseMove(Shift, X, Y);
  324.    if FCapture then
  325.    begin
  326.       if FKind = skVertical then
  327.          Position := FCaptureValue+FNumPositions*(Y-FCapturePoint.Y)div(Height-2*BevelExtend-FGlyph.Height)
  328.       else
  329.          Position := FCaptureValue+FNumPositions*(X-FCapturePoint.X)div(Width-2*BevelExtend-FGlyph.Width div FNumGlyphs);
  330.    end;
  331. end;
  332. {-- TMMSwitch ------------------------------------------------------------}
  333. procedure TMMSwitch.SetBounds(aLeft, aTop, aWidth, aHeight: Integer);
  334. var
  335.   W, H: Integer;
  336. begin
  337.    W := aWidth;
  338.    H := aHeight;
  339.    AdjustSize (W, H);
  340.    inherited SetBounds(aLeft, aTop, W, H);
  341. end;
  342. {-- TMMSwitch ------------------------------------------------------------}
  343. procedure TMMSwitch.AdjustSize(var W, H: Integer);
  344. begin
  345.    if (csLoading in ComponentState) then Exit;
  346.    if FKind = skVertical then
  347.    begin
  348.       W := FGlyph.Width div FNumGlyphs;
  349.       H := FNumPositions * FGlyph.Height;
  350.    end
  351.    else
  352.    begin
  353.       W := FNumPositions * FGlyph.Width div FNumGlyphs;
  354.       H := FGlyph.Height;
  355.    end;
  356.    inc(H,2*BevelExtend);
  357.    inc(W,2*BevelExtend);
  358. end;
  359. {-- TMMSwitch ------------------------------------------------------------}
  360. procedure TMMSwitch.AdjustBounds;
  361. var
  362.   W, H: Integer;
  363. begin
  364.    W := Width;
  365.    H := Height;
  366.    AdjustSize(W, H);
  367.    if (W <> Width) or (H <> Height) then
  368.    begin
  369.       FSwitchRect.Left := -1;
  370.       inherited SetBounds(Left, Top, W, H);
  371.    end
  372.    else Invalidate;
  373. end;
  374. {-- TMMSwitch ------------------------------------------------------------}
  375. procedure TMMSwitch.Changed;
  376. begin
  377.    AdjustBounds;
  378. end;
  379. {-- TMMSwitch ------------------------------------------------------------}
  380. procedure TMMSwitch.Loaded;
  381. begin
  382.    inherited Loaded;
  383.    AdjustBounds;
  384. end;
  385. {-- TMMSwitch ------------------------------------------------------------}
  386. procedure TMMSwitch.DrawSwitch;
  387. var
  388.    SrcRect: TRect;
  389. begin
  390.    if Visible then
  391.    with Canvas do
  392.    begin
  393.       Brush.Color := Color;
  394.       { clear the old switch }
  395.       if FSwitchRect.Left <> -1 then FillRect(FSwitchRect);
  396.       if FKind = skVertical then
  397.       begin
  398.          FSwitchRect.Left := BevelExtend;
  399.          FSwitchRect.Top := BevelExtend + FPosition * FGlyph.Height;
  400.          FSwitchRect.Right := FSwitchRect.Left + FGlyph.Width div FNumGlyphs;
  401.          FSwitchRect.Bottom := FSwitchRect.Top + FGlyph.Height;
  402.       end
  403.       else
  404.       begin
  405.          FSwitchRect.Left := BevelExtend + FPosition * FGlyph.Width div FNumGlyphs;
  406.          FSwitchRect.Top := BevelExtend;
  407.          FSwitchRect.Right := FSwitchRect.Left + FGlyph.Width div FNumGlyphs;
  408.          FSwitchRect.Bottom := FSwitchRect.Top + FGlyph.Height;
  409.       end;
  410.       SrcRect := Rect(0,0,FGlyph.Width div FNumGlyphs,FGlyph.Height);
  411.       if Not Enabled and (FNumGlyphs > 1) then
  412.          OffsetRect(SrcRect, FGlyph.Width div FNumGlyphs, 0);
  413.       if FCapture and (FNumGlyphs > 2) then
  414.          OffsetRect(SrcRect, 2 * FGlyph.Width div FNumGlyphs, 0);
  415.       { draw the new switch and change the backcolors }
  416.       BrushCopy(FSwitchRect, FGlyph, SrcRect, FGlyph.Canvas.Pixels[0,0]);
  417.       { draw the focus }
  418.       if Focused then
  419.       begin
  420.          Pen.Color := clBlack;
  421.          Brush.Style := bsClear;
  422.          with BeveledRect do Rectangle(Left,Top,Right,Bottom);
  423.       end;
  424.    end;
  425. end;
  426. {-- TMMSwitch ------------------------------------------------------------}
  427. procedure TMMSwitch.Paint;
  428. begin
  429.     { Draw the bevel }
  430.     inherited Paint;
  431.     DrawSwitch;
  432. end;
  433. end.