Rev 1 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | daniel-mar | 1 | unit DXClass; |
2 | |||
3 | interface |
||
4 | |||
5 | {$INCLUDE DelphiXcfg.inc} |
||
6 | |||
7 | uses |
||
4 | daniel-mar | 8 | Windows, Messages, SysUtils, Classes, Controls, Forms, MMSystem, Graphics, {$IFDEF _DMO_}MultiMon,{$ENDIF} |
9 | {$IfDef StandardDX} |
||
10 | {$IfDef DX9} |
||
11 | Direct3D, DirectInput, |
||
12 | {$EndIf} |
||
13 | DirectDraw, DirectSound; |
||
14 | {$Else} |
||
15 | DirectX; |
||
16 | {$EndIf} |
||
1 | daniel-mar | 17 | |
18 | type |
||
19 | |||
20 | { EDirectDrawError } |
||
21 | |||
22 | EDirectXError = class(Exception); |
||
23 | |||
24 | { TDirectX } |
||
25 | |||
26 | TDirectX = class(TPersistent) |
||
27 | private |
||
28 | procedure SetDXResult(Value: HRESULT); |
||
29 | protected |
||
30 | FDXResult: HRESULT; |
||
31 | procedure Check; virtual; |
||
32 | public |
||
33 | property DXResult: HRESULT read FDXResult write SetDXResult; |
||
34 | end; |
||
35 | |||
36 | { TDirectXDriver } |
||
37 | |||
38 | TDirectXDriver = class(TCollectionItem) |
||
39 | private |
||
40 | FGUID: PGUID; |
||
41 | FGUID2: TGUID; |
||
42 | FDescription: string; |
||
43 | FDriverName: string; |
||
44 | procedure SetGUID(Value: PGUID); |
||
45 | public |
||
46 | property GUID: PGUID read FGUID write SetGUID; |
||
47 | property Description: string read FDescription write FDescription; |
||
48 | property DriverName: string read FDriverName write FDriverName; |
||
49 | end; |
||
50 | |||
51 | { TDirectXDrivers } |
||
52 | |||
53 | TDirectXDrivers = class(TCollection) |
||
54 | private |
||
55 | function GetDriver(Index: Integer): TDirectXDriver; |
||
56 | public |
||
57 | constructor Create; |
||
58 | property Drivers[Index: Integer]: TDirectXDriver read GetDriver; default; |
||
59 | end; |
||
60 | |||
4 | daniel-mar | 61 | {$IFDEF _DMO_} |
62 | { TDirectXDriverEx } |
||
63 | |||
64 | TDirectXDriverEx = class(TCollectionItem) |
||
65 | private |
||
66 | FGUID: PGUID; |
||
67 | FGUID2: TGUID; |
||
68 | FDescription: string; |
||
69 | FDriverName: string; |
||
70 | FMonitor: HMonitor; |
||
71 | FMonitorInfo: TMonitorInfo; |
||
72 | procedure SetGUID(Value: PGUID); |
||
73 | function ConvertHMonitor(iMonitor: HMonitor): TMonitorInfo; |
||
74 | function GetMonitorInfo: TMonitorInfo; |
||
75 | function GetFlags: DWORD; |
||
76 | function GetTempSpace: TRect; |
||
77 | function GetWorkSpace: TRect; |
||
78 | public |
||
79 | property GUID: PGUID read FGUID write SetGUID; |
||
80 | property Monitor: HMonitor read FMonitor write FMonitor; |
||
81 | property MonitorInfo: TMonitorInfo read GetMonitorInfo; |
||
82 | published |
||
83 | property Description: string read FDescription write FDescription; |
||
84 | property DriverName: string read FDriverName write FDriverName; |
||
85 | property WorkSpace: TRect read GetWorkSpace; |
||
86 | property TempSpace: TRect read GetTempSpace; |
||
87 | property Flags: DWORD read GetFlags; |
||
88 | end; |
||
89 | |||
90 | { TDirectXDriversEx } |
||
91 | |||
92 | TDirectXDriversEx = class(TCollection) |
||
93 | private |
||
94 | function GetDriver(Index: Integer): TDirectXDriverEx; |
||
95 | public |
||
96 | constructor Create; |
||
97 | property Drivers[Index: Integer]: TDirectXDriverEx read GetDriver; default; |
||
98 | end; |
||
99 | {$ENDIF} |
||
100 | |||
1 | daniel-mar | 101 | { TDXForm } |
102 | |||
103 | TDXForm = class(TForm) |
||
104 | private |
||
105 | FStoreWindow: Boolean; |
||
106 | FWindowPlacement: TWindowPlacement; |
||
107 | procedure WMSYSCommand(var Msg: TWMSYSCommand); message WM_SYSCOMMAND; |
||
108 | protected |
||
109 | procedure CreateParams(var Params: TCreateParams); override; |
||
110 | public |
||
111 | constructor Create(AOnwer: TComponent); override; |
||
112 | destructor Destroy; override; |
||
113 | procedure RestoreWindow; |
||
114 | procedure StoreWindow; |
||
115 | end; |
||
116 | |||
117 | { TCustomDXTimer } |
||
118 | |||
119 | TDXTimerEvent = procedure(Sender: TObject; LagCount: Integer) of object; |
||
120 | |||
121 | TCustomDXTimer = class(TComponent) |
||
122 | private |
||
123 | FActiveOnly: Boolean; |
||
124 | FEnabled: Boolean; |
||
125 | FFrameRate: Integer; |
||
126 | FInitialized: Boolean; |
||
127 | FInterval: Cardinal; |
||
128 | FInterval2: Cardinal; |
||
129 | FNowFrameRate: Integer; |
||
130 | FOldTime: DWORD; |
||
131 | FOldTime2: DWORD; |
||
132 | FOnActivate: TNotifyEvent; |
||
133 | FOnDeactivate: TNotifyEvent; |
||
134 | FOnTimer: TDXTimerEvent; |
||
135 | procedure AppIdle(Sender: TObject; var Done: Boolean); |
||
136 | function AppProc(var Message: TMessage): Boolean; |
||
137 | procedure Finalize; |
||
138 | procedure Initialize; |
||
139 | procedure Resume; |
||
140 | procedure SetActiveOnly(Value: Boolean); |
||
141 | procedure SetEnabled(Value: Boolean); |
||
142 | procedure SetInterval(Value: Cardinal); |
||
143 | procedure Suspend; |
||
144 | protected |
||
145 | procedure DoActivate; virtual; |
||
146 | procedure DoDeactivate; virtual; |
||
147 | procedure DoTimer(LagCount: Integer); virtual; |
||
148 | procedure Loaded; override; |
||
149 | public |
||
150 | constructor Create(AOwner: TComponent); override; |
||
151 | destructor Destroy; override; |
||
152 | property ActiveOnly: Boolean read FActiveOnly write SetActiveOnly; |
||
153 | property Enabled: Boolean read FEnabled write SetEnabled; |
||
154 | property FrameRate: Integer read FFrameRate; |
||
155 | property Interval: Cardinal read FInterval write SetInterval; |
||
156 | property OnActivate: TNotifyEvent read FOnActivate write FOnActivate; |
||
157 | property OnDeactivate: TNotifyEvent read FOnDeactivate write FOnDeactivate; |
||
158 | property OnTimer: TDXTimerEvent read FOnTimer write FOnTimer; |
||
159 | end; |
||
160 | |||
161 | { TDXTimer } |
||
162 | |||
163 | TDXTimer = class(TCustomDXTimer) |
||
164 | published |
||
165 | property ActiveOnly; |
||
166 | property Enabled; |
||
167 | property Interval; |
||
168 | property OnActivate; |
||
169 | property OnDeactivate; |
||
170 | property OnTimer; |
||
171 | end; |
||
172 | |||
173 | { TControlSubClass } |
||
174 | |||
175 | TControlSubClassProc = procedure(var Message: TMessage; DefWindowProc: TWndMethod) of object; |
||
176 | |||
177 | TControlSubClass = class |
||
178 | private |
||
179 | FControl: TControl; |
||
180 | FDefWindowProc: TWndMethod; |
||
181 | FWindowProc: TControlSubClassProc; |
||
182 | procedure WndProc(var Message: TMessage); |
||
183 | public |
||
184 | constructor Create(Control: TControl; WindowProc: TControlSubClassProc); |
||
185 | destructor Destroy; override; |
||
186 | end; |
||
187 | |||
188 | { THashCollectionItem } |
||
189 | |||
190 | THashCollectionItem = class(TCollectionItem) |
||
191 | private |
||
192 | FHashCode: Integer; |
||
193 | FIndex: Integer; |
||
194 | FName: string; |
||
195 | FLeft: THashCollectionItem; |
||
196 | FRight: THashCollectionItem; |
||
197 | procedure SetName(const Value: string); |
||
198 | procedure AddHash; |
||
199 | procedure DeleteHash; |
||
200 | protected |
||
201 | function GetDisplayName: string; override; |
||
202 | procedure SetIndex(Value: Integer); override; |
||
203 | public |
||
204 | constructor Create(Collection: TCollection); override; |
||
205 | destructor Destroy; override; |
||
206 | procedure Assign(Source: TPersistent); override; |
||
207 | property Index: Integer read FIndex write SetIndex; |
||
208 | published |
||
209 | property Name: string read FName write SetName; |
||
210 | end; |
||
211 | |||
212 | { THashCollection } |
||
213 | |||
214 | THashCollection = class(TCollection) |
||
215 | private |
||
216 | FHash: array[0..255] of THashCollectionItem; |
||
217 | public |
||
218 | function IndexOf(const Name: string): Integer; |
||
219 | end; |
||
220 | |||
4 | daniel-mar | 221 | {Addapted from RXLib.PicClip} |
1 | daniel-mar | 222 | |
4 | daniel-mar | 223 | { TPicClip } |
224 | TCellRange = 1..MaxInt; |
||
225 | |||
226 | TDXPictureClip = class(TComponent) |
||
227 | private |
||
228 | FPicture: TPicture; |
||
229 | FRows: TCellRange; |
||
230 | FCols: TCellRange; |
||
231 | FBitmap: TBitmap; |
||
232 | FMasked: Boolean; |
||
233 | FMaskColor: TColor; |
||
234 | FOnChange: TNotifyEvent; |
||
235 | procedure CheckIndex(Index: Integer); |
||
236 | function GetCell(Col, Row: Cardinal): TBitmap; |
||
237 | function GetGraphicCell(Index: Integer): TBitmap; |
||
238 | function GetDefaultMaskColor: TColor; |
||
239 | function GetIsEmpty: Boolean; |
||
240 | function GetCount: Integer; |
||
241 | function GetHeight: Integer; |
||
242 | function GetWidth: Integer; |
||
243 | function IsMaskStored: Boolean; |
||
244 | procedure PictureChanged(Sender: TObject); |
||
245 | procedure SetHeight(Value: Integer); |
||
246 | procedure SetPicture(Value: TPicture); |
||
247 | procedure SetWidth(Value: Integer); |
||
248 | procedure SetMaskColor(Value: TColor); |
||
249 | protected |
||
250 | procedure AssignTo(Dest: TPersistent); override; |
||
251 | procedure Changed; dynamic; |
||
252 | public |
||
253 | constructor Create(AOwner: TComponent); override; |
||
254 | destructor Destroy; override; |
||
255 | procedure Assign(Source: TPersistent); override; |
||
256 | function GetIndex(Col, Row: Cardinal): Integer; |
||
257 | procedure Draw(Canvas: TCanvas; X, Y, Index: Integer); |
||
258 | procedure DrawCenter(Canvas: TCanvas; Rect: TRect; Index: Integer); |
||
259 | property Cells[Col, Row: Cardinal]: TBitmap read GetCell; |
||
260 | property GraphicCell[Index: Integer]: TBitmap read GetGraphicCell; |
||
261 | property IsEmpty: Boolean read GetIsEmpty; |
||
262 | property Count: Integer read GetCount; |
||
263 | published |
||
264 | property Cols: TCellRange read FCols write FCols default 1; |
||
265 | property Height: Integer read GetHeight write SetHeight stored False; |
||
266 | property Masked: Boolean read FMasked write FMasked default True; |
||
267 | property Rows: TCellRange read FRows write FRows default 1; |
||
268 | property Picture: TPicture read FPicture write SetPicture; |
||
269 | property MaskColor: TColor read FMaskColor write SetMaskColor stored IsMaskStored; |
||
270 | property Width: Integer read GetWidth write SetWidth stored False; |
||
271 | property OnChange: TNotifyEvent read FOnChange write FOnChange; |
||
272 | end; |
||
273 | |||
274 | function Max(Val1, Val2: Integer): Integer; {$IFDEF VER9UP}inline;{$ENDIF} |
||
275 | function Min(Val1, Val2: Integer): Integer; {$IFDEF VER9UP}inline;{$ENDIF} |
||
276 | |||
1 | daniel-mar | 277 | function Cos256(i: Integer): Double; |
278 | function Sin256(i: Integer): Double; |
||
279 | |||
4 | daniel-mar | 280 | function PointInRect(const Point: TPoint; const Rect: TRect): Boolean; {$IFDEF VER9UP}inline;{$ENDIF} |
281 | function RectInRect(const Rect1, Rect2: TRect): Boolean; {$IFDEF VER9UP}inline;{$ENDIF} |
||
282 | function OverlapRect(const Rect1, Rect2: TRect): Boolean; {$IFDEF VER9UP}inline;{$ENDIF} |
||
1 | daniel-mar | 283 | |
4 | daniel-mar | 284 | function WideRect(ALeft, ATop, AWidth, AHeight: Integer): TRect; {$IFDEF VER9UP}inline;{$ENDIF} |
285 | |||
286 | { Transformations routines} |
||
287 | |||
288 | const |
||
289 | L_Curve = 0;//The left curve |
||
290 | R_Curve = 1;//The right curve |
||
291 | |||
292 | C_Add = 0;//Increase (BTC) |
||
293 | C_Dec = 1;//Decrease (ETC) |
||
294 | |||
295 | Type |
||
296 | TDblPoint = packed record |
||
297 | X, Y: Double; |
||
298 | end; |
||
299 | TSngPoint = packed record //SinglePoint |
||
300 | X, Y: Single; |
||
301 | end; |
||
302 | |||
303 | |||
304 | //Transformation matrix |
||
305 | T2DRowCol = Array[1..3] of Array[1..3] of Double; |
||
306 | T2DVector = Array[1..3] of Double; |
||
307 | //Distance between 2 points |
||
308 | function Get2PointRange(a,b: TDblPoint):Double; |
||
309 | //From vector angular calculation |
||
310 | function Get256(dX,dY: Double):Double; |
||
311 | //The angular calculation of the A from B |
||
312 | function GetARadFromB(A,B: TDblPoint):Double; |
||
313 | |||
314 | //It calculates the TDblPoint |
||
315 | function DblPoint(a,b:Double):TDblPoint; |
||
316 | //It converts the TDboPoint to the TPoint |
||
317 | function TruncDblPoint(DblPos: TDblPoint): TPoint; |
||
318 | |||
319 | function GetPointFromRangeAndAngle(SP: TDblPoint; Range,Angle: Double): TDblPoint; |
||
320 | |||
321 | function Ini2DRowCol: T2DRowCol; |
||
322 | function Trans2DRowCol(x,y:double):T2DRowCol; |
||
323 | function Scale2DRowCol(x,y:double):T2DRowCol; |
||
324 | function Rotate2DRowCol(Theta:double):T2DRowCol; |
||
325 | function RotateIntoX2DRowCol(x,y: double):T2DRowCol; |
||
326 | function Multiply2DRowCol(A,B:T2DRowCol):T2DRowCol; |
||
327 | function ScaleAt2DRowCol(x,y,Sx,Sy:double):T2DRowCol; |
||
328 | function ReflectAcross2DRowCol(x,y,dx,dy:Double): T2DRowCol; |
||
329 | function Apply2DVector(V:T2DVector; M:T2DRowCol): T2DVector; |
||
330 | function RotateAround2DRowCol(x,y,Theta:Double): T2DRowCol; |
||
331 | |||
332 | //Collision decision |
||
333 | function PointInCircle(PPos,CPos: TPoint; R: integer): Boolean; |
||
334 | function CircleInCircle(C1Pos,C2Pos: TPoint; R1,R2:Integer): Boolean; |
||
335 | function SegmentInCircle(SPos,EPos,CPos: TPoint; R: Integer): Boolean; |
||
336 | |||
337 | //If A is closer than B from starting point S, the True is returned. |
||
338 | function CheckNearAThanB(S,A,B: TDblPoint): Boolean; |
||
339 | |||
340 | //The Angle of 256 period is returned |
||
341 | function Angle256(Angle: Single): Single; |
||
342 | |||
343 | { Support functions } |
||
344 | |||
1 | daniel-mar | 345 | procedure ReleaseCom(out Com); |
346 | function DXLoadLibrary(const FileName, FuncName: string): TFarProc; |
||
347 | |||
4 | daniel-mar | 348 | { Simple helper } |
349 | |||
350 | procedure Log(const Co: string; const FName: string{$IFDEF VER4UP} = 'c:\logerr.txt'{$ENDIF}); |
||
351 | |||
1 | daniel-mar | 352 | implementation |
353 | |||
354 | uses DXConsts; |
||
355 | |||
356 | function Max(Val1, Val2: Integer): Integer; |
||
357 | begin |
||
358 | if Val1>=Val2 then Result := Val1 else Result := Val2; |
||
359 | end; |
||
360 | |||
361 | function Min(Val1, Val2: Integer): Integer; |
||
362 | begin |
||
363 | if Val1<=Val2 then Result := Val1 else Result := Val2; |
||
364 | end; |
||
365 | |||
366 | function PointInRect(const Point: TPoint; const Rect: TRect): Boolean; |
||
367 | begin |
||
368 | Result := (Point.X >= Rect.Left) and |
||
369 | (Point.X <= Rect.Right) and |
||
370 | (Point.Y >= Rect.Top) and |
||
371 | (Point.Y <= Rect.Bottom); |
||
372 | end; |
||
373 | |||
374 | function RectInRect(const Rect1, Rect2: TRect): Boolean; |
||
375 | begin |
||
376 | Result := (Rect1.Left >= Rect2.Left) and |
||
377 | (Rect1.Right <= Rect2.Right) and |
||
378 | (Rect1.Top >= Rect2.Top) and |
||
379 | (Rect1.Bottom <= Rect2.Bottom); |
||
380 | end; |
||
381 | |||
382 | function OverlapRect(const Rect1, Rect2: TRect): Boolean; |
||
383 | begin |
||
384 | Result := (Rect1.Left < Rect2.Right) and |
||
385 | (Rect1.Right > Rect2.Left) and |
||
386 | (Rect1.Top < Rect2.Bottom) and |
||
387 | (Rect1.Bottom > Rect2.Top); |
||
388 | end; |
||
389 | |||
390 | function WideRect(ALeft, ATop, AWidth, AHeight: Integer): TRect; |
||
391 | begin |
||
392 | with Result do |
||
393 | begin |
||
394 | Left := ALeft; |
||
395 | Top := ATop; |
||
396 | Right := ALeft+AWidth; |
||
397 | Bottom := ATop+AHeight; |
||
398 | end; |
||
399 | end; |
||
400 | |||
401 | var |
||
402 | CosinTable: array[0..255] of Double; |
||
403 | |||
404 | procedure InitCosinTable; |
||
405 | var |
||
406 | i: Integer; |
||
407 | begin |
||
408 | for i:=0 to 255 do |
||
409 | CosinTable[i] := Cos((i/256)*2*PI); |
||
410 | end; |
||
411 | |||
412 | function Cos256(i: Integer): Double; |
||
413 | begin |
||
414 | Result := CosinTable[i and 255]; |
||
415 | end; |
||
416 | |||
417 | function Sin256(i: Integer): Double; |
||
418 | begin |
||
419 | Result := CosinTable[(i+192) and 255]; |
||
420 | end; |
||
421 | |||
422 | procedure ReleaseCom(out Com); |
||
423 | begin |
||
424 | end; |
||
425 | |||
426 | var |
||
427 | LibList: TStringList; |
||
428 | |||
429 | function DXLoadLibrary(const FileName, FuncName: string): Pointer; |
||
430 | var |
||
431 | i: Integer; |
||
432 | h: THandle; |
||
433 | begin |
||
434 | if LibList=nil then |
||
435 | LibList := TStringList.Create; |
||
436 | |||
437 | i := LibList.IndexOf(AnsiLowerCase(FileName)); |
||
438 | if i=-1 then |
||
439 | begin |
||
440 | { DLL is loaded. } |
||
441 | h := LoadLibrary(PChar(FileName)); |
||
442 | if h=0 then |
||
443 | raise Exception.CreateFmt(SDLLNotLoaded, [FileName]); |
||
444 | LibList.AddObject(AnsiLowerCase(FileName), Pointer(h)); |
||
445 | end else |
||
446 | begin |
||
447 | { DLL has already been loaded. } |
||
448 | h := THandle(LibList.Objects[i]); |
||
449 | end; |
||
450 | |||
451 | Result := GetProcAddress(h, PChar(FuncName)); |
||
452 | if Result=nil then |
||
453 | raise Exception.CreateFmt(SDLLNotLoaded, [FileName]); |
||
454 | end; |
||
455 | |||
456 | procedure FreeLibList; |
||
457 | var |
||
458 | i: Integer; |
||
459 | begin |
||
460 | if LibList<>nil then |
||
461 | begin |
||
462 | for i:=0 to LibList.Count-1 do |
||
463 | FreeLibrary(THandle(LibList.Objects[i])); |
||
464 | LibList.Free; |
||
465 | end; |
||
466 | end; |
||
467 | |||
468 | { TDirectX } |
||
469 | |||
470 | procedure TDirectX.Check; |
||
471 | begin |
||
472 | end; |
||
473 | |||
474 | procedure TDirectX.SetDXResult(Value: HRESULT); |
||
475 | begin |
||
476 | FDXResult := Value; |
||
477 | if FDXResult<>0 then Check; |
||
478 | end; |
||
479 | |||
480 | { TDirectXDriver } |
||
481 | |||
482 | procedure TDirectXDriver.SetGUID(Value: PGUID); |
||
483 | begin |
||
484 | if not IsBadHugeReadPtr(Value, SizeOf(TGUID)) then |
||
485 | begin |
||
486 | FGUID2 := Value^; |
||
487 | FGUID := @FGUID2; |
||
488 | end else |
||
489 | FGUID := Value; |
||
490 | end; |
||
491 | |||
492 | { TDirectXDrivers } |
||
493 | |||
494 | constructor TDirectXDrivers.Create; |
||
495 | begin |
||
496 | inherited Create(TDirectXDriver); |
||
497 | end; |
||
498 | |||
499 | function TDirectXDrivers.GetDriver(Index: Integer): TDirectXDriver; |
||
500 | begin |
||
501 | Result := (inherited Items[Index]) as TDirectXDriver; |
||
502 | end; |
||
503 | |||
504 | { TDXForm } |
||
505 | |||
506 | var |
||
507 | SetAppExStyleCount: Integer; |
||
508 | |||
509 | constructor TDXForm.Create(AOnwer: TComponent); |
||
510 | var |
||
511 | ExStyle: Integer; |
||
512 | begin |
||
513 | inherited Create(AOnwer); |
||
514 | Inc(SetAppExStyleCount); |
||
515 | ExStyle := GetWindowLong(Application.Handle, GWL_EXSTYLE); |
||
516 | ExStyle := ExStyle or WS_EX_TOOLWINDOW; |
||
517 | SetWindowLong(Application.Handle, GWL_EXSTYLE, ExStyle); |
||
518 | end; |
||
519 | |||
520 | destructor TDXForm.Destroy; |
||
521 | var |
||
522 | ExStyle: Integer; |
||
523 | begin |
||
524 | Dec(SetAppExStyleCount); |
||
525 | if SetAppExStyleCount=0 then |
||
526 | begin |
||
527 | ExStyle := GetWindowLong(Application.Handle, GWL_EXSTYLE); |
||
528 | ExStyle := ExStyle and (not WS_EX_TOOLWINDOW); |
||
529 | SetWindowLong(Application.Handle, GWL_EXSTYLE, ExStyle); |
||
530 | end; |
||
531 | inherited Destroy; |
||
532 | end; |
||
533 | |||
534 | procedure TDXForm.CreateParams(var Params: TCreateParams); |
||
535 | begin |
||
536 | inherited CreateParams(Params); |
||
537 | Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW; |
||
538 | end; |
||
539 | |||
540 | procedure TDXForm.RestoreWindow; |
||
541 | begin |
||
542 | if FStoreWindow then |
||
543 | begin |
||
544 | SetWindowPlacement(Handle, @FWindowPlacement); |
||
545 | FStoreWindow := False; |
||
546 | end; |
||
547 | end; |
||
548 | |||
549 | procedure TDXForm.StoreWindow; |
||
550 | begin |
||
551 | FWindowPlacement.Length := SizeOf(FWindowPlacement); |
||
552 | FStoreWindow := GetWindowPlacement(Handle, @FWindowPlacement); |
||
553 | end; |
||
554 | |||
555 | procedure TDXForm.WMSYSCommand(var Msg: TWMSYSCommand); |
||
556 | begin |
||
557 | if Msg.CmdType = SC_MINIMIZE then |
||
558 | begin |
||
559 | DefaultHandler(Msg); |
||
560 | WindowState := wsMinimized; |
||
561 | end else |
||
562 | inherited; |
||
563 | end; |
||
564 | |||
565 | { TCustomDXTimer } |
||
566 | |||
567 | constructor TCustomDXTimer.Create(AOwner: TComponent); |
||
568 | begin |
||
569 | inherited Create(AOwner); |
||
570 | FActiveOnly := True; |
||
571 | FEnabled := True; |
||
572 | Interval := 1000; |
||
573 | Application.HookMainWindow(AppProc); |
||
574 | end; |
||
575 | |||
576 | destructor TCustomDXTimer.Destroy; |
||
577 | begin |
||
578 | Finalize; |
||
579 | Application.UnHookMainWindow(AppProc); |
||
580 | inherited Destroy; |
||
581 | end; |
||
582 | |||
583 | procedure TCustomDXTimer.AppIdle(Sender: TObject; var Done: Boolean); |
||
584 | var |
||
585 | t, t2: DWORD; |
||
586 | LagCount, i: Integer; |
||
587 | begin |
||
588 | Done := False; |
||
589 | |||
590 | t := TimeGetTime; |
||
591 | t2 := t-FOldTime; |
||
592 | if t2>=FInterval then |
||
593 | begin |
||
594 | FOldTime := t; |
||
595 | |||
596 | LagCount := t2 div FInterval2; |
||
597 | if LagCount<1 then LagCount := 1; |
||
598 | |||
599 | Inc(FNowFrameRate); |
||
600 | |||
601 | i := Max(t-FOldTime2, 1); |
||
602 | if i>=1000 then |
||
603 | begin |
||
604 | FFrameRate := Round(FNowFrameRate*1000/i); |
||
605 | FNowFrameRate := 0; |
||
606 | FOldTime2 := t; |
||
607 | end; |
||
608 | |||
609 | DoTimer(LagCount); |
||
610 | end; |
||
611 | end; |
||
612 | |||
613 | function TCustomDXTimer.AppProc(var Message: TMessage): Boolean; |
||
614 | begin |
||
615 | Result := False; |
||
616 | case Message.Msg of |
||
617 | CM_ACTIVATE: |
||
618 | begin |
||
619 | DoActivate; |
||
620 | if FInitialized and FActiveOnly then Resume; |
||
621 | end; |
||
622 | CM_DEACTIVATE: |
||
623 | begin |
||
624 | DoDeactivate; |
||
625 | if FInitialized and FActiveOnly then Suspend; |
||
626 | end; |
||
627 | end; |
||
628 | end; |
||
629 | |||
630 | procedure TCustomDXTimer.DoActivate; |
||
631 | begin |
||
632 | if Assigned(FOnActivate) then FOnActivate(Self); |
||
633 | end; |
||
634 | |||
635 | procedure TCustomDXTimer.DoDeactivate; |
||
636 | begin |
||
637 | if Assigned(FOnDeactivate) then FOnDeactivate(Self); |
||
638 | end; |
||
639 | |||
640 | procedure TCustomDXTimer.DoTimer(LagCount: Integer); |
||
641 | begin |
||
642 | if Assigned(FOnTimer) then FOnTimer(Self, LagCount); |
||
643 | end; |
||
644 | |||
645 | procedure TCustomDXTimer.Finalize; |
||
646 | begin |
||
647 | if FInitialized then |
||
648 | begin |
||
649 | Suspend; |
||
650 | FInitialized := False; |
||
651 | end; |
||
652 | end; |
||
653 | |||
654 | procedure TCustomDXTimer.Initialize; |
||
655 | begin |
||
656 | Finalize; |
||
657 | |||
658 | if ActiveOnly then |
||
659 | begin |
||
660 | if Application.Active then |
||
661 | Resume; |
||
662 | end else |
||
663 | Resume; |
||
664 | FInitialized := True; |
||
665 | end; |
||
666 | |||
667 | procedure TCustomDXTimer.Loaded; |
||
668 | begin |
||
669 | inherited Loaded; |
||
670 | if (not (csDesigning in ComponentState)) and FEnabled then |
||
671 | Initialize; |
||
672 | end; |
||
673 | |||
674 | procedure TCustomDXTimer.Resume; |
||
675 | begin |
||
676 | FOldTime := TimeGetTime; |
||
677 | FOldTime2 := TimeGetTime; |
||
678 | Application.OnIdle := AppIdle; |
||
679 | end; |
||
680 | |||
681 | procedure TCustomDXTimer.SetActiveOnly(Value: Boolean); |
||
682 | begin |
||
683 | if FActiveOnly<>Value then |
||
684 | begin |
||
685 | FActiveOnly := Value; |
||
686 | |||
687 | if Application.Active and FActiveOnly then |
||
688 | if FInitialized and FActiveOnly then Suspend; |
||
689 | end; |
||
690 | end; |
||
691 | |||
692 | procedure TCustomDXTimer.SetEnabled(Value: Boolean); |
||
693 | begin |
||
694 | if FEnabled<>Value then |
||
695 | begin |
||
696 | FEnabled := Value; |
||
697 | if ComponentState*[csReading, csLoading]=[] then |
||
698 | if FEnabled then Initialize else Finalize; |
||
699 | end; |
||
700 | end; |
||
701 | |||
702 | procedure TCustomDXTimer.SetInterval(Value: Cardinal); |
||
703 | begin |
||
704 | if FInterval<>Value then |
||
705 | begin |
||
706 | FInterval := Max(Value, 0); |
||
707 | FInterval2 := Max(Value, 1); |
||
708 | end; |
||
709 | end; |
||
710 | |||
711 | procedure TCustomDXTimer.Suspend; |
||
712 | begin |
||
713 | Application.OnIdle := nil; |
||
714 | end; |
||
715 | |||
716 | { TControlSubClass } |
||
717 | |||
718 | constructor TControlSubClass.Create(Control: TControl; |
||
719 | WindowProc: TControlSubClassProc); |
||
720 | begin |
||
721 | inherited Create; |
||
722 | FControl := Control; |
||
723 | FDefWindowProc := FControl.WindowProc; |
||
724 | FControl.WindowProc := WndProc; |
||
725 | FWindowProc := WindowProc; |
||
726 | end; |
||
727 | |||
728 | destructor TControlSubClass.Destroy; |
||
729 | begin |
||
730 | FControl.WindowProc := FDefWindowProc; |
||
731 | inherited Destroy; |
||
732 | end; |
||
733 | |||
734 | procedure TControlSubClass.WndProc(var Message: TMessage); |
||
735 | begin |
||
736 | FWindowProc(Message, FDefWindowProc); |
||
737 | end; |
||
738 | |||
739 | { THashCollectionItem } |
||
740 | |||
741 | function MakeHashCode(const Str: string): Integer; |
||
742 | var |
||
743 | s: string; |
||
744 | begin |
||
745 | s := AnsiLowerCase(Str); |
||
746 | Result := Length(s)*16; |
||
747 | if Length(s)>=2 then |
||
748 | Result := Result + (Ord(s[1]) + Ord(s[Length(s)-1])); |
||
749 | Result := Result and 255; |
||
750 | end; |
||
751 | |||
752 | constructor THashCollectionItem.Create(Collection: TCollection); |
||
753 | begin |
||
754 | inherited Create(Collection); |
||
755 | FIndex := inherited Index; |
||
756 | AddHash; |
||
757 | end; |
||
758 | |||
759 | destructor THashCollectionItem.Destroy; |
||
760 | var |
||
761 | i: Integer; |
||
762 | begin |
||
763 | for i:=FIndex+1 to Collection.Count-1 do |
||
764 | Dec(THashCollectionItem(Collection.Items[i]).FIndex); |
||
765 | DeleteHash; |
||
766 | inherited Destroy; |
||
767 | end; |
||
768 | |||
769 | procedure THashCollectionItem.Assign(Source: TPersistent); |
||
770 | begin |
||
771 | if Source is THashCollectionItem then |
||
772 | begin |
||
773 | Name := THashCollectionItem(Source).Name; |
||
774 | end else |
||
775 | inherited Assign(Source); |
||
776 | end; |
||
777 | |||
778 | procedure THashCollectionItem.AddHash; |
||
779 | var |
||
780 | Item: THashCollectionItem; |
||
781 | begin |
||
782 | FHashCode := MakeHashCode(FName); |
||
783 | |||
784 | Item := THashCollection(Collection).FHash[FHashCode]; |
||
785 | if Item<>nil then |
||
786 | begin |
||
787 | Item.FLeft := Self; |
||
788 | Self.FRight := Item; |
||
789 | end; |
||
790 | |||
791 | THashCollection(Collection).FHash[FHashCode] := Self; |
||
792 | end; |
||
793 | |||
794 | procedure THashCollectionItem.DeleteHash; |
||
795 | begin |
||
796 | if FLeft<>nil then |
||
797 | begin |
||
798 | FLeft.FRight := FRight; |
||
799 | if FRight<>nil then |
||
800 | FRight.FLeft := FLeft; |
||
801 | end else |
||
802 | begin |
||
803 | if FHashCode<>-1 then |
||
804 | begin |
||
805 | THashCollection(Collection).FHash[FHashCode] := FRight; |
||
806 | if FRight<>nil then |
||
807 | FRight.FLeft := nil; |
||
808 | end; |
||
809 | end; |
||
810 | FLeft := nil; |
||
811 | FRight := nil; |
||
812 | end; |
||
813 | |||
814 | function THashCollectionItem.GetDisplayName: string; |
||
815 | begin |
||
816 | Result := Name; |
||
817 | if Result='' then Result := inherited GetDisplayName; |
||
818 | end; |
||
819 | |||
820 | procedure THashCollectionItem.SetIndex(Value: Integer); |
||
821 | begin |
||
822 | if FIndex<>Value then |
||
823 | begin |
||
824 | FIndex := Value; |
||
825 | inherited SetIndex(Value); |
||
826 | end; |
||
827 | end; |
||
828 | |||
829 | procedure THashCollectionItem.SetName(const Value: string); |
||
830 | begin |
||
831 | if FName<>Value then |
||
832 | begin |
||
833 | FName := Value; |
||
834 | DeleteHash; |
||
835 | AddHash; |
||
836 | end; |
||
837 | end; |
||
838 | |||
839 | { THashCollection } |
||
840 | |||
841 | function THashCollection.IndexOf(const Name: string): Integer; |
||
842 | var |
||
843 | Item: THashCollectionItem; |
||
844 | begin |
||
845 | Item := FHash[MakeHashCode(Name)]; |
||
846 | while Item<>nil do |
||
847 | begin |
||
848 | if AnsiCompareText(Item.Name, Name)=0 then |
||
849 | begin |
||
850 | Result := Item.FIndex; |
||
851 | Exit; |
||
852 | end; |
||
853 | Item := Item.FRight; |
||
854 | end; |
||
855 | Result := -1; |
||
856 | end; |
||
857 | |||
4 | daniel-mar | 858 | { TDXPictureClip } |
859 | |||
860 | constructor TDXPictureClip.Create(AOwner: TComponent); |
||
861 | begin |
||
862 | inherited Create(AOwner); |
||
863 | FPicture := TPicture.Create; |
||
864 | FPicture.OnChange := PictureChanged; |
||
865 | FBitmap := TBitmap.Create; |
||
866 | FRows := 1; |
||
867 | FCols := 1; |
||
868 | FMaskColor := GetDefaultMaskColor; |
||
869 | FMasked := True; |
||
870 | end; |
||
871 | |||
872 | destructor TDXPictureClip.Destroy; |
||
873 | begin |
||
874 | FOnChange := nil; |
||
875 | FPicture.OnChange := nil; |
||
876 | FBitmap.Free; |
||
877 | FPicture.Free; |
||
878 | inherited Destroy; |
||
879 | end; |
||
880 | |||
881 | procedure TDXPictureClip.Assign(Source: TPersistent); |
||
882 | begin |
||
883 | if Source is TDXPictureClip then begin |
||
884 | with TDXPictureClip(Source) do begin |
||
885 | Self.FRows := Rows; |
||
886 | Self.FCols := Cols; |
||
887 | Self.FMasked := Masked; |
||
888 | Self.FMaskColor := MaskColor; |
||
889 | Self.FPicture.Assign(FPicture); |
||
890 | end; |
||
891 | end |
||
892 | else if (Source is TPicture) or (Source is TGraphic) then |
||
893 | FPicture.Assign(Source) |
||
894 | else inherited Assign(Source); |
||
895 | end; |
||
896 | |||
897 | type |
||
898 | THack = class(TImageList); |
||
899 | |||
900 | procedure TDXPictureClip.AssignTo(Dest: TPersistent); |
||
901 | var |
||
902 | I: Integer; |
||
903 | SaveChange: TNotifyEvent; |
||
904 | begin |
||
905 | if (Dest is TPicture) then Dest.Assign(FPicture) |
||
906 | else if (Dest is TImageList) and not IsEmpty then begin |
||
907 | with TImageList(Dest) do begin |
||
908 | SaveChange := OnChange; |
||
909 | try |
||
910 | OnChange := nil; |
||
911 | Clear; |
||
912 | Width := Self.Width; |
||
913 | Height := Self.Height; |
||
914 | for I := 0 to Self.Count - 1 do begin |
||
915 | if Self.Masked and (MaskColor <> clNone) then |
||
916 | TImageList(Dest).AddMasked(GraphicCell[I], MaskColor) |
||
917 | else TImageList(Dest).Add(GraphicCell[I], nil); |
||
918 | end; |
||
919 | Masked := Self.Masked; |
||
920 | finally |
||
921 | OnChange := SaveChange; |
||
922 | end; |
||
923 | THack(Dest).Change; |
||
924 | end; |
||
925 | end |
||
926 | else inherited AssignTo(Dest); |
||
927 | end; |
||
928 | |||
929 | procedure TDXPictureClip.Changed; |
||
930 | begin |
||
931 | if Assigned(FOnChange) then FOnChange(Self); |
||
932 | end; |
||
933 | |||
934 | function TDXPictureClip.GetIsEmpty: Boolean; |
||
935 | begin |
||
936 | Result := not Assigned(Picture) or Picture.Graphic.Empty; |
||
937 | end; |
||
938 | |||
939 | function TDXPictureClip.GetCount: Integer; |
||
940 | begin |
||
941 | if IsEmpty then Result := 0 |
||
942 | else Result := Cols * Rows; |
||
943 | end; |
||
944 | const |
||
945 | { TBitmap.GetTransparentColor from GRAPHICS.PAS uses this value } |
||
946 | PaletteMask = $02000000; |
||
947 | |||
948 | procedure TDXPictureClip.Draw(Canvas: TCanvas; X, Y, Index: Integer); |
||
949 | |||
950 | function PaletteColor(Color: TColor): Longint; |
||
951 | begin |
||
952 | Result := ColorToRGB(Color) or PaletteMask; |
||
953 | end; |
||
954 | procedure StretchBltTransparent(DstDC: HDC; DstX, DstY, DstW, DstH: Integer; |
||
955 | SrcDC: HDC; SrcX, SrcY, SrcW, SrcH: Integer; Palette: HPalette; |
||
956 | TransparentColor: TColorRef); |
||
957 | var |
||
958 | Color: TColorRef; |
||
959 | bmAndBack, bmAndObject, bmAndMem, bmSave: HBitmap; |
||
960 | bmBackOld, bmObjectOld, bmMemOld, bmSaveOld: HBitmap; |
||
961 | MemDC, BackDC, ObjectDC, SaveDC: HDC; |
||
962 | palDst, palMem, palSave, palObj: HPalette; |
||
963 | begin |
||
964 | { Create some DCs to hold temporary data } |
||
965 | BackDC := CreateCompatibleDC(DstDC); |
||
966 | ObjectDC := CreateCompatibleDC(DstDC); |
||
967 | MemDC := CreateCompatibleDC(DstDC); |
||
968 | SaveDC := CreateCompatibleDC(DstDC); |
||
969 | { Create a bitmap for each DC } |
||
970 | bmAndObject := CreateBitmap(SrcW, SrcH, 1, 1, nil); |
||
971 | bmAndBack := CreateBitmap(SrcW, SrcH, 1, 1, nil); |
||
972 | bmAndMem := CreateCompatibleBitmap(DstDC, DstW, DstH); |
||
973 | bmSave := CreateCompatibleBitmap(DstDC, SrcW, SrcH); |
||
974 | { Each DC must select a bitmap object to store pixel data } |
||
975 | bmBackOld := SelectObject(BackDC, bmAndBack); |
||
976 | bmObjectOld := SelectObject(ObjectDC, bmAndObject); |
||
977 | bmMemOld := SelectObject(MemDC, bmAndMem); |
||
978 | bmSaveOld := SelectObject(SaveDC, bmSave); |
||
979 | { Select palette } |
||
980 | palDst := 0; palMem := 0; palSave := 0; palObj := 0; |
||
981 | if Palette <> 0 then begin |
||
982 | palDst := SelectPalette(DstDC, Palette, True); |
||
983 | RealizePalette(DstDC); |
||
984 | palSave := SelectPalette(SaveDC, Palette, False); |
||
985 | RealizePalette(SaveDC); |
||
986 | palObj := SelectPalette(ObjectDC, Palette, False); |
||
987 | RealizePalette(ObjectDC); |
||
988 | palMem := SelectPalette(MemDC, Palette, True); |
||
989 | RealizePalette(MemDC); |
||
990 | end; |
||
991 | { Set proper mapping mode } |
||
992 | SetMapMode(SrcDC, GetMapMode(DstDC)); |
||
993 | SetMapMode(SaveDC, GetMapMode(DstDC)); |
||
994 | { Save the bitmap sent here } |
||
995 | BitBlt(SaveDC, 0, 0, SrcW, SrcH, SrcDC, SrcX, SrcY, SRCCOPY); |
||
996 | { Set the background color of the source DC to the color, } |
||
997 | { contained in the parts of the bitmap that should be transparent } |
||
998 | Color := SetBkColor(SaveDC, PaletteColor(TransparentColor)); |
||
999 | { Create the object mask for the bitmap by performing a BitBlt() } |
||
1000 | { from the source bitmap to a monochrome bitmap } |
||
1001 | BitBlt(ObjectDC, 0, 0, SrcW, SrcH, SaveDC, 0, 0, SRCCOPY); |
||
1002 | { Set the background color of the source DC back to the original } |
||
1003 | SetBkColor(SaveDC, Color); |
||
1004 | { Create the inverse of the object mask } |
||
1005 | BitBlt(BackDC, 0, 0, SrcW, SrcH, ObjectDC, 0, 0, NOTSRCCOPY); |
||
1006 | { Copy the background of the main DC to the destination } |
||
1007 | BitBlt(MemDC, 0, 0, DstW, DstH, DstDC, DstX, DstY, SRCCOPY); |
||
1008 | { Mask out the places where the bitmap will be placed } |
||
1009 | StretchBlt(MemDC, 0, 0, DstW, DstH, ObjectDC, 0, 0, SrcW, SrcH, SRCAND); |
||
1010 | { Mask out the transparent colored pixels on the bitmap } |
||
1011 | BitBlt(SaveDC, 0, 0, SrcW, SrcH, BackDC, 0, 0, SRCAND); |
||
1012 | { XOR the bitmap with the background on the destination DC } |
||
1013 | StretchBlt(MemDC, 0, 0, DstW, DstH, SaveDC, 0, 0, SrcW, SrcH, SRCPAINT); |
||
1014 | { Copy the destination to the screen } |
||
1015 | BitBlt(DstDC, DstX, DstY, DstW, DstH, MemDC, 0, 0, |
||
1016 | SRCCOPY); |
||
1017 | { Restore palette } |
||
1018 | if Palette <> 0 then begin |
||
1019 | SelectPalette(MemDC, palMem, False); |
||
1020 | SelectPalette(ObjectDC, palObj, False); |
||
1021 | SelectPalette(SaveDC, palSave, False); |
||
1022 | SelectPalette(DstDC, palDst, True); |
||
1023 | end; |
||
1024 | { Delete the memory bitmaps } |
||
1025 | DeleteObject(SelectObject(BackDC, bmBackOld)); |
||
1026 | DeleteObject(SelectObject(ObjectDC, bmObjectOld)); |
||
1027 | DeleteObject(SelectObject(MemDC, bmMemOld)); |
||
1028 | DeleteObject(SelectObject(SaveDC, bmSaveOld)); |
||
1029 | { Delete the memory DCs } |
||
1030 | DeleteDC(MemDC); |
||
1031 | DeleteDC(BackDC); |
||
1032 | DeleteDC(ObjectDC); |
||
1033 | DeleteDC(SaveDC); |
||
1034 | end; |
||
1035 | procedure StretchBitmapTransparent(Dest: TCanvas; Bitmap: TBitmap; |
||
1036 | TransparentColor: TColor; DstX, DstY, DstW, DstH, SrcX, SrcY, |
||
1037 | SrcW, SrcH: Integer); |
||
1038 | var |
||
1039 | CanvasChanging: TNotifyEvent; |
||
1040 | begin |
||
1041 | if DstW <= 0 then DstW := Bitmap.Width; |
||
1042 | if DstH <= 0 then DstH := Bitmap.Height; |
||
1043 | if (SrcW <= 0) or (SrcH <= 0) then begin |
||
1044 | SrcX := 0; SrcY := 0; |
||
1045 | SrcW := Bitmap.Width; |
||
1046 | SrcH := Bitmap.Height; |
||
1047 | end; |
||
1048 | if not Bitmap.Monochrome then |
||
1049 | SetStretchBltMode(Dest.Handle, STRETCH_DELETESCANS); |
||
1050 | CanvasChanging := Bitmap.Canvas.OnChanging; |
||
1051 | Bitmap.Canvas.Lock; |
||
1052 | try |
||
1053 | Bitmap.Canvas.OnChanging := nil; |
||
1054 | if TransparentColor = clNone then begin |
||
1055 | StretchBlt(Dest.Handle, DstX, DstY, DstW, DstH, Bitmap.Canvas.Handle, |
||
1056 | SrcX, SrcY, SrcW, SrcH, Dest.CopyMode); |
||
1057 | end |
||
1058 | else begin |
||
1059 | if TransparentColor = clDefault then |
||
1060 | TransparentColor := Bitmap.Canvas.Pixels[0, Bitmap.Height - 1]; |
||
1061 | if Bitmap.Monochrome then TransparentColor := clWhite |
||
1062 | else TransparentColor := ColorToRGB(TransparentColor); |
||
1063 | StretchBltTransparent(Dest.Handle, DstX, DstY, DstW, DstH, |
||
1064 | Bitmap.Canvas.Handle, SrcX, SrcY, SrcW, SrcH, Bitmap.Palette, |
||
1065 | TransparentColor); |
||
1066 | end; |
||
1067 | finally |
||
1068 | Bitmap.Canvas.OnChanging := CanvasChanging; |
||
1069 | Bitmap.Canvas.Unlock; |
||
1070 | end; |
||
1071 | end; |
||
1072 | procedure DrawBitmapTransparent(Dest: TCanvas; DstX, DstY: Integer; |
||
1073 | Bitmap: TBitmap; TransparentColor: TColor); |
||
1074 | begin |
||
1075 | StretchBitmapTransparent(Dest, Bitmap, TransparentColor, DstX, DstY, |
||
1076 | Bitmap.Width, Bitmap.Height, 0, 0, Bitmap.Width, Bitmap.Height); |
||
1077 | end; |
||
1078 | var |
||
1079 | Image: TGraphic; |
||
1080 | begin |
||
1081 | if Index < 0 then Image := Picture.Graphic |
||
1082 | else Image := GraphicCell[Index]; |
||
1083 | if (Image <> nil) and not Image.Empty then begin |
||
1084 | if FMasked and (FMaskColor <> clNone) and |
||
1085 | (Picture.Graphic is TBitmap) then |
||
1086 | DrawBitmapTransparent(Canvas, X, Y, TBitmap(Image), FMaskColor) |
||
1087 | else Canvas.Draw(X, Y, Image); |
||
1088 | end; |
||
1089 | end; |
||
1090 | |||
1091 | procedure TDXPictureClip.DrawCenter(Canvas: TCanvas; Rect: TRect; Index: Integer); |
||
1092 | var |
||
1093 | X, Y: Integer; |
||
1094 | begin |
||
1095 | X := (Rect.Left + Rect.Right - Width) div 2; |
||
1096 | Y := (Rect.Bottom + Rect.Top - Height) div 2; |
||
1097 | Draw(Canvas, X, Y, Index); |
||
1098 | end; |
||
1099 | |||
1100 | procedure TDXPictureClip.CheckIndex(Index: Integer); |
||
1101 | begin |
||
1102 | if (Index >= Cols * Rows) or (Index < 0) then |
||
1103 | raise EListError.CreateFmt('%s (%d)', ['Load list error', Index]); |
||
1104 | end; |
||
1105 | |||
1106 | function TDXPictureClip.GetIndex(Col, Row: Cardinal): Integer; |
||
1107 | begin |
||
1108 | Result := Col + (Row * Cols); |
||
1109 | if (Result >= Cols * Rows) or IsEmpty then Result := -1; |
||
1110 | end; |
||
1111 | |||
1112 | function TDXPictureClip.GetCell(Col, Row: Cardinal): TBitmap; |
||
1113 | begin |
||
1114 | Result := GetGraphicCell(GetIndex(Col, Row)); |
||
1115 | end; |
||
1116 | |||
1117 | function TDXPictureClip.GetGraphicCell(Index: Integer): TBitmap; |
||
1118 | procedure AssignBitmapCell(Source: TGraphic; Dest: TBitmap; Cols, Rows, |
||
1119 | Index: Integer); |
||
1120 | var |
||
1121 | CellWidth, CellHeight: Integer; |
||
1122 | begin |
||
1123 | if (Source <> nil) and (Dest <> nil) then begin |
||
1124 | if Cols <= 0 then Cols := 1; |
||
1125 | if Rows <= 0 then Rows := 1; |
||
1126 | if Index < 0 then Index := 0; |
||
1127 | CellWidth := Source.Width div Cols; |
||
1128 | CellHeight := Source.Height div Rows; |
||
1129 | with Dest do begin |
||
1130 | Width := CellWidth; Height := CellHeight; |
||
1131 | end; |
||
1132 | if Source is TBitmap then begin |
||
1133 | Dest.Canvas.CopyRect(Bounds(0, 0, CellWidth, CellHeight), |
||
1134 | TBitmap(Source).Canvas, Bounds((Index mod Cols) * CellWidth, |
||
1135 | (Index div Cols) * CellHeight, CellWidth, CellHeight)); |
||
1136 | Dest.TransparentColor := TBitmap(Source).TransparentColor; |
||
1137 | end |
||
1138 | else begin |
||
1139 | Dest.Canvas.Brush.Color := clSilver; |
||
1140 | Dest.Canvas.FillRect(Bounds(0, 0, CellWidth, CellHeight)); |
||
1141 | Dest.Canvas.Draw(-(Index mod Cols) * CellWidth, |
||
1142 | -(Index div Cols) * CellHeight, Source); |
||
1143 | end; |
||
1144 | Dest.Transparent := Source.Transparent; |
||
1145 | end; |
||
1146 | end; |
||
1147 | begin |
||
1148 | CheckIndex(Index); |
||
1149 | AssignBitmapCell(Picture.Graphic, FBitmap, Cols, Rows, Index); |
||
1150 | if Picture.Graphic is TBitmap then |
||
1151 | if FBitmap.PixelFormat <> pfDevice then |
||
1152 | FBitmap.PixelFormat := TBitmap(Picture.Graphic).PixelFormat; |
||
1153 | FBitmap.TransparentColor := FMaskColor or PaletteMask; |
||
1154 | FBitmap.Transparent := (FMaskColor <> clNone) and Masked; |
||
1155 | Result := FBitmap; |
||
1156 | end; |
||
1157 | |||
1158 | function TDXPictureClip.GetDefaultMaskColor: TColor; |
||
1159 | begin |
||
1160 | Result := clOlive; |
||
1161 | if (Picture.Graphic <> nil) and (Picture.Graphic is TBitmap) then |
||
1162 | Result := TBitmap(Picture.Graphic).TransparentColor and |
||
1163 | not PaletteMask; |
||
1164 | end; |
||
1165 | |||
1166 | function TDXPictureClip.GetHeight: Integer; |
||
1167 | begin |
||
1168 | Result := Picture.Height div FRows; |
||
1169 | end; |
||
1170 | |||
1171 | function TDXPictureClip.GetWidth: Integer; |
||
1172 | begin |
||
1173 | Result := Picture.Width div FCols; |
||
1174 | end; |
||
1175 | |||
1176 | function TDXPictureClip.IsMaskStored: Boolean; |
||
1177 | begin |
||
1178 | Result := MaskColor <> GetDefaultMaskColor; |
||
1179 | end; |
||
1180 | |||
1181 | procedure TDXPictureClip.SetMaskColor(Value: TColor); |
||
1182 | begin |
||
1183 | if Value <> FMaskColor then begin |
||
1184 | FMaskColor := Value; |
||
1185 | Changed; |
||
1186 | end; |
||
1187 | end; |
||
1188 | |||
1189 | procedure TDXPictureClip.PictureChanged(Sender: TObject); |
||
1190 | begin |
||
1191 | FMaskColor := GetDefaultMaskColor; |
||
1192 | if not (csReading in ComponentState) then Changed; |
||
1193 | end; |
||
1194 | |||
1195 | procedure TDXPictureClip.SetHeight(Value: Integer); |
||
1196 | begin |
||
1197 | if (Value > 0) and (Picture.Height div Value > 0) then |
||
1198 | Rows := Picture.Height div Value; |
||
1199 | end; |
||
1200 | |||
1201 | procedure TDXPictureClip.SetWidth(Value: Integer); |
||
1202 | begin |
||
1203 | if (Value > 0) and (Picture.Width div Value > 0) then |
||
1204 | Cols := Picture.Width div Value; |
||
1205 | end; |
||
1206 | |||
1207 | procedure TDXPictureClip.SetPicture(Value: TPicture); |
||
1208 | begin |
||
1209 | FPicture.Assign(Value); |
||
1210 | end; |
||
1211 | |||
1212 | { Transformations routines } |
||
1213 | { Authorisation: Mr. Takanori Kawasaki} |
||
1214 | |||
1215 | //Distance between 2 points is calculated |
||
1216 | function Get2PointRange(a,b: TDblPoint):Double; |
||
1217 | var |
||
1218 | x,y: Double; |
||
1219 | begin |
||
1220 | x := a.X - b.X; |
||
1221 | y := a.Y - b.Y; |
||
1222 | Result := Sqrt(x*x+y*y); |
||
1223 | end; |
||
1224 | |||
1225 | //Direction angle in the coordinate A which was seen from coordinate B is calculated |
||
1226 | function GetARadFromB(A,B: TDblPoint):Double; |
||
1227 | var |
||
1228 | dX,dY: Double; |
||
1229 | begin |
||
1230 | dX := A.X - B.X; |
||
1231 | dY := A.Y - B.Y; |
||
1232 | Result := Get256(dX,dY); |
||
1233 | end; |
||
1234 | |||
1235 | //Direction angle is returned with 0 - 255. |
||
1236 | function Get256(dX,dY:Double):Double; |
||
1237 | begin |
||
1238 | Result := 0; |
||
1239 | if dX > 0 then |
||
1240 | begin//0-63 |
||
1241 | if dY > 0 then Result := ArcTan(dY / dX) // 0 < Res < 90 |
||
1242 | else//0 |
||
1243 | if dY = 0 then Result := 0 // 0 |
||
1244 | else//192-255 |
||
1245 | if dY < 0 then Result := 2*Pi + ArcTan(dY / dX) // 270 < Res < 360 |
||
1246 | end else |
||
1247 | if dX = 0 then |
||
1248 | begin//64 |
||
1249 | if dY > 0 then Result := 1 / 2 * Pi // 90 |
||
1250 | else//0 |
||
1251 | if dY = 0 then Result := 0 // 0 |
||
1252 | else//192 |
||
1253 | if dY < 0 then Result := 3 / 2 * Pi // 270 |
||
1254 | end else |
||
1255 | if dX < 0 then |
||
1256 | begin//64-127 |
||
1257 | if dY > 0 then Result := Pi + ArcTan(dY / dX) // 90 < Res < 180 |
||
1258 | else//128 |
||
1259 | if dY = 0 then Result := Pi // 180 |
||
1260 | else//128-191 |
||
1261 | if dY < 0 then Result := Pi + ArcTan(dY / dX) // 180 < Res < 270 |
||
1262 | end; |
||
1263 | Result := 256 * Result / (2*Pi); |
||
1264 | end; |
||
1265 | |||
1266 | //From the coordinate SP the Range it calculates the point which leaves with the angular Angle |
||
1267 | function GetPointFromRangeAndAngle(SP: TDblPoint; Range,Angle: Double): TDblPoint; |
||
1268 | begin |
||
1269 | Result.X := SP.X + Range * Cos(Angle); |
||
1270 | Result.Y := SP.Y + Range * Sin(Angle); |
||
1271 | end; |
||
1272 | |||
1273 | //* As for coordinate transformation coordinate for mathematics is used |
||
1274 | //Identity matrix for the 2d is returned. |
||
1275 | function Ini2DRowCol: T2DRowCol; |
||
1276 | var |
||
1277 | i,ii:integer; |
||
1278 | begin |
||
1279 | for i := 1 to 3 do |
||
1280 | for ii := 1 to 3 do |
||
1281 | if i = ii then Result[i,ii] := 1 else Result[i,ii] := 0; |
||
1282 | end; |
||
1283 | |||
1284 | //Transformation matrix of the portable quantity |
||
1285 | //where the one for 2d is appointed is returned. |
||
1286 | function Trans2DRowCol(x,y:double):T2DRowCol; |
||
1287 | begin |
||
1288 | Result := Ini2DRowCol; |
||
1289 | Result[3,1] := x; |
||
1290 | Result[3,2] := y; |
||
1291 | end; |
||
1292 | |||
1293 | //Conversion coordinate of the expansion and contraction |
||
1294 | //quantity where the one for 2d is appointed is returned. |
||
1295 | function Scale2DRowCol(x,y:double):T2DRowCol; |
||
1296 | begin |
||
1297 | Result := Ini2DRowCol; |
||
1298 | Result[1,1] := x; |
||
1299 | Result[2,2] := y; |
||
1300 | end; |
||
1301 | |||
1302 | //Coordinate transformation of the rotary quantity |
||
1303 | //where the one for 2d is appointed is returned. |
||
1304 | function Rotate2DRowCol(Theta:double):T2DRowCol; |
||
1305 | begin |
||
1306 | Result := Ini2DRowCol; |
||
1307 | Result[1,1] := Cos256(Trunc(Theta)); |
||
1308 | Result[1,2] := Sin256(Trunc(Theta)); |
||
1309 | Result[2,1] := -1 * Result[1,2]; |
||
1310 | Result[2,2] := Result[1,1]; |
||
1311 | end; |
||
1312 | |||
1313 | //You apply two conversion coordinates and adjust. |
||
1314 | function Multiply2DRowCol(A,B:T2DRowCol):T2DRowCol; |
||
1315 | begin |
||
1316 | Result[1,1] := A[1,1] * B[1,1] + A[1,2] * B[2,1]; |
||
1317 | Result[1,2] := A[1,1] * B[1,2] + A[1,2] * B[2,2]; |
||
1318 | Result[1,3] := 0; |
||
1319 | Result[2,1] := A[2,1] * B[1,1] + A[2,2] * B[2,1]; |
||
1320 | Result[2,2] := A[2,1] * B[1,2] + A[2,2] * B[2,2]; |
||
1321 | Result[2,3] := 0; |
||
1322 | Result[3,1] := A[3,1] * B[1,1] + A[3,2] * B[2,1] + B[3,1]; |
||
1323 | Result[3,2] := A[3,1] * B[1,2] + A[3,2] * B[2,2] + B[3,2]; |
||
1324 | Result[3,3] := 1; |
||
1325 | end; |
||
1326 | |||
1327 | //Until coordinate (the X and the Y) comes on the X axis, |
||
1328 | //the conversion coordinate which turns the position |
||
1329 | //of the point is returned. |
||
1330 | function RotateIntoX2DRowCol(x,y: double):T2DRowCol; |
||
1331 | var |
||
1332 | d: double; |
||
1333 | begin |
||
1334 | Result := Ini2DRowCol; |
||
1335 | d := sqrt(x*x+y*y); |
||
1336 | Result[1,1] := x / d; |
||
1337 | Result[1,2] := y / d; |
||
1338 | Result[2,1] := -1 * Result[1,2]; |
||
1339 | Result[2,2] := Result[1,1]; |
||
1340 | end; |
||
1341 | |||
1342 | //Coordinate (the X and the Y) as a center, the conversion |
||
1343 | //coordinate which does the scaling of the magnification ratio |
||
1344 | //which is appointed with the Sx and the Sy is returned. |
||
1345 | function ScaleAt2DRowCol(x,y,Sx,Sy:double):T2DRowCol; |
||
1346 | var |
||
1347 | T,S,TInv,M:T2DRowCol; |
||
1348 | begin |
||
1349 | T := Trans2DRowCol(-x,-y); |
||
1350 | TInv := Trans2DRowCol(x,y); |
||
1351 | S := Scale2DRowCol(Sx,Sy); |
||
1352 | M := Multiply2DRowCol(T,S); |
||
1353 | Result := Multiply2DRowCol(M,T); |
||
1354 | end; |
||
1355 | |||
1356 | //Coordinate (the X and the Y) it passes, comes hard and |
||
1357 | //(DX and the dy) with the direction which is shown it |
||
1358 | //returns the transformation matrix which does the reflected |
||
1359 | //image conversion which centers the line which faces. |
||
1360 | function ReflectAcross2DRowCol(x,y,dx,dy:Double): T2DRowCol; |
||
1361 | var |
||
1362 | T,R,S,RInv,TInv,M1,M2,M3: T2DRowCol; |
||
1363 | begin |
||
1364 | T := Trans2DRowCol(-x,-y); |
||
1365 | TInv := Trans2DRowCol(x,y); |
||
1366 | R := RotateIntoX2DRowCol(dx,dy); |
||
1367 | RInv := RotateIntoX2DRowCol(dx,-dy); |
||
1368 | S := Scale2DRowCol(1,-1); |
||
1369 | M1 := Multiply2DRowCol(T,R); |
||
1370 | M2 := Multiply2DRowCol(S,RInv); |
||
1371 | M3 := Multiply2DRowCol(M1,M2); |
||
1372 | Result := Multiply2DRowCol(M3,TInv); |
||
1373 | end; |
||
1374 | |||
1375 | //Coordinate focusing on (the X and the Y) the transformation |
||
1376 | //matrix which turns the position of the point with angle Theta is returned. |
||
1377 | function RotateAround2DRowCol(x,y,Theta:Double): T2DRowCol; |
||
1378 | var |
||
1379 | T,R,TInv,M: T2DRowCol; |
||
1380 | begin |
||
1381 | T := Trans2DRowCol(-x,-y); |
||
1382 | TInv := Trans2DRowCol(x,y); |
||
1383 | R := Rotate2DRowCol(Theta); |
||
1384 | M := Multiply2DRowCol(T,R); |
||
1385 | Result := Multiply2DRowCol(M,TInv); |
||
1386 | end; |
||
1387 | |||
1388 | //Transformation matrix is applied to the point. |
||
1389 | function Apply2DVector(V:T2DVector; M:T2DRowCol): T2DVector; |
||
1390 | begin |
||
1391 | Result[1] := V[1] * M[1,1] + V[2] * M[2,1] + M[3,1]; |
||
1392 | Result[2] := V[1] * M[1,2] + V[2] * M[2,2] + M[3,2]; |
||
1393 | Result[3] := 1; |
||
1394 | end; |
||
1395 | |||
1396 | //The TDblPoint is returned |
||
1397 | function DblPoint(a,b:Double):TDblPoint; |
||
1398 | begin |
||
1399 | Result.X := a; |
||
1400 | Result.Y := b; |
||
1401 | end; |
||
1402 | |||
1403 | function TruncDblPoint(DblPos: TDblPoint): TPoint; |
||
1404 | begin |
||
1405 | Result.X := Trunc(DblPos.X); |
||
1406 | Result.Y := Trunc(DblPos.Y); |
||
1407 | end; |
||
1408 | { |
||
1409 | +-----------------------------------------------------------------------------+ |
||
1410 | |Collision decision | |
||
1411 | +-----------------------------------------------------------------------------+} |
||
1412 | |||
1413 | //Point and circle |
||
1414 | function PointInCircle(PPos,CPos: TPoint; R: integer): Boolean; |
||
1415 | begin |
||
1416 | Result := (PPos.X - CPos.X)*(PPos.X - CPos.X)+(PPos.Y - CPos.Y)*(PPos.Y - CPos.Y)<= R*R; |
||
1417 | end; |
||
1418 | |||
1419 | //Circle and circle |
||
1420 | function CircleInCircle(C1Pos,C2Pos: TPoint; R1,R2:Integer): Boolean; |
||
1421 | begin |
||
1422 | Result := (C1Pos.X - C2Pos.X)*(C1Pos.X - C2Pos.X)+(C1Pos.Y - C2Pos.Y)*(C1Pos.Y - C2Pos.Y) <= (R1+R2)*(R1+R2); |
||
1423 | end; |
||
1424 | |||
1425 | //Circle and line segment |
||
1426 | function SegmentInCircle(SPos,EPos,CPos: TPoint; R: Integer): Boolean; |
||
1427 | var |
||
1428 | V,C: TPoint; |
||
1429 | VC,VV,CC:integer; |
||
1430 | begin |
||
1431 | Result := False; |
||
1432 | V.X := EPos.X - SPos.X; V.Y := EPos.Y - SPos.Y; |
||
1433 | C.X := CPos.X - SPos.X; C.Y := CPos.Y - SPos.Y; |
||
1434 | VC := V.X * C.X + V.Y * C.Y; |
||
1435 | if VC < 0 then |
||
1436 | begin |
||
1437 | Result := (C.X * C.X + C.Y * C.Y) <= R*R; |
||
1438 | end |
||
1439 | else |
||
1440 | begin |
||
1441 | VV := V.X * V.X + V.Y * V.Y; |
||
1442 | if VC >= VV then |
||
1443 | begin |
||
1444 | Result := (EPos.X - CPos.X)*(EPos.X - CPos.X)+(EPos.Y - CPos.Y)*(EPos.Y - CPos.Y) <= R * R; |
||
1445 | end |
||
1446 | else |
||
1447 | if VC < VV then |
||
1448 | begin |
||
1449 | CC := C.X * C.X + C.Y * C.Y; |
||
1450 | Result := CC - (VC div VV)* VC <= R*R; |
||
1451 | end; |
||
1452 | end; |
||
1453 | end; |
||
1454 | |||
1455 | //Angle recalc |
||
1456 | function Angle256(Angle: Single): Single; |
||
1457 | begin |
||
1458 | Result := Angle; |
||
1459 | While Result < 0 do Result := Result + 256; |
||
1460 | While Result >= 256 do Result := Result -256; |
||
1461 | end; |
||
1462 | |||
1463 | //If A is closer than B from starting point S, the True is returned. |
||
1464 | function CheckNearAThanB(S,A,B: TDblPoint): Boolean; |
||
1465 | begin |
||
1466 | Result := (S.X-A.X)*(S.X-A.X)+(S.Y-A.Y)*(S.Y-A.Y) <= (S.X-B.X)*(S.X-B.X)+(S.Y-B.Y)*(S.Y-B.Y); |
||
1467 | end; |
||
1468 | |||
1469 | function CircumCenter3Pt(const x1, y1, x2, y2, x3, y3: Single; out Px, Py: Single): Boolean; |
||
1470 | var |
||
1471 | A,B,C,D,E,F,G: Single; |
||
1472 | begin |
||
1473 | A := x2 - x1; |
||
1474 | B := y2 - y1; |
||
1475 | C := x3 - x1; |
||
1476 | D := y3 - y1; |
||
1477 | E := A * (x1 + x2) + B * (y1 + y2); |
||
1478 | F := C * (x1 + x3) + D * (y1 + y3); |
||
1479 | G := 2.0 * (A * (y3 - y2) - B * (x3 - x2)); |
||
1480 | Result := G <> 0.0; |
||
1481 | if Result then begin |
||
1482 | Px := (D * E - B * F) / G; |
||
1483 | Py := (A * F - C * E) / G; |
||
1484 | end; |
||
1485 | end; |
||
1486 | |||
1487 | function Distance(const x1, y1, x2, y2: Double): Double; |
||
1488 | begin |
||
1489 | Result := Sqrt(Sqr(y2 - y1) + Sqr(x2 - x1)); |
||
1490 | end; |
||
1491 | |||
1492 | procedure InCenter(const x1, y1, x2, y2, x3, y3: Double; out Px, Py: Double); |
||
1493 | var |
||
1494 | Perim: Double; |
||
1495 | Side12: Double; |
||
1496 | Side23: Double; |
||
1497 | Side31: Double; |
||
1498 | begin |
||
1499 | Side12 := Distance(x1, y1, x2, y2); |
||
1500 | Side23 := Distance(x2, y2, x3, y3); |
||
1501 | Side31 := Distance(x3, y3, x1, y1); |
||
1502 | { Using Heron's S=UR } |
||
1503 | Perim := 1.0 / (Side12 + Side23 + Side31); |
||
1504 | Px := (Side23 * x1 + Side31 * x2 + Side12 * x3) * Perim; |
||
1505 | Py := (Side23 * y1 + Side31 * y2 + Side12 * y3) * Perim; |
||
1506 | end; |
||
1507 | |||
1508 | function PointInTriangle(const Px, Py, x1, y1, x2, y2, x3, y3: Double): Boolean; |
||
1509 | function Orientation(const x1, y1, x2, y2, Px, Py: Double): Integer; |
||
1510 | var |
||
1511 | Orin: Double; |
||
1512 | begin |
||
1513 | (* Linear determinant of the 3 points *) |
||
1514 | Orin := (x2 - x1) * (py - y1) - (px - x1) * (y2 - y1); |
||
1515 | |||
1516 | if Orin > 0.0 then |
||
1517 | Result := +1 (* Orientaion is to the right-hand side *) |
||
1518 | else if Orin < 0.0 then |
||
1519 | Result := -1 (* Orientaion is to the left-hand side *) |
||
1520 | else |
||
1521 | Result := 0; (* Orientaion is neutral aka collinear *) |
||
1522 | end; |
||
1523 | var |
||
1524 | Or1, Or2, Or3: Integer; |
||
1525 | begin |
||
1526 | Or1 := Orientation(x1, y1, x2, y2, Px, Py); |
||
1527 | Or2 := Orientation(x2, y2, x3, y3, Px, Py); |
||
1528 | Or3 := Orientation(x3, y3, x1, y1, Px, Py); |
||
1529 | |||
1530 | if (Or1 = Or2) and (Or2 = Or3) then |
||
1531 | Result := True |
||
1532 | else if Or1 = 0 then |
||
1533 | Result := (Or2 = 0) or (Or3 = 0) |
||
1534 | else if Or2 = 0 then |
||
1535 | Result := (Or1 = 0) or (Or3 = 0) |
||
1536 | else if Or3 = 0 then |
||
1537 | Result := (Or2 = 0) or (Or1 = 0) |
||
1538 | else |
||
1539 | Result := False; |
||
1540 | end; |
||
1541 | |||
1542 | procedure Log(const Co: string; const FName: string); |
||
1543 | var F: Text; D: TDateTime; |
||
1544 | Hour, Minute, Second, MSec: Word; |
||
1545 | begin |
||
1546 | AsSignFile(F, FName); |
||
1547 | if FileExists(FName) then Append(F) |
||
1548 | else ReWrite(F); |
||
1549 | try |
||
1550 | D := Now; |
||
1551 | DecodeTime(D, Hour, Minute, Second, MSec); |
||
1552 | WriteLn(F, DateToStr(D) + ' ' + IntToStr(Hour)+':'+IntToStr(Minute)+':'+IntToStr(Second)+ '.'+IntToStr(MSec) +' ' + Co); |
||
1553 | finally |
||
1554 | CloseFile(F); |
||
1555 | end; |
||
1556 | end; |
||
1557 | |||
1558 | {$IFDEF _DMO_} |
||
1559 | |||
1560 | { TDirectXDriverEx } |
||
1561 | |||
1562 | function TDirectXDriverEx.ConvertHMonitor(iMonitor: HMonitor): TMonitorInfo; |
||
1563 | begin |
||
1564 | ZeroMemory(@Result, sizeof(Result)); |
||
1565 | Result.cbSize := SizeOf(Result); |
||
1566 | MultiMon.GetMonitorInfo(iMonitor, @Result); |
||
1567 | end; |
||
1568 | |||
1569 | function TDirectXDriverEx.GetFlags: DWORD; |
||
1570 | begin |
||
1571 | Result := ConvertHMonitor(FMonitor).dwFlags; |
||
1572 | end; |
||
1573 | |||
1574 | function TDirectXDriverEx.GetMonitorInfo: TMonitorInfo; |
||
1575 | begin |
||
1576 | Result:= ConvertHMonitor(FMonitor); |
||
1577 | end; |
||
1578 | |||
1579 | function TDirectXDriverEx.GetTempSpace: TRect; |
||
1580 | begin |
||
1581 | Result := ConvertHMonitor(FMonitor).rcWork |
||
1582 | end; |
||
1583 | |||
1584 | function TDirectXDriverEx.GetWorkSpace: TRect; |
||
1585 | begin |
||
1586 | Result := ConvertHMonitor(FMonitor).rcMonitor |
||
1587 | end; |
||
1588 | |||
1589 | procedure TDirectXDriverEx.SetGUID(Value: PGUID); |
||
1590 | begin |
||
1591 | if not IsBadHugeReadPtr(Value, SizeOf(TGUID)) then |
||
1592 | begin |
||
1593 | FGUID2 := Value^; |
||
1594 | FGUID := @FGUID2; |
||
1595 | end else |
||
1596 | FGUID := Value; |
||
1597 | end; |
||
1598 | |||
1599 | { TDirectXDriversEx } |
||
1600 | |||
1601 | constructor TDirectXDriversEx.Create; |
||
1602 | begin |
||
1603 | inherited Create(TDirectXDriverEx); |
||
1604 | end; |
||
1605 | |||
1606 | function TDirectXDriversEx.GetDriver(Index: Integer): TDirectXDriverEx; |
||
1607 | begin |
||
1608 | Result := (inherited Items[Index]) as TDirectXDriverEx; |
||
1609 | end; |
||
1610 | |||
1611 | {$ENDIF} |
||
1612 | |||
1 | daniel-mar | 1613 | initialization |
1614 | InitCosinTable; |
||
1615 | finalization |
||
1616 | FreeLibList; |
||
4 | daniel-mar | 1617 | end. |