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

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: 13.08.98 - 20:52:39 $                                        =}
  24. {========================================================================}
  25. unit MMCCon;
  26. {$I COMPILER.INC}
  27. interface
  28. uses
  29. {$IFDEF WIN32}
  30.     Windows,
  31. {$ELSE}
  32.     WinTypes,
  33.     WinProcs,
  34. {$ENDIF}
  35.     Forms,
  36.     Messages,
  37.     Classes,
  38.     SysUtils,
  39.     StdCtrls,
  40.     ExtCtrls,
  41.     Controls,
  42.     MMObj,
  43.     MMUtils,
  44.     MMMath,
  45.     MMLevel
  46.     {$IFNDEF LEVEL_ONLY}
  47.     ,MMMeter
  48.     {$ENDIF}
  49.     ;
  50. const
  51.     {$IFDEF CBUILDER3} {$EXTERNALSYM defInterval} {$ENDIF}
  52.     defInterval = 25;
  53. type
  54.     EMMLevelConnectorError = class(Exception);
  55.     TMMCurrentValue     = array[TMMChannel] of LongInt;
  56.     {-- TMMCustomLevelConnector -----------------------------------------}
  57.     TMMCustomLevelConnector = class(TMMNonVisualComponent)
  58.     private
  59.         FTimerID    : Longint;
  60.         FInterval   : Integer;
  61.         FLevel1     : TMMCustomLevel;
  62.         FLevel2     : TMMCustomLevel;
  63.         {$IFNDEF LEVEL_ONLY}
  64.         FMeter1     : TMMCustomMeter;
  65.         FMeter2     : TMMCustomMeter;
  66.         {$ENDIF}
  67.         FAuto       : Boolean;
  68.         FEnabled    : Boolean;
  69.         FMessageDone: Boolean;
  70.         FOnTrigger  : TNotifyEvent;
  71.         procedure SetLevel(Index: Integer; Value: TMMCustomLevel);
  72.         {$IFNDEF LEVEL_ONLY}
  73.         procedure SetMeter(Index: Integer; Value: TMMCustomMeter);
  74.         {$ENDIF}
  75.         procedure SetAuto(Value: Boolean);
  76.         procedure SetInterval(Value: Integer);
  77.         procedure SetEnabled(Value: Boolean);
  78.     protected
  79.         FPrev       : TMMCurrentValue;
  80.         FPrevValid  : Boolean;
  81.         procedure Loaded; override;
  82.         procedure SetupConnector; virtual;
  83.         procedure UpdateValue; virtual;
  84.         procedure UpdateControl; virtual;
  85.         procedure GetLevelValues(var LeftValue, RightValue,BothValue: integer); virtual;
  86.         procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  87.     public
  88.         constructor Create(AOwner: TComponent); override;
  89.         destructor  Destroy; override;
  90.         procedure   ChangeDesigning(aValue: Boolean); override;
  91.         procedure   Trigger; virtual;
  92.     protected
  93.         property OnTrigger: TNotifyEvent read FOnTrigger write FOnTrigger;
  94.         property Level1: TMMCustomLevel index 1 read FLevel1 write SetLevel;
  95.         property Level2: TMMCustomLevel index 2 read FLevel2 write SetLevel;
  96.         {$IFNDEF LEVEL_ONLY}
  97.         property Meter1: TMMCustomMeter index 1 read FMeter1 write SetMeter;
  98.         property Meter2: TMMCustomMeter index 2 read FMeter2 write SetMeter;
  99.         {$ENDIF}
  100.         property AutoTrigger: Boolean  read FAuto write SetAuto default True;
  101.         property Interval: Integer  read FInterval write SetInterval default defInterval;
  102.         property Enabled: Boolean read FEnabled write SetEnabled default True;
  103.     end;
  104. implementation
  105. uses MMTimer;
  106. var
  107.    ConnectorWindow: HWND    = 0;
  108.    ConnectorCount : Integer = 0;
  109.    Connectors     : TList   = nil;
  110. {------------------------------------------------------------------------------}
  111. procedure TimeCallBack(uTimerID, dwUser: Longint); export;
  112. begin
  113.    { D3: Rely on MMTimer unit }
  114.    if (dwUser <> 0) then
  115.    with TMMCustomLevelConnector(dwUser) do
  116.    begin
  117.       if Enabled and not (csDestroying in ComponentState) then
  118.       begin
  119.          if FMessageDone then
  120.          begin
  121.             FMessageDone := False;
  122.             PostMessage(ConnectorWindow,MM_TIMER,0,dwUser);
  123.          end;
  124.       end;
  125.    end;
  126. end;
  127. {------------------------------------------------------------------------------}
  128. function TimerWndProc(Window: HWND; Message, wParam: UINT; lParam: Longint): Longint;
  129. export;{$IFDEF WIN32}stdcall;{$ENDIF}
  130. begin
  131.    Result := 0;
  132.    try
  133.       if (Message = MM_TIMER) and (lParam <> 0) then
  134.       begin
  135.          with TMMCustomLevelConnector(lParam) do
  136.          begin
  137.             if (Connectors <> nil) and (Connectors.IndexOf(Pointer(lParam)) <> -1) then
  138.                 Trigger;
  139.             FMessageDone := True;
  140.          end;
  141.          Exit;
  142.       end;
  143.       Result := DefWindowProc(Window, Message, wParam, lParam);
  144.    except
  145.       Application.HandleException(nil);
  146.    end;
  147. end;
  148. const
  149.   TMMLevelConnectorWindowClass: TWndClass = (
  150.     style: 0;
  151.     lpfnWndProc: @TimerWndProc;
  152.     cbClsExtra: 0;
  153.     cbWndExtra: 0;
  154.     hInstance: 0;
  155.     hIcon: 0;
  156.     hCursor: 0;
  157.     hbrBackground: 0;
  158.     lpszMenuName: nil;
  159.     lpszClassName: 'TMMLevelConnectorWindow');
  160. {------------------------------------------------------------------------------}
  161. function AllocateConnectorWindow: HWND;
  162. var
  163.    TempClass: TWndClass;
  164.    ClassRegistered: Boolean;
  165. begin
  166.    TMMLevelConnectorWindowClass.hInstance := HInstance;
  167.    ClassRegistered := GetClassInfo(HInstance,
  168.                       TMMLevelConnectorWindowClass.lpszClassName, TempClass);
  169.     if not ClassRegistered or (TempClass.lpfnWndProc <> @TimerWndProc) then
  170.     begin
  171.        if ClassRegistered then
  172.           Windows.UnregisterClass(TMMLevelConnectorWindowClass.lpszClassName, HInstance);
  173.        Windows.RegisterClass(TMMLevelConnectorWindowClass);
  174.     end;
  175.     Result := CreateWindow(TMMLevelConnectorWindowClass.lpszClassName, '', 0,
  176.                            0, 0, 0, 0, 0, 0, HInstance, nil);
  177. end;
  178. {------------------------------------------------------------------------------}
  179. procedure AddConnector(C: TMMCustomLevelConnector);
  180. begin
  181.    if ConnectorCount = 0 then
  182.    begin
  183.       ConnectorWindow := AllocateConnectorWindow;
  184.       Connectors      := TList.Create;
  185.    end;
  186.    Connectors.Add(C);
  187.    inc(ConnectorCount);
  188. end;
  189. {------------------------------------------------------------------------------}
  190. procedure RemoveConnector(C: TMMCustomLevelConnector);
  191. begin
  192.    Connectors.Remove(C);
  193.    dec(ConnectorCount);
  194.    if ConnectorCount = 0 then
  195.    begin
  196.       DestroyWindow(ConnectorWindow);
  197.       Connectors.Free;
  198.       Connectors := nil;
  199.    end;
  200. end;
  201. {== TMMCustomLevelConnector ===================================================}
  202. constructor TMMCustomLevelConnector.Create(AOwner: TComponent);
  203. begin
  204.    inherited Create(AOwner);
  205.    FInterval    := defInterval;
  206.    FEnabled     := True;
  207.    FMessageDone := True;
  208.    FAuto        := True;
  209.    AddConnector(Self);
  210.    if not (csDesigning in ComponentState) then
  211.    begin
  212.       { create the timer }
  213.       FTimerID:= MMTimeSetEvent(FInterval, not FAuto, TimeCallBack, Longint(Self));
  214.    end;
  215. end;
  216. {-- TMMCustomLevelConnector --------------------------------------------}
  217. destructor TMMCustomLevelConnector.Destroy;
  218. var
  219.    Msg: TMsg;
  220. begin
  221.     if (FTimerID <> 0) then
  222.     begin
  223.        { destroy the timer }
  224.        MMTimeKillEvent(FTimerID);
  225.        { remove pending messages }
  226.        while PeekMessage(Msg, ConnectorWindow, MM_TIMER, MM_TIMER, PM_REMOVE) do;
  227.     end;
  228.     RemoveConnector(Self);
  229.     inherited Destroy;
  230. end;
  231. {-- TMMCustomLevelConnector --------------------------------------------}
  232. procedure TMMCustomLevelConnector.ChangeDesigning(aValue: Boolean);
  233. begin
  234.    inherited;
  235.    if not (csDesigning in ComponentState) then
  236.    begin
  237.       { create the timer }
  238.       FTimerID:= MMTimeSetEvent(FInterval, not FAuto, TimeCallBack, Longint(Self));
  239.    end;
  240. end;
  241. {-- TMMCustomLevelConnector --------------------------------------------}
  242. procedure TMMCustomLevelConnector.SetEnabled(Value: Boolean);
  243. begin
  244.    if FEnabled <> Value then
  245.    begin
  246.       FEnabled:= Value;
  247.       UpdateControl;
  248.    end;
  249. end;
  250. {-- TMMCustomLevelConnector --------------------------------------------}
  251. procedure TMMCustomLevelConnector.SetupConnector;
  252. begin
  253.    { must be overwritten }
  254.    FPrevValid:= False;
  255. end;
  256. {-- TMMCustomLevelConnector --------------------------------------------}
  257. procedure TMMCustomLevelConnector.Loaded;
  258. begin
  259.    inherited Loaded;
  260.    UpdateControl;
  261. end;
  262. {-- TMMCustomLevelConnector --------------------------------------------}
  263. procedure TMMCustomLevelConnector.Notification(AComponent: TComponent; Operation: TOperation);
  264. begin
  265.    inherited Notification(AComponent,Operation);
  266.    if Operation = opRemove then
  267.       if AComponent = Level1 then
  268.          Level1 := nil
  269.       else if AComponent = Level2 then
  270.          Level2 := nil
  271.       {$IFNDEF LEVEL_ONLY}
  272.       else if AComponent = Meter1 then
  273.          Meter1 := nil
  274.       else if AComponent = Meter2 then
  275.          Meter2 := nil
  276.       {$ENDIF}
  277.       ;
  278. end;
  279. {-- TMMCustomLevelConnector --------------------------------------------}
  280. procedure TMMCustomLevelConnector.UpdateValue;
  281. begin
  282.    if not FAuto then Trigger;
  283. end;
  284. {-- TMMCustomLevelConnector --------------------------------------------}
  285. procedure TMMCustomLevelConnector.UpdateControl;
  286. begin
  287.    if Assigned(FLevel1) then
  288.       TMMLevel(FLevel1).BitLength := b16bit;
  289.    if Assigned(FLevel2) then
  290.       TMMLevel(FLevel2).BitLength := b16bit;
  291.    {$IFNDEF LEVEL_ONLY}
  292.    if Assigned(FMeter1) then
  293.       TMMLevel(FMeter1).BitLength := b16bit;
  294.    if Assigned(FMeter2) then
  295.       TMMLevel(FMeter2).BitLength := b16bit;
  296.    {$ENDIF}
  297.    SetupConnector;
  298.    UpdateValue;
  299. end;
  300. {-- TMMCustomLevelConnector --------------------------------------------}
  301. procedure TMMCustomLevelConnector.SetLevel(Index: Integer; Value: TMMCustomLevel);
  302. begin
  303.    if (Longint(Value) = Longint(Self)) then exit;
  304.    case Index of
  305.       1: if (Value = nil) or ((Value <> nil) and (FLevel2 <> Value)) then
  306.              FLevel1:= Value
  307.          else Exit;
  308.       2: if (Value = nil) or ((Value <> nil) and (FLevel1 <> Value)) then
  309.              FLevel2:= Value
  310.          else Exit;
  311.    end;
  312.    if Value <> nil then
  313.       Value.FreeNotification(Self);
  314.    UpdateControl;
  315. end;
  316. {$IFNDEF LEVEL_ONLY}
  317. {-- TMMCustomLevelConnector --------------------------------------------}
  318. procedure TMMCustomLevelConnector.SetMeter(Index: Integer; Value: TMMCustomMeter);
  319. begin
  320.    if (Longint(Value) = Longint(Self)) then exit;
  321.    case Index of
  322.       1: if (Value = nil) or ((Value <> nil) and (FMeter2 <> Value)) then
  323.              FMeter1:= Value
  324.          else Exit;
  325.       2: if (Value = nil) or ((Value <> nil) and (FMeter1 <> Value)) then
  326.              FMeter2:= Value
  327.          else Exit;
  328.    end;
  329.    if Value <> nil then
  330.       Value.FreeNotification(Self);
  331.    UpdateControl;
  332. end;
  333. {$ENDIF}
  334. {-- TMMCustomLevelConnector --------------------------------------------}
  335. procedure TMMCustomLevelConnector.SetAuto(Value: Boolean);
  336. begin
  337.    if Value <> FAuto then
  338.    begin
  339.       FAuto := Value;
  340.       if not (csDesigning in ComponentState) then
  341.       begin
  342.          if FAuto then
  343.             MMTimeResumeEvent(FTimerID)
  344.          else
  345.             MMTimeSuspendEvent(FTimerID)
  346.       end;
  347.    end;
  348. end;
  349. {-- TMMCustomLevelConnector --------------------------------------------}
  350. procedure TMMCustomLevelConnector.SetInterval(Value: Integer);
  351. begin
  352.    if Value <= 0 then
  353.       { TODO: Should be resource id }
  354.       raise EMMLevelConnectorError.Create('Interval should be > 0');
  355.    if Value <> FInterval then
  356.    begin
  357.       FInterval:= Value;
  358.       if not (csDesigning in ComponentState) then
  359.          MMTimeSetInterval(FTimerID,FInterval);
  360.    end;
  361. end;
  362. {-- TMMCustomLevelConnector --------------------------------------------}
  363. procedure TMMCustomLevelConnector.GetLevelValues(var LeftValue, RightValue, BothValue: integer);
  364. begin
  365.    LeftValue  := 0;
  366.    RightValue := 0;
  367.    BothValue  := 0;
  368. end;
  369. {-- TMMCustomLevelConnector --------------------------------------------}
  370. procedure TMMCustomLevelConnector.Trigger;
  371. var
  372.    LeftValue, RightValue, BothValue: integer;
  373.    procedure SetLevelValue(Level: TMMCustomLevel; Val: Integer);
  374.    begin
  375.       TMMLevel(Level).SetData(Val);
  376.    end;
  377.    {$IFNDEF LEVEL_ONLY}
  378.    procedure SetMeterValue(Meter: TMMCustomMeter; Val: Integer);
  379.    begin
  380.       TMMMeter(Meter).SetData(Val);
  381.    end;
  382.    {$ENDIF}
  383. begin
  384.    if not (csLoading in ComponentState) and
  385.       not (csReading in ComponentState) then
  386.    begin
  387.       GetLevelValues(LeftValue, RightValue, BothValue);
  388.       if assigned(FLevel1) then
  389.          if assigned(FLevel2) then
  390.             SetLevelValue(FLevel1, LeftValue)
  391.          else
  392.             SetLevelValue(Level1, BothValue);
  393.       if assigned(FLevel2) then SetLevelValue(FLevel2, RightValue);
  394.       {$IFNDEF LEVEL_ONLY}
  395.       if assigned(FMeter1) then
  396.          if assigned(FMeter2) then
  397.             SetMeterValue(FMeter1, LeftValue)
  398.          else
  399.             SetMeterValue(FMeter1, BothValue);
  400.       if assigned(FMeter2) then SetMeterValue(FMeter2, RightValue);
  401.       {$ENDIF}
  402.       if assigned(FOnTrigger) then FOnTrigger(Self);
  403.    end;
  404. end;
  405. end.