home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / DELPHIX.ZIP / Source / DXClass.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-10-06  |  15.8 KB  |  706 lines

  1. unit DXClass;
  2.  
  3. interface
  4.  
  5. {$INCLUDE DelphiXcfg.inc}
  6.  
  7. uses
  8.   Windows, Messages, SysUtils, Classes, Controls, Forms, MMSystem, DirectX;
  9.  
  10. type
  11.  
  12.   {  EDirectDrawError  }
  13.  
  14.   EDirectXError = class(Exception);
  15.  
  16.   {  TDirectX  }
  17.  
  18.   TDirectX = class(TPersistent)
  19.   private
  20.     procedure SetDXResult(Value: HRESULT);
  21.   protected
  22.     FDXResult: HRESULT;
  23.     procedure Check; virtual;
  24.   public
  25.     property DXResult: HRESULT read FDXResult write SetDXResult;
  26.   end;
  27.  
  28.   {  TDirectXDriver  }
  29.  
  30.   TDirectXDriver = class(TCollectionItem)
  31.   private
  32.     FGuid: PGUID;
  33.     FGuid2: TGUID;
  34.     FDescription: string;
  35.     FDriverName: string;
  36.     procedure SetGuid(Value: PGUID);
  37.   public
  38.     property Guid: PGUID read FGuid write SetGuid;
  39.     property Description: string read FDescription write FDescription;
  40.     property DriverName: string read FDriverName write FDriverName;
  41.   end;
  42.  
  43.   {  TDirectXDrivers  }
  44.  
  45.   TDirectXDrivers = class(TCollection)
  46.   private
  47.     function GetDriver(Index: Integer): TDirectXDriver;
  48.   public
  49.     constructor Create;
  50.     property Drivers[Index: Integer]: TDirectXDriver read GetDriver; default;
  51.   end;
  52.  
  53.   {  TDXForm  }
  54.  
  55.   TDXForm = class(TForm)
  56.   private
  57.     FStoreWindow: Boolean;
  58.     FWindowPlacement: TWindowPlacement;
  59.     procedure WMSYSCommand(var Msg: TWMSYSCommand); message WM_SYSCOMMAND;
  60.   protected
  61.     procedure CreateParams(var Params: TCreateParams); override;
  62.   public
  63.     constructor Create(AOnwer: TComponent); override;
  64.     destructor Destroy; override;
  65.     procedure RestoreWindow;
  66.     procedure StoreWindow;
  67.   end;
  68.  
  69.   {  TCustomDXTimer  }
  70.  
  71.   TDXTimerEvent = procedure(Sender: TObject; LagCount: Integer) of object;
  72.  
  73.   TCustomDXTimer = class(TComponent)
  74.   private
  75.     FActiveOnly: Boolean;
  76.     FEnabled: Boolean;
  77.     FFrameRate: Integer;
  78.     FInitialized: Boolean;
  79.     FInterval: Cardinal;
  80.     FInterval2: Cardinal;
  81.     FMaxLag: Integer;
  82.     FNowFrameRate: Integer;
  83.     FOldTime: DWORD;
  84.     FOldTime2: DWORD;
  85.     FOnActivate: TNotifyEvent;
  86.     FOnDeactivate: TNotifyEvent;
  87.     FOnTimer: TDXTimerEvent;
  88.     procedure AppIdle(Sender: TObject; var Done: Boolean);
  89.     function AppProc(var Message: TMessage): Boolean;
  90.     procedure Finalize;
  91.     procedure Initialize;
  92.     procedure Resume;
  93.     procedure SetActiveOnly(Value: Boolean);
  94.     procedure SetEnabled(Value: Boolean);
  95.     procedure SetInterval(Value: Cardinal);
  96.     procedure Suspend;
  97.   protected
  98.     procedure DoActivate; virtual;
  99.     procedure DoDeactivate; virtual;
  100.     procedure DoTimer(LagCount: Integer); virtual;
  101.     procedure Loaded; override;
  102.   public
  103.     constructor Create(AOwner: TComponent); override;
  104.     destructor Destroy; override;
  105.     property ActiveOnly: Boolean read FActiveOnly write SetActiveOnly;
  106.     property Enabled: Boolean read FEnabled write SetEnabled;
  107.     property FrameRate: Integer read FFrameRate;
  108.     property Interval: Cardinal read FInterval write SetInterval;
  109.     property MaxLag: Integer read FMaxLag write FMaxLag;
  110.     property OnActivate: TNotifyEvent read FOnActivate write FOnActivate;
  111.     property OnDeactivate: TNotifyEvent read FOnDeactivate write FOnDeactivate;
  112.     property OnTimer: TDXTimerEvent read FOnTimer write FOnTimer;
  113.   end;
  114.  
  115.   {  TDXTimer  }
  116.  
  117.   TDXTimer = class(TCustomDXTimer)
  118.   published
  119.     property ActiveOnly;
  120.     property Enabled;
  121.     property Interval;
  122.     property MaxLag;
  123.     property OnActivate;
  124.     property OnDeactivate;
  125.     property OnTimer;
  126.   end;
  127.  
  128.   {  TControlSubClass  }
  129.  
  130.   TControlSubClassEvent = procedure(var Message: TMessage; DefWindowProc: TWndMethod) of object;
  131.  
  132.   TControlSubClass = class
  133.   private
  134.     FControl: TControl;
  135.     FDefWindowProc: TWndMethod;
  136.     FWindowProc: TControlSubClassEvent;
  137.     procedure WndProc(var Message: TMessage);
  138.   public
  139.     constructor Create(Control: TControl; WindowProc: TControlSubClassEvent);
  140.     destructor Destroy; override;
  141.   end;
  142.  
  143.   {  THashCollectionItem  }
  144.  
  145.   THashCollectionItem = class(TCollectionItem)
  146.   private
  147.     FHashCode: Integer;
  148.     FIndex: Integer;
  149.     FName: string;
  150.     FLeft: THashCollectionItem;
  151.     FRight: THashCollectionItem;
  152.     procedure SetName(const Value: string);
  153.     procedure AddHash;
  154.     procedure DeleteHash;
  155.   protected
  156.     function GetDisplayName: string; override;
  157.     procedure SetIndex(Value: Integer); override;
  158.   public
  159.     constructor Create(Collection: TCollection); override;
  160.     destructor Destroy; override;
  161.     procedure Assign(Source: TPersistent); override;
  162.     property Index: Integer read FIndex write SetIndex;
  163.   published
  164.     property Name: string read FName write SetName;
  165.   end;
  166.  
  167.   {  THashCollection  }
  168.  
  169.   THashCollection = class(TCollection)
  170.   private
  171.     FHash: array[0..255] of THashCollectionItem;
  172.   public
  173.     function IndexOf(const Name: string): Integer;
  174.   end;
  175.  
  176. function Max(B1, B2: Integer): Integer;
  177. function Min(B1, B2: Integer): Integer;
  178.  
  179. function PointInRect(const Point: TPoint; const Rect: TRect): Boolean;
  180. function RectInRect(const Rect1, Rect2: TRect): Boolean;
  181. function OverlapRect(const Rect1, Rect2: TRect): Boolean;
  182.  
  183. function WideRect(ALeft, ATop, AWidth, AHeight: Integer): TRect;
  184.  
  185. function Cos256(i: Integer): Double;
  186. function Sin256(i: Integer): Double;
  187.  
  188. procedure ReleaseCom(out Com);
  189.  
  190. function DXLoadLibrary(const FileName, FuncName: string): TFarProc;
  191.  
  192. implementation
  193.  
  194. uses DXConsts;
  195.  
  196. function Max(B1, B2: Integer): Integer;
  197. begin
  198.   if B1>=B2 then Result := B1 else Result := B2;
  199. end;
  200.  
  201. function Min(B1, B2: Integer): Integer;
  202. begin
  203.   if B1<=B2 then Result := B1 else Result := B2;
  204. end;
  205.  
  206. function PointInRect(const Point: TPoint; const Rect: TRect): Boolean;
  207. begin
  208.   Result := (Point.X >= Rect.Left) and
  209.             (Point.X <= Rect.Right) and
  210.             (Point.Y >= Rect.Top) and
  211.             (Point.Y <= Rect.Bottom);
  212. end;
  213.  
  214. function RectInRect(const Rect1, Rect2: TRect): Boolean;
  215. begin
  216.   Result := (Rect1.Left >= Rect2.Left) and
  217.             (Rect1.Right <= Rect2.Right) and
  218.             (Rect1.Top >= Rect2.Top) and
  219.             (Rect1.Bottom <= Rect2.Bottom);
  220. end;
  221.  
  222. function OverlapRect(const Rect1, Rect2: TRect): Boolean;
  223. begin
  224.   Result := (Rect1.Left < Rect2.Right) and
  225.             (Rect1.Right > Rect2.Left) and
  226.             (Rect1.Top < Rect2.Bottom) and
  227.             (Rect1.Bottom > Rect2.Top);
  228. end;
  229.  
  230. function WideRect(ALeft, ATop, AWidth, AHeight: Integer): TRect;
  231. begin
  232.   with Result do
  233.   begin
  234.     Left := ALeft;
  235.     Top := ATop;
  236.     Right := ALeft+AWidth;
  237.     Bottom := ATop+AHeight;
  238.   end;
  239. end;
  240.  
  241. var
  242.   CosinTable: array[0..255] of Double;
  243.  
  244. procedure InitCosinTable;
  245. var
  246.   i: Integer;
  247. begin
  248.   for i:=0 to 255 do
  249.     CosinTable[i] := Cos((i/256)*2*PI);
  250. end;
  251.  
  252. function Cos256(i: Integer): Double;
  253. begin
  254.   Result := CosinTable[i and 255];
  255. end;
  256.  
  257. function Sin256(i: Integer): Double;
  258. begin
  259.   Result := CosinTable[(i+192) and 255];
  260. end;
  261.  
  262. procedure ReleaseCom(out Com);
  263. begin
  264. end;
  265.  
  266. var
  267.   LibList: TStringList;
  268.  
  269. function DXLoadLibrary(const FileName, FuncName: string): Pointer;
  270. var
  271.   i: Integer;
  272.   h: THandle;
  273. begin
  274.   if LibList=nil then
  275.     LibList := TStringList.Create;
  276.  
  277.   i := LibList.IndexOf(AnsiLowerCase(FileName));
  278.   if i=-1 then
  279.   begin
  280.     {  DLL is loaded.  }
  281.     h := LoadLibrary(PChar(FileName));
  282.     if h=0 then
  283.       raise Exception.CreateFmt(SDLLNotLoaded, [FileName]);
  284.     LibList.AddObject(AnsiLowerCase(FileName), Pointer(h));
  285.   end else
  286.   begin
  287.     {  DLL has already been loaded.  }
  288.     h := THandle(LibList.Objects[i]);
  289.   end;
  290.  
  291.   Result := GetProcAddress(h, PChar(FuncName));
  292.   if Result=nil then
  293.     raise Exception.CreateFmt(SDLLNotLoaded, [FileName]);
  294. end;
  295.  
  296. procedure FreeLibList;
  297. var
  298.   i: Integer;
  299. begin
  300.   if LibList<>nil then
  301.   begin
  302.     for i:=0 to LibList.Count-1 do
  303.       FreeLibrary(THandle(LibList.Objects[i]));
  304.     LibList.Free;
  305.   end;
  306. end;
  307.  
  308. {  TDirectX  }
  309.  
  310. procedure TDirectX.Check;
  311. begin
  312. end;
  313.  
  314. procedure TDirectX.SetDXResult(Value: HRESULT);
  315. begin
  316.   FDXResult := Value;
  317.   if FDXResult<>0 then Check;
  318. end;
  319.  
  320. {  TDirectXDriver  }
  321.  
  322. procedure TDirectXDriver.SetGuid(Value: PGUID);
  323. begin
  324.   if not IsBadHugeReadPtr(Value, SizeOf(TGUID)) then
  325.   begin
  326.     FGuid2 := Value^;
  327.     FGuid := @FGuid2;
  328.   end else
  329.     FGuid := Value;
  330. end;
  331.  
  332. {  TDirectXDrivers  }
  333.  
  334. constructor TDirectXDrivers.Create;
  335. begin
  336.   inherited Create(TDirectXDriver);
  337. end;
  338.  
  339. function TDirectXDrivers.GetDriver(Index: Integer): TDirectXDriver;
  340. begin
  341.   Result := (inherited Items[Index]) as TDirectXDriver;
  342. end;
  343.  
  344. {  TDXForm  }
  345.  
  346. var
  347.   SetAppExStyleCount: Integer;
  348.  
  349. constructor TDXForm.Create(AOnwer: TComponent);
  350. var
  351.   ExStyle: Integer;
  352. begin
  353.   inherited Create(AOnwer);
  354.   Inc(SetAppExStyleCount);
  355.   ExStyle := GetWindowLong(Application.Handle, GWL_EXSTYLE);
  356.   ExStyle := ExStyle or WS_EX_TOOLWINDOW;
  357.   SetWindowLong(Application.Handle, GWL_EXSTYLE, ExStyle);
  358. end;
  359.  
  360. destructor TDXForm.Destroy;
  361. var
  362.   ExStyle: Integer;
  363. begin
  364.   Dec(SetAppExStyleCount);
  365.   if SetAppExStyleCount=0 then
  366.   begin
  367.     ExStyle := GetWindowLong(Application.Handle, GWL_EXSTYLE);
  368.     ExStyle := ExStyle and (not WS_EX_TOOLWINDOW);
  369.     SetWindowLong(Application.Handle, GWL_EXSTYLE, ExStyle);
  370.   end;
  371.   inherited Destroy;
  372. end;
  373.  
  374. procedure TDXForm.CreateParams(var Params: TCreateParams);
  375. begin
  376.   inherited CreateParams(Params);
  377.   Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  378. end;
  379.  
  380. procedure TDXForm.RestoreWindow;
  381. begin
  382.   if FStoreWindow then
  383.   begin
  384.     SetWindowPlacement(Handle, @FWindowPlacement);
  385.     FStoreWindow := False;
  386.   end;
  387. end;
  388.  
  389. procedure TDXForm.StoreWindow;
  390. begin
  391.   FWindowPlacement.Length := SizeOf(FWindowPlacement);
  392.   FStoreWindow := GetWindowPlacement(Handle, @FWindowPlacement);
  393. end;
  394.  
  395. procedure TDXForm.WMSYSCommand(var Msg: TWMSYSCommand);
  396. begin
  397.   if Msg.CmdType = SC_MINIMIZE then
  398.   begin
  399.     DefaultHandler(Msg);
  400.     WindowState := wsMinimized;
  401.   end else
  402.     inherited;
  403. end;
  404.  
  405. {  TCustomDXTimer  }
  406.  
  407. constructor TCustomDXTimer.Create(AOwner: TComponent);
  408. begin
  409.   inherited Create(AOwner);
  410.   FActiveOnly := True;
  411.   FEnabled := True;
  412.   Interval := 1000;
  413.   FMaxLag := 10;
  414.   Application.HookMainWindow(AppProc);
  415. end;
  416.  
  417. destructor TCustomDXTimer.Destroy;
  418. begin
  419.   Finalize;
  420.   Application.UnHookMainWindow(AppProc);
  421.   inherited Destroy;
  422. end;
  423.  
  424. procedure TCustomDXTimer.AppIdle(Sender: TObject; var Done: Boolean);
  425. var
  426.   t, t2: DWORD;
  427.   LagCount, i: Integer;
  428. begin
  429.   Done := False;
  430.  
  431.   t := TimeGetTime;
  432.   t2 := t-FOldTime;
  433.   if t2>=FInterval then
  434.   begin
  435.     FOldTime := t;
  436.  
  437.     LagCount := t2 div FInterval2;
  438.     if FMaxLag>0 then
  439.       FMaxLag := Max(LagCount, FMaxLag);
  440.     LagCount := Max(LagCount, 1);
  441.  
  442.     Inc(FNowFrameRate);
  443.  
  444.     i := Max(t-FOldTime2, 1);
  445.     if i>=1000 then
  446.     begin
  447.       FFrameRate := Round(FNowFrameRate*1000/i);
  448.       FNowFrameRate := 0;
  449.       FOldTime2 := t;
  450.     end;
  451.  
  452.     DoTimer(LagCount);
  453.   end;
  454. end;
  455.  
  456. function TCustomDXTimer.AppProc(var Message: TMessage): Boolean;
  457. begin
  458.   Result := False;
  459.   case Message.Msg of
  460.     CM_ACTIVATE:
  461.         begin
  462.           DoActivate;
  463.           if FInitialized and FActiveOnly then Resume;
  464.         end;
  465.     CM_DEACTIVATE:
  466.         begin
  467.           DoDeactivate;
  468.           if FInitialized and FActiveOnly then Suspend;
  469.         end;
  470.   end;
  471. end;
  472.  
  473. procedure TCustomDXTimer.DoActivate;
  474. begin
  475.   if Assigned(FOnActivate) then FOnActivate(Self);
  476. end;
  477.  
  478. procedure TCustomDXTimer.DoDeactivate;
  479. begin
  480.   if Assigned(FOnDeactivate) then FOnDeactivate(Self);
  481. end;
  482.  
  483. procedure TCustomDXTimer.DoTimer(LagCount: Integer);
  484. begin
  485.   if Assigned(FOnTimer) then FOnTimer(Self, LagCount);
  486. end;
  487.  
  488. procedure TCustomDXTimer.Finalize;
  489. begin
  490.   if FInitialized then
  491.   begin
  492.     Suspend;
  493.     FInitialized := False;
  494.   end;
  495. end;
  496.  
  497. procedure TCustomDXTimer.Initialize;
  498. begin
  499.   Finalize;
  500.  
  501.   if ActiveOnly then
  502.   begin
  503.     if Application.Active then
  504.       Resume;
  505.   end else
  506.     Resume;
  507.   FInitialized := True;
  508. end;
  509.  
  510. procedure TCustomDXTimer.Loaded;
  511. begin
  512.   inherited Loaded;
  513.   if (not (csDesigning in ComponentState)) and FEnabled then
  514.     Initialize;
  515. end;
  516.  
  517. procedure TCustomDXTimer.Resume;
  518. begin
  519.   FOldTime := TimeGetTime;
  520.   FOldTime2 := TimeGetTime;
  521.   Application.OnIdle := AppIdle;
  522. end;
  523.  
  524. procedure TCustomDXTimer.SetActiveOnly(Value: Boolean);
  525. begin
  526.   if FActiveOnly<>Value then
  527.   begin
  528.     FActiveOnly := Value;
  529.  
  530.     if Application.Active and FActiveOnly then
  531.       if FInitialized and FActiveOnly then Suspend;
  532.   end;
  533. end;
  534.  
  535. procedure TCustomDXTimer.SetEnabled(Value: Boolean);
  536. begin
  537.   if FEnabled<>Value then
  538.   begin
  539.     FEnabled := Value;
  540.     if ComponentState*[csReading, csLoading]=[] then
  541.       if FEnabled then Initialize else Finalize;
  542.   end;
  543. end;
  544.  
  545. procedure TCustomDXTimer.SetInterval(Value: Cardinal);
  546. begin
  547.   if FInterval<>Value then
  548.   begin
  549.     FInterval := Max(Value, 0);
  550.     FInterval2 := Max(Value, 1);
  551.   end;
  552. end;
  553.  
  554. procedure TCustomDXTimer.Suspend;
  555. begin
  556.   Application.OnIdle := nil;
  557. end;
  558.  
  559. {  TControlSubClass  }
  560.  
  561. constructor TControlSubClass.Create(Control: TControl;
  562.   WindowProc: TControlSubClassEvent);
  563. begin
  564.   inherited Create;
  565.   FControl := Control;
  566.   FDefWindowProc := FControl.WindowProc;
  567.   FControl.WindowProc := WndProc;
  568.   FWindowProc := WindowProc;
  569. end;
  570.  
  571. destructor TControlSubClass.Destroy;
  572. begin
  573.   FControl.WindowProc := FDefWindowProc;
  574.   inherited Destroy;
  575. end;
  576.  
  577. procedure TControlSubClass.WndProc(var Message: TMessage);
  578. begin
  579.   FWindowProc(Message, FDefWindowProc);
  580. end;
  581.  
  582. {  THashCollectionItem  }
  583.  
  584. function MakeHashCode(const Str: string): Integer;
  585. var
  586.   s: string;
  587. begin
  588.   s := AnsiLowerCase(Str);
  589.   Result := Length(s)*16;
  590.   if Length(s)>=2 then
  591.     Result := Result + (Ord(s[1]) + Ord(s[Length(s)-1]));
  592.   Result := Result and 255;
  593. end;
  594.  
  595. constructor THashCollectionItem.Create(Collection: TCollection);
  596. begin
  597.   inherited Create(Collection);
  598.   FIndex := inherited Index;
  599.   AddHash;
  600. end;
  601.  
  602. destructor THashCollectionItem.Destroy;
  603. var
  604.   i: Integer;
  605. begin
  606.   for i:=FIndex+1 to Collection.Count-1 do
  607.     Dec(THashCollectionItem(Collection.Items[i]).FIndex);
  608.   DeleteHash;
  609.   inherited Destroy;
  610. end;
  611.  
  612. procedure THashCollectionItem.Assign(Source: TPersistent);
  613. begin
  614.   if Source is THashCollectionItem then
  615.   begin
  616.     Name := THashCollectionItem(Source).Name;
  617.   end else
  618.     inherited Assign(Source);
  619. end;
  620.  
  621. procedure THashCollectionItem.AddHash;
  622. var
  623.   Item: THashCollectionItem;
  624. begin
  625.   FHashCode := MakeHashCode(FName);
  626.  
  627.   Item := THashCollection(Collection).FHash[FHashCode];
  628.   if Item<>nil then
  629.   begin
  630.     Item.FLeft := Self;
  631.     Self.FRight := Item;
  632.   end;
  633.  
  634.   THashCollection(Collection).FHash[FHashCode] := Self;
  635. end;
  636.  
  637. procedure THashCollectionItem.DeleteHash;
  638. begin
  639.   if FLeft<>nil then
  640.   begin
  641.     FLeft.FRight := FRight;
  642.     if FRight<>nil then
  643.       FRight.FLeft := FLeft;
  644.   end else
  645.   begin
  646.     if FHashCode<>-1 then
  647.     begin
  648.       THashCollection(Collection).FHash[FHashCode] := FRight;
  649.       if FRight<>nil then
  650.         FRight.FLeft := nil;
  651.     end;
  652.   end;
  653.   FLeft := nil;
  654.   FRight := nil;
  655. end;
  656.  
  657. function THashCollectionItem.GetDisplayName: string;
  658. begin
  659.   Result := Name;
  660.   if Result='' then Result := inherited GetDisplayName;
  661. end;
  662.  
  663. procedure THashCollectionItem.SetIndex(Value: Integer);
  664. begin
  665.   if FIndex<>Value then
  666.   begin
  667.     FIndex := Value;
  668.     inherited SetIndex(Value);
  669.   end;
  670. end;
  671.  
  672. procedure THashCollectionItem.SetName(const Value: string);
  673. begin
  674.   if FName<>Value then
  675.   begin
  676.     FName := Value;
  677.     DeleteHash;
  678.     AddHash;
  679.   end;
  680. end;
  681.  
  682. {  THashCollection  }
  683.  
  684. function THashCollection.IndexOf(const Name: string): Integer;
  685. var
  686.   Item: THashCollectionItem;
  687. begin
  688.   Item := FHash[MakeHashCode(Name)];
  689.   while Item<>nil do
  690.   begin
  691.     if AnsiCompareText(Item.Name, Name)=0 then
  692.     begin
  693.       Result := Item.FIndex;
  694.       Exit;
  695.     end;
  696.     Item := Item.FRight;
  697.   end;
  698.   Result := -1;
  699. end;
  700.  
  701. initialization
  702.   InitCosinTable;
  703. finalization
  704.   FreeLibList;
  705. end.
  706.