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

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/index.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: 11.11.98 - 16:02:52 $                                        =}
  24. {========================================================================}
  25. unit MMDIBCv;
  26. {$I COMPILER.INC}
  27. {$IFNDEF WIN32}
  28.    {$DEFINE USEWING}
  29. {$ENDIF}
  30. interface
  31. uses
  32. {$IFDEF WIN32}
  33.     Windows,
  34. {$ELSE}
  35.     WinTypes,
  36.     WinProcs,
  37. {$ENDIF}
  38.     Classes,
  39.     Controls,
  40.     Graphics,
  41.     Dialogs,
  42.     SysUtils,
  43.     MMObj,
  44.     MMUtils,
  45.     MMDIB,
  46.     CRightC
  47. {$IFDEF USEWING}
  48.     ,MMWinG
  49. {$ENDIF};
  50. const
  51.      { different DIB Orientations }
  52.      DIB_TOPDOWN  = -1;
  53.      DIB_BOTTOMUP =  1;
  54.      { DIB_TOPDOWN is the fastest, but many drivers can't work with    }
  55.      { this STANDARD format. For example the ATI driver causes a GPF   }
  56.      { in BitBlt. NEVER buy a ATI card, if you would have trouble do it!}
  57.      DIB_ORIENT: integer = DIB_BOTTOMUP;   { Bottom - Up DIB !! }
  58. type
  59.     EMMDIBError = class(Exception);
  60.     {-- TMMDIBCanvas ----------------------------------------------------}
  61.     TMMDIBCanvas = class(TCanvas)
  62.     private
  63.            FOwner       : TComponent;
  64.            FHDIBDC      : THandle;
  65.            FBits        : integer;
  66.            FHOrigBitmap : HBitmap;
  67.            FHBitmap     : HBitmap;
  68.            FHBackGround : HBitmap;
  69.            FPBitMapInfo : PBitMapInfo;
  70.            FHPalette    : HPalette;
  71.            FPLogPalette : PLogPalette;
  72.            FRealize     : Boolean;
  73.            FMapped      : Boolean;
  74.            FPSurface    : Pointer;
  75.            FPBackSurface: Pointer;
  76.            FWidth       : integer;
  77.            FHeight      : integer;
  78.            FClipRect    : TRect;
  79.            FBackBitmap  : TBitmap;
  80.            FStretchBgnd : Boolean;
  81.            FNeedUpdate  : Boolean;
  82.            FCanUpdate   : Boolean;
  83.            FAnimFirst   : Integer;
  84.            FAnimColors  : TList;
  85.            FAnimLock    : Integer;
  86.            FAnimValues  : TList;
  87.            FAnimCount   : Integer;
  88.            procedure SetBPP(aValue: integer);
  89.            procedure SetWidth(aWidth: integer);
  90.            procedure SetHeight(aHeight: integer);
  91.            procedure SetBackBitmap(aBitmap: TBitmap);
  92.            procedure SetRealize(Value: Boolean);
  93.            procedure SetMapped(Value: Boolean);
  94.            procedure SetStretchBgnd(Value: Boolean);
  95.            procedure BackGroundChanged(Sender: TObject);
  96.            procedure CheckDIB;
  97.            procedure CreateDIB;
  98.            procedure DestroyDIB;
  99.            procedure RecreateDIB;
  100.            function  GetAnimCount: Integer;
  101.            procedure SetAnimCount(Value: Integer);
  102.            function  GetAnimColor(Index: Integer): TColor;
  103.            function  GetAnimColorValue(Index: Integer): TColor;
  104.            procedure SetAnimColorValue(Index: Integer; Value: TColor);
  105.            function  GetAnimColorIndex(Index: Integer): Integer;
  106.            procedure FreeColors;
  107.     protected
  108.            procedure CreateHandle; override;
  109.     public
  110.            constructor Create(aOwner: TComponent); virtual;
  111.            destructor  Destroy; override;
  112.            procedure SetBounds(aLeft, aTop, aWidth, aHeight: Integer); virtual;
  113.            procedure SetLogPalette(pLogPal: PLogPalette);
  114.            procedure DIB_Init;
  115.            procedure DIB_InitDrawing;
  116.            procedure DIB_DoneDrawing;
  117.            procedure DIB_SetTColor(Color: TColor);
  118.            procedure DIB_SetColorRef(ColorRef: Longint);
  119.            function  DIB_ColorToIndex(Color: TColor): Longint;
  120.            procedure DIB_SetColor(Index: Longint);
  121.            procedure DIB_SetClipRect(R: TRect);
  122.            function  DIB_GetClipRect: TRect;
  123.            function  DIB_GetPixelAddress(aSurface: Pointer; X, Y: integer): Pointer;
  124.            procedure DIB_SetPixel(X, Y: integer; Color: Longint);{$IFDEF WIN32}pascal;{$ENDIF}
  125.            function  DIB_GetPixel(X, Y: integer): Longint;{$IFDEF WIN32}pascal;{$ENDIF}
  126.            procedure DIB_Line(X1, Y1, X2, Y2: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  127.            procedure DIB_LineNotXor(X1, Y1, X2, Y2: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  128.            procedure DIB_MoveTo(X,Y: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  129.            procedure DIB_LineTo(X,Y: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  130.            procedure DIB_HLine(X1, X2, Y: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  131.            procedure DIB_HLineDashed(X1, X2, Y: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  132.            procedure DIB_HLineDoted(X1, X2, Y, Steps: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  133.            procedure DIB_VLine(X, Y1, Y2: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  134.            procedure DIB_VLineXor(X, Y1, Y2: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  135.            procedure DIB_VLineNotXor(X, Y1, Y2: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  136.            procedure DIB_VLineDashed(X, Y1, Y2: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  137.            procedure DIB_VLineDoted(X, Y1, Y2, Steps: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  138.            procedure DIB_VLineMultiColor(X, Y: integer; Colors: PByte; Cnt: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  139.            procedure DIB_Rectangle(X1, Y1, X2, Y2: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  140.            procedure DIB_FillRect(Rect: TRect);{$IFDEF WIN32}pascal;{$ENDIF}
  141.            procedure DIB_FillRectXor(Rect: TRect);{$IFDEF WIN32}pascal;{$ENDIF}
  142.            procedure DIB_FillRectDoted(Rect: TRect; Doted: Boolean);{$IFDEF WIN32}pascal;{$ENDIF}
  143.            procedure DIB_Ellipse(X, Y: integer; StAngle, EndAngle, XRadius, YRadius: Word);{$IFDEF WIN32}pascal;{$ENDIF}
  144.            procedure DIB_FillEllipse(X, Y: integer; XRadius, YRadius: Word);{$IFDEF WIN32}pascal;{$ENDIF}
  145.            procedure DIB_Clear;{$IFDEF WIN32}pascal;{$ENDIF}
  146.            procedure DIB_CopyDIBBits(Source:Pointer;XDst,YDst,Width,Height,XSrc,YSrc: integer);{$IFDEF WIN32}pascal;{$ENDIF}
  147.            procedure DIB_BitBlt(DestDC: THandle; Dest: TRect; X, Y: integer);
  148.            procedure DIB_StretchBlt(DestDC: THandle; Dest: TRect; Src: TRect);
  149.            procedure BeginAnimate;
  150.            procedure EndAnimate;
  151.            property Surface: Pointer read FPSurface;
  152.            property BackSurface: Pointer read FPBackSurface;
  153.            property BitmapInfo: PBitmapInfo read FPBitmapInfo;
  154.            property Bitmap: HBitmap read FHBitmap;
  155.            property Palette: HPalette read FHPalette;
  156.            property AnimatedColorCount: Integer read GetAnimCount write SetAnimCount;
  157.            property AnimatedColor[i: Integer]: TColor read GetAnimColor;
  158.            property AnimatedColorValue[i: Integer]: TColor read GetAnimColorValue write SetAnimColorValue;
  159.            property AnimatedColorIndex[i: Integer]: Integer read GetAnimColorIndex ;
  160.     published
  161.            property BitsPerPixel: integer read FBits write SetBPP stored True;
  162.            property PaletteRealize: Boolean read FRealize write SetRealize default False;
  163.            property PaletteMapped: Boolean read FMapped write SetMapped default False;
  164.            property BackGroundBitmap: TBitmap read FBackBitmap write SetBackBitmap;
  165.            property StretchBackGround: Boolean read FStretchBgnd write SetStretchBgnd default True;
  166.            property Width: integer read FWidth write SetWidth default 1;
  167.            property Height: integer read FHeight write SetHeight default 1;
  168.     end;
  169.     TMMDIBDrawProc = procedure(Clear: Boolean) of object;
  170.     {-- TMMDIBGraphicControl --------------------------------------------------}
  171.     TMMDIBGraphicControl = class(TMMGraphicControl)
  172.     private
  173.            FTag2      : integer;
  174.            FDIBCanvas : TMMDIBCanvas;
  175.            FBackGround: TBitmap;
  176.            FUseBackDIB: Boolean;
  177.            FTempUseDIB: Boolean;
  178.            function  GetBPP: integer;
  179.            procedure SetRealize(aValue: Boolean);
  180.            function  GetRealize: Boolean;
  181.            procedure SetMapped(aValue: Boolean);
  182.            function  GetMapped: Boolean;
  183.            procedure BackGroundChanged(Sender: TObject);
  184.            procedure SetBackGround(aBitmap: TBitmap);
  185.            procedure SetUseBackDIB(aValue: Boolean);
  186.     protected
  187.            procedure FastDraw(DrawProc: TMMDIBDrawProc; Clear: Boolean);
  188.            procedure SetBPP(aValue: integer); virtual;
  189.            procedure Loaded; override;
  190.            function  GetPalette: HPALETTE; override;
  191.            property  UseBackGroundDIB: Boolean read FUseBackDIB write SetUseBackDIB default False;
  192.            property  BackGroundDIB: TBitmap read FBackGround write SetBackGround;
  193.            property  PaletteRealize: Boolean read GetRealize write SetRealize default False;
  194.            property  PaletteMapped: Boolean read GetMapped write SetMapped default False;
  195.     public
  196.            constructor Create(AOwner: TComponent); override;
  197.            destructor  Destroy; override;
  198.            procedure   SetBounds(aLeft, aTop, aWidth, aHeight: integer); override;
  199.            procedure   DrawBackGround; virtual;
  200.            property    DIBCanvas: TMMDIBCanvas read FDIBCanvas write FDIBCanvas;
  201.            property    BitsPerPixel: integer read GetBPP write SetBPP default 8;
  202.     published
  203.            property    Tag2: integer read FTag2 write FTag2;
  204.     end;
  205. {------------------------------------------------------------------------}
  206. { !!! DO NOT TOUCH !!! THIS IS INTERNAL, BUT MUST BE GLOBAL !!!          }
  207. {------------------------------------------------------------------------}
  208. var
  209.    DataSection: TRtlCriticalSection;
  210.    { filled by DIB_InitDrawing and used by the asm stuff }
  211.    biBits: Longint;        { DIB Bits per Pixel          }
  212.    biBPP: Longint;         { DIB Bytes per Pixel         }
  213.    biWidth: Longint;       { DIB Width                   }
  214.    biHeight: Longint;      { DIB Height                  }
  215.    biScanWidth: Longint;   { Real Width for one scanLine }
  216.    biLineDiff: Longint;    { Real differenz to next line }
  217.    biColor: Longint;       { temp. color value           }
  218.    biSurface: Pointer;     { pointer to bitmap data      }
  219.    biPenPos: TPoint;       { internal pen position       }
  220.    biClipRect: TRect;      { clipping rectangle          }
  221. implementation
  222. {$IFDEF WIN32}{$L MMDIB32.OBJ}{$ELSE}{$L MMDIB16.OBJ}{$ENDIF}
  223. {$F+}
  224. procedure TMMDIBCanvas.DIB_Init; external;
  225. procedure TMMDIBCanvas.DIB_SetPixel(X, Y: integer; Color: Longint); external;
  226. function  TMMDIBCanvas.DIB_GetPixel(X, Y: integer): Longint; external;
  227. procedure TMMDIBCanvas.DIB_Line(X1, Y1, X2, Y2: integer); external;
  228. procedure TMMDIBCanvas.DIB_LineNotXor(X1, Y1, X2, Y2: integer); external;
  229. procedure TMMDIBCanvas.DIB_MoveTo(X, Y: integer); external;
  230. procedure TMMDIBCanvas.DIB_LineTo(X, Y: integer); external;
  231. procedure TMMDIBCanvas.DIB_HLine(X1, X2, Y: integer); external;
  232. procedure TMMDIBCanvas.DIB_HLineDashed(X1, X2, Y: integer); external;
  233. procedure TMMDIBCanvas.DIB_HLineDoted(X1, X2, Y, Steps: integer); external;
  234. procedure TMMDIBCanvas.DIB_VLine(X, Y1, Y2: integer); external;
  235. procedure TMMDIBCanvas.DIB_VLineXor(X, Y1, Y2: integer); external;
  236. procedure TMMDIBCanvas.DIB_VLineNotXor(X, Y1, Y2: integer); external;
  237. procedure TMMDIBCanvas.DIB_VLineDashed(X, Y1, Y2: integer); external;
  238. procedure TMMDIBCanvas.DIB_VLineDoted(X, Y1, Y2, Steps: integer); external;
  239. procedure TMMDIBCanvas.DIB_VLineMultiColor(X, Y: integer; Colors: PByte; Cnt: integer); external;
  240. procedure TMMDIBCanvas.DIB_Rectangle(X1, Y1, X2, Y2: integer); external;
  241. procedure TMMDIBCanvas.DIB_FillRect(Rect: TRect); external;
  242. procedure TMMDIBCanvas.DIB_FillRectXor(Rect: TRect); external;
  243. procedure TMMDIBCanvas.DIB_FillRectDoted(Rect: TRect; Doted: Boolean); external;
  244. procedure TMMDIBCanvas.DIB_Ellipse(X, Y: integer; StAngle, EndAngle, XRadius, YRadius: Word); external;
  245. procedure TMMDIBCanvas.DIB_FillEllipse(X, Y: integer; XRadius, YRadius: Word);external;
  246. procedure TMMDIBCanvas.DIB_Clear; external;
  247. procedure TMMDIBCanvas.DIB_CopyDIBBits(Source:Pointer;XDst,YDst,Width,Height,XSrc,YSrc: integer); external;
  248. {$F-}
  249. {-- TMMDIBCanvas --------------------------------------------------------}
  250. constructor TMMDIBCanvas.Create(aOwner: TComponent);
  251. begin
  252.      inherited Create;
  253.      FOwner := aOwner;
  254. {$IFDEF USEWING}
  255.      if (NOT WinGDLLLoaded) then
  256.      {$IFDEF WIN32}
  257.         raise EMMDIBError.Create(LoadResStr(IDS_DLLERROR)+' WING32.DLL');
  258.      {$ELSE}
  259.         raise EMMDIBError.Create(LoadResStr(IDS_DLLERROR)+' WING.DLL');
  260.      {$ENDIF}
  261. {$ENDIF}
  262.      DIB_Init;
  263.      FBits := 8;
  264.      FHDIBDC := 0;
  265.      FHBitmap := 0;
  266.      FHOrigBitmap := 0;
  267.      FHPalette := 0;
  268.      FPSurface := NIL;
  269.      FPBitmapInfo := NIL;
  270.      FPLogPalette := Nil;
  271.      FRealize := False;
  272.      FMapped := False;
  273.      FCanUpdate := True;
  274.      FStretchBgnd := True;
  275.      FPBackSurface := NIL;
  276.      FHBackGround := 0;
  277.      FBackBitmap := TBitmap.Create;
  278.      FBackBitmap.OnChange := BackGroundChanged;
  279.      FWidth := 1;
  280.      FHeight := 1;
  281.      CreateHandle;
  282. end;
  283. {-- TMMDIBCanvas --------------------------------------------------------}
  284. Destructor TMMDIBCanvas.Destroy;
  285. begin
  286.      DestroyDIB;
  287.      FBackBitmap.Free;
  288.      Handle := 0;
  289.      DeleteDC(FHDIBDC);
  290.      FHDIBDC := 0;
  291.      if (FPLogPalette <> nil) then GlobalFreeMem(Pointer(FPLogPalette));
  292.      FreeColors;
  293.      FAnimValues.Free;
  294.      inherited Destroy;
  295. end;
  296. {-- TMMDIBCanvas --------------------------------------------------------}
  297. procedure TMMDIBCanvas.CheckDIB;
  298. begin
  299.    if FNeedUpdate then RecreateDIB;
  300. end;
  301. {-- TMMDIBCanvas --------------------------------------------------------}
  302. procedure TMMDIBCanvas.CreateHandle;
  303. begin
  304.      if (FHDIBDC = 0) then
  305.      begin
  306.           {$IFDEF USEWING}
  307.           FHDIBDC := WinGCreateDC;
  308.           if (FHDIBDC = 0) then
  309.              raise EMMDIBError.Create('Unable to access WinG device context');
  310.           {$ELSE}
  311.           FHDIBDC := CreateCompatibleDC(0);
  312.           if (FHDIBDC = 0) then
  313.              raise EMMDIBError.Create('Unable to access DIB device context');
  314.           {$ENDIF}
  315.           FNeedUpdate := True;
  316.      end;
  317.      CheckDIB;
  318. end;
  319. {-- TMMDIBCanvas --------------------------------------------------------}
  320. procedure TMMDIBCanvas.SetWidth(aWidth: integer);
  321. begin
  322.    SetBounds(0,0,aWidth,FHeight);
  323. end;
  324. {-- TMMDIBCanvas --------------------------------------------------------}
  325. procedure TMMDIBCanvas.SetHeight(aHeight: integer);
  326. begin
  327.    SetBounds(0,0,FWidth,aHeight);
  328. end;
  329. {-- TMMDIBCanvas --------------------------------------------------------}
  330. procedure TMMDIBCanvas.SetBounds(aLeft, aTop, aWidth, aHeight: Integer);
  331. begin
  332.    if (aWidth <> FWidth) or (aHeight <> FHeight) then
  333.    begin
  334.       FWidth := aWidth;
  335.       FHeight := aHeight;
  336.       FClipRect := Rect(0,0,FWidth,FHeight);
  337.       Handle := 0;
  338.       FNeedUpdate := True;
  339.    end;
  340. end;
  341. {-- TMMDIBCanvas --------------------------------------------------------}
  342. procedure TMMDIBCanvas.SetBPP(aValue: integer);
  343. begin
  344.    if (aValue <> FBits) then
  345.    begin
  346.       if (aValue <> 8) and (aValue <> 24) then
  347.          raise EMMDIBError.Create('Bitlength not supported yet');
  348.       FBits := aValue;
  349.       RecreateDIB;
  350.    end;
  351. end;
  352. {-- TMMDIBCanvas --------------------------------------------------------}
  353. procedure TMMDIBCanvas.SetBackBitmap(aBitmap: TBitmap);
  354. begin
  355.      if (aBitmap <> FBackBitmap) then FBackBitmap.Assign(aBitmap);
  356. end;
  357. {-- TMMDIBCanvas --------------------------------------------------------}
  358. procedure TMMDIBCanvas.BackGroundChanged(Sender: TObject);
  359. begin
  360.      RecreateDIB;
  361. end;
  362. {-- TMMDIBCanvas --------------------------------------------------------}
  363. procedure TMMDIBCanvas.SetStretchBgnd(Value: Boolean);
  364. begin
  365.      if (Value <> FStretchBgnd) then
  366.      begin
  367.         FStretchBgnd := Value;
  368.         if not FBackBitmap.Empty then RecreateDIB;
  369.      end;
  370. end;
  371. {-- TMMDIBCanvas --------------------------------------------------------}
  372. procedure TMMDIBCanvas.SetLogPalette(pLogPal: PLogPalette);
  373. begin
  374.    if (FPLogPalette <> nil) then
  375.    begin
  376.       GlobalFreeMem(Pointer(FPLogPalette));
  377.       FPLogPalette := nil;
  378.    end;
  379.    if (pLogPal <> nil) then
  380.    with pLogPal^ do
  381.    if (palVersion >= $300) and (palNumEntries <= 256) then
  382.    begin
  383.       FPLogPalette := GlobalAllocMem(sizeOf(TLogPalette)+sizeOf(TPaletteEntry)*256);
  384.       Move(pLogPal^,FPLogPalette^,sizeOf(TLogPalette)+sizeOf(TPaletteEntry)*palNumEntries);
  385.    end;
  386.    RecreateDIB;
  387. end;
  388. {-- TMMDIBCanvas --------------------------------------------------------}
  389. procedure TMMDIBCanvas.SetRealize(Value: Boolean);
  390. begin
  391.      if (Value <> FRealize) then
  392.      begin
  393.         FRealize := Value;
  394.         RecreateDIB;
  395.      end;
  396. end;
  397. {-- TMMDIBCanvas --------------------------------------------------------}
  398. procedure TMMDIBCanvas.SetMapped(Value: Boolean);
  399. begin
  400.      if (Value <> FMapped) then
  401.      begin
  402.         FMapped := Value;
  403.      end;
  404. end;
  405. {------------------------------------------------------------------------}
  406. { It is possible, because number palette entries <= 256 }
  407. function FindUniqueColor(Pal: PLogPalette): TColorRef;
  408. var
  409.     N : Integer;
  410.     C : TColorRef;
  411.     function Unique: Boolean;
  412.     var
  413.        i: Integer;
  414.     begin
  415.        Result := False;
  416.        for i := 0 to N - 1 do
  417.        with Pal^.palPalEntry[i] do
  418.        if RGB(peRed,peGreen,peBlue) = C then
  419.           Exit;
  420.        Result := True;
  421.     end;
  422. begin
  423.    N := Pal^.palNumEntries;
  424.    C := 0;
  425.    while not Unique do Inc(C);
  426.    Result := C;
  427. end;
  428. {------------------------------------------------------------------------}
  429. function ColorToPalEntry(C: TColorRef): TPaletteEntry;
  430. begin
  431.    with Result do
  432.    begin
  433.       peRed   := GetRValue(C);
  434.       peGreen := GetGValue(C);
  435.       peBlue  := GetBValue(C);
  436.       peFlags := PC_RESERVED;
  437.    end;
  438. end;
  439. {-- TMMDIBCanvas --------------------------------------------------------}
  440. procedure TMMDIBCanvas.CreateDIB;
  441. Var
  442.    LogPal: PLogPalette;
  443.    {$IFDEF WIN32}
  444.    BackBitImageSize: DWord;
  445.    BackBitInfoSize: DWord;
  446.    {$ELSE}
  447.    BackBitImageSize: Longint;
  448.    BackBitInfoSize: Longint;
  449.    {$ENDIF}
  450.    BackBitInfo: PBitmapInfo;
  451.    BackBitImage: Pointer;
  452.    i,j,H,W,aWidth,aHeight: integer;
  453.    C: TColorRef;
  454. begin
  455.      if (FHDIBDC = 0) then exit;
  456.      LogPal := nil;
  457.      BackBitInfo := nil;
  458.      BackBitImage := nil;
  459.      {$IFNDEF WIN32}
  460.      FBits := 8;
  461.      {$ENDIF}
  462.      { create the bitmap header }
  463.      FPBitmapInfo := PBitmapInfo(DIB_Create(FBits,DIB_ORIENT,FWidth,FHeight,False));
  464.      with FPBitMapInfo^.bmiHeader do
  465.      begin
  466.           {$IFDEF USEWING}
  467.           if WinGRecommendDIBFormat(FPBitMapInfo) then
  468.           begin        { make sure it's 8bpp and remember the orientation }
  469.                biBitCount := FBits;
  470.                biCompression := BI_RGB;
  471.           end;
  472.           {$ENDIF}
  473.           biWidth := Max(FWidth,1);
  474.           biHeight := Max(FHeight,1) * DIB_ORIENT;
  475.      end;
  476.      LogPal := CreateSystemColorPalette;
  477.      try
  478.         with LogPal^ do
  479.         begin
  480.            if (FBackBitmap <> nil) and (not FBackBitmap.Empty) then
  481.            begin
  482.               GetDIBSizes(FBackBitmap.Handle, BackBitInfoSize, BackBitImageSize);
  483.               BackBitInfo:= GlobalAllocMem(BackBitInfoSize);
  484.               BackBitImage:= GlobalAllocMem(BackBitImageSize);
  485.               GetDIB(FBackBitmap.Handle, FBackBitmap.Palette, BackBitInfo^, BackBitImage^);
  486.               i := 10;
  487.               GetPaletteEntries(FBackBitmap.Palette, i, 235, palPalEntry[i]);
  488.            end
  489.            else if (FPLogPalette <> nil) then
  490.            begin
  491.               for i := 10 to 246 do
  492.               with FPLogPalette^.palPalEntry[i] do
  493.               begin
  494.                  palPalEntry[i].peRed := peRed;
  495.                  palPalEntry[i].peGreen := peGreen;
  496.                  palPalEntry[i].peBlue := peBlue;
  497.                  palPalEntry[i].peFlags := PC_NOCOLLAPSE;
  498.               end;
  499.            end;
  500.            FreeColors;
  501.            if FAnimCount <> 0 then
  502.            begin
  503.               FAnimColors := TList.Create;
  504.               { For now let's alloc upper colors for animation }
  505.               for i := 246 - FAnimCount + 1 to 246 do
  506.               begin
  507.                  C := FindUniqueColor(LogPal);
  508.                  palPalEntry[i] := ColorToPalEntry(C);
  509.                  FAnimColors.Add(Pointer(LongInt(C)));
  510.               end;
  511.               FAnimFirst := 246 - FAnimCount + 1;
  512.            end
  513.            else FAnimFirst := 256;
  514.            { copy from the palette to the DIB bitmap color table }
  515.            for i := 0 to 255 do
  516.            with FPBitmapInfo^.bmiColors[i], palPalEntry[i] do
  517.            begin
  518.               rgbRed := peRed;
  519.               rgbGreen := peGreen;
  520.               rgbBlue := peBlue;
  521.               { Set the PC_NOCOLLAPSE flag for each of our colors so }
  522.               { that GDI won't merge them together.  Be careful not  }
  523.               { to set PC_NOCOLLAPSE for the sys color entries or    }
  524.               { we'll get multpile copies of these colors in the     }
  525.               { palette when we realize it.                          }
  526.               if (i > 9) and (i < 246) and not (i >= FAnimFirst) then
  527.                  rgbReserved := PC_NOCOLLAPSE
  528.               else
  529.                  rgbReserved := 0;
  530.            end;
  531.            { create the palette }
  532.            FHPalette := CreatePalette(LogPal^);
  533.         end;
  534.         if (FBackBitmap <> NIL) and (not FBackBitmap.Empty) then
  535.         begin
  536.            {$IFDEF USEWING}
  537.            FHBackGround := WinGCreateBitmap(FHDIBDC, FPBitMapInfo, @FPBackSurface);
  538.            {$ELSE}
  539.            FHBackGround := CreateDIBSection(FHDIBDC, FPBitMapInfo^, DIB_RGB_Colors,
  540.                                             FPBackSurface, {$IFDEF DELPHI3}0{$ELSE}Nil{$ENDIF}, 0);
  541.            {$ENDIF}
  542.            FHOrigBitmap := SelectObject(FHDIBDC, FHBackGround);
  543.            aWidth  := BackBitInfo^.bmiHeader.biWidth;
  544.            aHeight := BackBitInfo^.bmiHeader.biHeight;
  545.            SetStretchBltMode(FHDIBDC, STRETCH_DELETESCANS);
  546.            if FStretchBgnd then
  547.            begin
  548.               StretchDIBits(FHDIBDC,
  549.                             0, 0,
  550.                             FWidth,
  551.                             FHeight,
  552.                             0, 0,
  553.                             aWidth,
  554.                             aHeight,
  555.                             BackBitImage,
  556.                             BackBitInfo^,
  557.                             DIB_RGB_Colors,
  558.                             SRCCOPY);
  559.            end
  560.            else
  561.            begin
  562.               i := 0;
  563.               H := FHeight;
  564.               while H > 0 do
  565.               begin
  566.                  j := 0;
  567.                  W := FWidth;
  568.                  while W > 0 do
  569.                  begin
  570.                     StretchDIBits(FHDIBDC,
  571.                                   j*aWidth, i*aHeight,
  572.                                   aWidth,aHeight,
  573.                                   0, 0,
  574.                                   aWidth,
  575.                                   aHeight,
  576.                                   BackBitImage,
  577.                                   BackBitInfo^,
  578.                                   DIB_RGB_Colors,
  579.                                   SRCCOPY);
  580.                     dec(W,aWidth);
  581.                     inc(j);
  582.                  end;
  583.                  dec(H,aHeight);
  584.                  inc(i);
  585.               end;
  586.            end;
  587.            FHBackGround := SelectObject(FHDIBDC, FHOrigBitmap);
  588.         end;
  589.      finally
  590.         GlobalFreeMem(Pointer(BackBitInfo));
  591.         GlobalFreeMem(Pointer(BackBitImage));
  592.         GlobalFreeMem(Pointer(LogPal));
  593.      end;
  594.      {$IFDEF USEWING}
  595.      FHBitmap := WinGCreateBitmap(FHDIBDC, FPBitMapInfo, @FPSurface);
  596.      {$ELSE}
  597.      FHBitmap := CreateDIBSection(FHDIBDC, FPBitMapInfo^, DIB_RGB_Colors,
  598.                                   FPSurface, {$IFDEF DELPHI3}0{$ELSE}nil{$ENDIF}, 0);
  599.      {$ENDIF}
  600.      FHOrigBitmap := SelectObject(FHDIBDC, FHBitmap);
  601.      PatBlt(FHDIBDC, 0, 0, FWidth, FHeight, BLACKNESS);
  602.      Handle := FHDIBDC;
  603.      FNeedUpdate := False;
  604. end;
  605. {-- TMMDIBCanvas --------------------------------------------------------}
  606. procedure TMMDIBCanvas.DestroyDIB;
  607. begin
  608.      if (FHBackGround <> 0) then
  609.      begin
  610.           DeleteObject(FHBackGround);
  611.           FHBackGround := 0;
  612.           FPBackSurface := NIL;
  613.      end;
  614.      if (FHBitmap <> 0) then
  615.      begin
  616.           SelectObject(FHDIBDC, FHOrigBitmap);
  617.           DeleteObject(FHBitmap);
  618.           FHBitmap := 0;
  619.           FPSurface := NIL;
  620.      end;
  621.      if (FHPalette <> 0) then
  622.      begin
  623.           DeleteObject(FHPalette);
  624.           FHPalette := 0;
  625.      end;
  626.      if (FPBitmapInfo <> nil) then
  627.         GlobalFreeMem(Pointer(FPBitmapInfo));
  628. end;
  629. {-- TMMDIBCanvas --------------------------------------------------------}
  630. procedure TMMDIBCanvas.RecreateDIB;
  631. begin
  632.      if not FCanUpdate then
  633.         raise EMMDIBError.Create(FOwner.ClassName +': Attempt to create new DIB while initialized for drawing');
  634.      DestroyDIB;
  635.      CreateDIB;
  636. end;
  637. {-- TMMDIBCanvas --------------------------------------------------------}
  638. procedure TMMDIBCanvas.DIB_BitBlt(DestDC: THandle; Dest: TRect; X, Y: integer);
  639. Var
  640.    oldPalette: HPalette;
  641. begin
  642.      if (Handle <> 0) and (DestDC <> 0) then
  643.      with Dest do
  644.      begin
  645.           if FRealize then
  646.           begin
  647.                oldPalette := SelectPalette(DestDC, FHPalette, not FMapped);
  648.                RealizePalette(DestDC);
  649.                {$IFDEF USEWING}
  650.                WinGBitBlt(DestDC, Left, Top, Right, Bottom, FHDIBDC, X, Y);
  651.                {$ELSE}
  652.                BitBlt(DestDC, Left, Top, Right, Bottom, FHDIBDC, X, Y, SRCCOPY);
  653.                {$ENDIF}
  654.                SelectPalette(DestDC, OldPalette, not FMapped);
  655.                RealizePalette(DestDC);
  656.           end
  657.           else
  658.           begin
  659.               {$IFDEF USEWING}
  660.               WinGBitBlt(DestDC, Left, Top, Right, Bottom, FHDIBDC, X, Y);
  661.               {$ELSE}
  662.               BitBlt(DestDC, Left, Top, Right, Bottom, FHDIBDC, X, Y, SRCCOPY);
  663.               {$ENDIF}
  664.           end;
  665.           {$IFDEF WIN32}
  666.           GDIFlush;
  667.           {$ENDIF}
  668.      end;
  669. end;
  670. {-- TMMDIBCanvas --------------------------------------------------------}
  671. procedure TMMDIBCanvas.DIB_StretchBlt(DestDC: THandle; Dest: TRect; Src: TRect);
  672. Var
  673.    oldPalette: HPalette;
  674. begin
  675.      if (Handle <> 0) and (DestDC <> 0) then
  676.      with Dest do
  677.      begin
  678.           if FRealize then
  679.           begin
  680.                oldPalette := SelectPalette(DestDC, FHPalette, not FMapped);
  681.                RealizePalette(DestDC);
  682.                {$IFDEF USEWING}
  683.                WinGStretchBlt(DestDC, Left, Top, Right, Bottom,
  684.                               FHDIBDC, Src.Left, Src.Top, Src.Right, Src.Bottom);
  685.                {$ELSE}
  686.                StretchBlt(DestDC, Left, Top, Right, Bottom,
  687.                           FHDIBDC, Src.Left, Src.Top, Src.Right, Src.Bottom, SRCCOPY);
  688.                {$ENDIF}
  689.                SelectPalette(DestDC, OldPalette, not FMapped);
  690.                RealizePalette(DestDC);
  691.           end
  692.           else
  693.           begin
  694.               {$IFDEF USEWING}
  695.               WinGStretchBlt(DestDC, Left, Top, Right, Bottom,
  696.                              FHDIBDC, Src.Left, Src.Top, Src.Right, Src.Bottom);
  697.               {$ELSE}
  698.               StretchBlt(DestDC, Left, Top, Right, Bottom,
  699.                          FHDIBDC, Src.Left, Src.Top, Src.Right, Src.Bottom, SRCCOPY);
  700.               {$ENDIF}
  701.           end;
  702.           {$IFDEF WIN32}
  703.           GDIFlush;
  704.           {$ENDIF}
  705.      end;
  706. end;
  707. {-- TMMDIBCanvas --------------------------------------------------------}
  708. function TMMDIBCanvas.DIB_GetPixelAddress(aSurface: Pointer; X, Y: integer): Pointer;
  709. var
  710.    biScanWidth,BPP: integer;
  711. begin
  712.    { make sure it's in range and if not return nil }
  713.    if (X >= FWidth) or (Y >= FHeight) then
  714.       raise EMMDIBError.Create('Attempt to get out of range pixel address');
  715.    BPP := FBits shr 3;
  716.    { Calculate the scan line storage width }
  717.    biScanWidth := (FWidth*BPP + 3) and not 3;
  718.    if (DIB_ORIENT = DIB_TOPDOWN) then
  719.       Result := PChar(aSurface) + (Y * biScanWidth) + (X*BPP)
  720.    else
  721.       Result := PChar(aSurface) + ((FHeight-1-Y) * biScanWidth) + (X*BPP);
  722. end;
  723. {-- TMMDIBCanvas --------------------------------------------------------}
  724. function TMMDIBCanvas.DIB_ColorToIndex(Color: TColor): Longint;
  725. begin
  726.      Result := ColorToRGB(Color);
  727.      if FBits <= 8 then
  728.         Result := GetNearestPaletteIndex(FHPalette, Result);
  729. end;
  730. {-- TMMDIBCanvas --------------------------------------------------------}
  731. procedure TMMDIBCanvas.DIB_SetClipRect(R: TRect);
  732. begin
  733.      FClipRect.Left  := Max(R.Left,0);
  734.      FClipRect.Top   := Max(R.Top,0);
  735.      FClipRect.Right := Min(R.Right,FWidth);
  736.      FClipRect.Bottom:= Min(R.Bottom,FHeight);
  737.      biClipRect := FClipRect;
  738. end;
  739. {-- TMMDIBCanvas --------------------------------------------------------}
  740. function TMMDIBCanvas.DIB_GetClipRect: TRect;
  741. begin
  742.     Result := FClipRect;
  743. end;
  744. {-- TMMDIBCanvas --------------------------------------------------------}
  745. procedure TMMDIBCanvas.DIB_SetTColor(Color: TColor);
  746. var
  747.    Temp: Longint;
  748. begin
  749.      Temp := ColorToRGB(Color);
  750.      if FBits = 24 then
  751.      begin
  752.         biColor := Temp;
  753.      end
  754.      else
  755.      begin
  756.         Temp := GetNearestPaletteIndex(FHPalette, Temp);
  757.         asm
  758.            mov  al, Temp.Byte[0]
  759.            mov  ah, al
  760.            mov  biColor.Word[0], ax
  761.            mov  biColor.Word[2], ax
  762.         end;
  763.      end;
  764. end;
  765. {-- TMMDIBCanvas --------------------------------------------------------}
  766. procedure TMMDIBCanvas.DIB_SetColorRef(ColorRef: Longint);
  767. var
  768.    Temp: integer;
  769. begin
  770.      if FBits = 24 then
  771.      begin
  772.         biColor := ColorRef;
  773.      end
  774.      else
  775.      begin
  776.         Temp := GetNearestPaletteIndex(FHPalette, ColorRef);
  777.         asm
  778.            mov  al, Temp.Byte[0]
  779.            mov  ah, al
  780.            mov  biColor.Word[0], ax
  781.            mov  biColor.Word[2], ax
  782.         end;
  783.      end;
  784. end;
  785. {-- TMMDIBCanvas --------------------------------------------------------}
  786. procedure TMMDIBCanvas.DIB_SetColor(Index: Longint);
  787. begin
  788.    if FBits = 24 then
  789.    begin
  790.       biColor := Index;
  791.    end
  792.    else
  793.    begin
  794.       asm
  795.          {$IFDEF WIN32}
  796.          mov  dh, dl
  797.          mov  biColor.Word[0], dx
  798.          mov  biColor.Word[2], dx
  799.          {$ELSE}
  800.          mov  al, byte ptr [Index]
  801.          mov  ah, al
  802.          mov  biColor.Word[0], ax
  803.          mov  biColor.Word[2], ax
  804.          {$ENDIF}
  805.       end;
  806.    end;
  807. end;
  808. {-- TMMDIBCanvas --------------------------------------------------------}
  809. procedure TMMDIBCanvas.DIB_InitDrawing;
  810. begin
  811.      EnterCriticalSection(DataSection);
  812.      Changing;
  813.      CheckDIB;
  814.      biPenPos.X := 0;
  815.      biPenPos.Y := 0;
  816.      biBits := FBits;
  817.      biBPP := FBits shr 3;
  818.      biHeight := FHeight;
  819.      biWidth := FWidth;
  820.      biScanWidth := (FWidth*biBPP + 3) and not 3;
  821.      biLineDiff := biScanWidth * -DIB_ORIENT;
  822.      biSurface:= FPSurface;
  823.      biClipRect := FClipRect;
  824.      FCanUpdate := False;
  825.      {$IFDEF WIN32}
  826.      GDIFlush;
  827.      {$ENDIF}
  828. end;
  829. {-- TMMDIBCanvas --------------------------------------------------------}
  830. procedure TMMDIBCanvas.DIB_DoneDrawing;
  831. begin
  832.      biPenPos.X := 0;
  833.      biPenPos.Y := 0;
  834.      biHeight := 0;
  835.      biWidth := 0;
  836.      biScanWidth := 0;
  837.      biSurface:= nil;
  838.      FCanUpdate := True;
  839.      Changed;
  840.      LeaveCriticalSection(DataSection);
  841. end;
  842. const
  843.     MaxAnimColors = 246 - 10;
  844. {-- TMMDIBCanvas --------------------------------------------------------}
  845. procedure TMMDIBCanvas.FreeColors;
  846. begin
  847.    if FAnimColors <> nil then
  848.       FAnimColors.Free;
  849.    FAnimColors := nil;
  850. end;
  851. {-- TMMDIBCanvas --------------------------------------------------------}
  852. function  TMMDIBCanvas.GetAnimCount: Integer;
  853. begin
  854.    if FAnimColors <> nil then
  855.       Result := FAnimColors.Count
  856.    else
  857.       Result := 0;
  858. end;
  859. {-- TMMDIBCanvas --------------------------------------------------------}
  860. procedure TMMDIBCanvas.SetAnimCount(Value: Integer);
  861. begin
  862.    if (Value < 0) or (Value > MaxAnimColors) then
  863.       { TODO: Should be res id }
  864.       raise EMMDIBError.Create('Invalid count of animated colors');
  865.    if Value <> AnimatedColorCount then
  866.    begin
  867.       FAnimCount := Value;
  868.       RecreateDIB;
  869.    end;
  870. end;
  871. {-- TMMDIBCanvas --------------------------------------------------------}
  872. function  TMMDIBCanvas.GetAnimColor(Index: Integer): TColor ;
  873. begin
  874.    if not InRange(Index,0,AnimatedColorCount-1) then
  875.       { Should be res id }
  876.       raise EMMDIBError.Create('Invalidate animated color index');
  877.    Result := TColorRef(FAnimColors[Index]);
  878. end;
  879. {------------------------------------------------------------------------}
  880. function QuadToColor(Q: TRGBQuad): TColorRef;
  881. begin
  882.    with Q do Result := RGB(rgbRed,rgbGreen,rgbBlue);
  883. end;
  884. {------------------------------------------------------------------------}
  885. function ColorToQuad(C: TColorRef): TRGBQuad;
  886. begin
  887.    with Result do
  888.    begin
  889.       rgbRed  := GetRValue(C);
  890.       rgbGreen:= GetGValue(C);
  891.       rgbBlue := GetBValue(C);
  892.    end;
  893. end;
  894. {-- TMMDIBCanvas --------------------------------------------------------}
  895. function TMMDIBCanvas.GetAnimColorValue(Index: Integer): TColor;
  896. var
  897.    Pal: array[0..255] of TRGBQuad;
  898. begin
  899.    if not InRange(Index,0,AnimatedColorCount-1) then
  900.       { Should be res id }
  901.       raise EMMDIBError.Create('Invalidate animated color index');
  902.    {$IFDEF WIN32}
  903.    if GetDIBColorTable(Handle,0,256,Pal) <> 256 then
  904.    {$ELSE}
  905.    if WinGGetDIBColorTable(Handle,0,256,@Pal) <> 256 then
  906.    {$ENDIF}
  907.       { TODO: Should be res id }
  908.       raise EMMDIBError.Create('Get palette entries failed');
  909.    Result := QuadToColor(Pal[FAnimFirst+Index]);
  910. end;
  911. {-- TMMDIBCanvas --------------------------------------------------------}
  912. procedure TMMDIBCanvas.SetAnimColorValue(Index: Integer; Value: TColor);
  913. var
  914.    Pal1: array[0..255] of TRGBQuad;
  915.    Pal2: array[0..255] of TPaletteEntry;
  916. begin
  917.    if not InRange(Index,0,AnimatedColorCount-1) then
  918.       { Should be res id }
  919.       raise EMMDIBError.Create('Invalidate animated color index');
  920.    Value := ColorToRGB(Value);
  921.    if FAnimLock > 0 then
  922.    begin
  923.       FAnimValues[Index] := Pointer(Value);
  924.       Exit;
  925.    end;
  926.    {$IFDEF WIN32}
  927.    if GetDIBColorTable(Handle,0,256,Pal1) <> 256 then
  928.    {$ELSE}
  929.    if WinGGetDIBColorTable(Handle,0,256,@Pal1) <> 256 then
  930.    {$ENDIF}
  931.       { TODO: Should be res id }
  932.       raise EMMDIBError.Create('Get palette entries failed');
  933.    if GetPaletteEntries(FHPalette,0,256,Pal2) <> 256 then
  934.       { TODO: Should be res id }
  935.       raise EMMDIBError.Create('Get palette entries failed');
  936.    Pal1[FAnimFirst+Index] := ColorToQuad(Value);
  937.    Pal2[FAnimFirst+Index] := ColorToPalEntry(Value);
  938.    {$IFDEF WIN32}
  939.    if SetDIBColorTable(Handle,0,256,Pal1) <> 256 then
  940.    {$ELSE}
  941.    if WinGSetDIBColorTable(Handle,0,256,@Pal1) <> 256 then
  942.    {$ENDIF}
  943.       { TODO: Should be res id }
  944.       raise EMMDIBError.Create('Set palette entries failed');
  945.    {$IFDEF WIN32}
  946.    if not AnimatePalette(FHPalette,0,256,@Pal2[0]) then
  947.       { TODO: Should be res id }
  948.       raise EMMDIBError.Create('Animation of palette entries failed');
  949.    {$ELSE}
  950.    AnimatePalette(FHPalette,0,256,Pal2[0]);
  951.    {$ENDIF}
  952. end;
  953. {-- TMMDIBCanvas --------------------------------------------------------}
  954. function  TMMDIBCanvas.GetAnimColorIndex(Index: Integer): Integer;
  955. begin
  956.    Result := FAnimFirst + Index;
  957. end;
  958. {-- TMMDIBCanvas --------------------------------------------------------}
  959. procedure TMMDIBCanvas.BeginAnimate;
  960. var
  961.    Pal : array[0..255] of TRGBQuad;
  962.    i   : Integer;
  963. begin
  964.    Inc(FAnimLock);
  965.    if (FAnimLock = 1) and (AnimatedColorCount > 0) then
  966.    begin
  967.       {$IFDEF WIN32}
  968.       if GetDIBColorTable(Handle,FAnimFirst,AnimatedColorCount,Pal) <> UINT(AnimatedColorCount) then
  969.       {$ELSE}
  970.       if WinGGetDIBColorTable(Handle,FAnimFirst,AnimatedColorCount,@Pal) <> AnimatedColorCount then
  971.       {$ENDIF}
  972.          { TODO: Should be res id }
  973.          raise EMMDIBError.Create('Get palette entries failed');
  974.       FAnimValues := TList.Create;
  975.       for i := 0 to AnimatedColorCount - 1 do
  976.           FAnimValues.Add(Pointer(QuadToColor(Pal[i])));
  977.    end;
  978. end;
  979. {-- TMMDIBCanvas --------------------------------------------------------}
  980. procedure TMMDIBCanvas.EndAnimate;
  981. var
  982.    Pal1: array[0..255] of TRGBQuad;
  983.    Pal2: array[0..255] of TPaletteEntry;
  984.    i   : Integer;
  985. begin
  986.    Dec(FAnimLock);
  987.    if (FAnimLock = 0) and (AnimatedColorCount > 0) then
  988.    begin
  989.       for i := 0 to AnimatedColorCount - 1 do
  990.       begin
  991.          Pal1[i] := ColorToQuad(TColorRef(FAnimValues[i]));
  992.          Pal2[i] := ColorToPalEntry(TColorRef(FAnimValues[i]));
  993.       end;
  994.       try
  995.          {$IFDEF WIN32}
  996.          if SetDIBColorTable(Handle,FAnimFirst,AnimatedColorCount,Pal1) <> UINT(AnimatedColorCount) then
  997.          {$ELSE}
  998.          if WinGSetDIBColorTable(Handle,FAnimFirst,AnimatedColorCount,@Pal1) <> AnimatedColorCount then
  999.          {$ENDIF}
  1000.             { TODO: Should be res id }
  1001.             raise EMMDIBError.Create('Set palette entries failed');
  1002.          {$IFDEF WIN32}
  1003.          if not AnimatePalette(FHPalette,FAnimFirst,AnimatedColorCount,@Pal2[0]) then
  1004.             { TODO: Should be res id }
  1005.             raise EMMDIBError.Create('Animation of palette entries failed');
  1006.          {$ELSE}
  1007.          AnimatePalette(FHPalette,FAnimFirst,AnimatedColorCount,Pal2[0]);
  1008.          {$ENDIF}
  1009.       finally
  1010.          FAnimValues.Free;
  1011.          FAnimValues := nil;
  1012.       end;
  1013.    end;
  1014. end;
  1015. {== TMMDIBGraphicControl ================================================}
  1016. constructor TMMDIBGraphicControl.Create(AOwner: TComponent);
  1017. begin
  1018.      inherited Create(AOwner);
  1019.      FDIBCanvas := TMMDIBCanvas.Create(Self);
  1020.      FUseBackDIB := False;
  1021.      PaletteRealize := False;
  1022.      PaletteMapped := False;
  1023.      FBackGround := TBitmap.Create;
  1024.      FBackGround.OnChange := BackGroundChanged;
  1025. end;
  1026. {-- TMMDIBGraphicControl ------------------------------------------------}
  1027. destructor TMMDIBGraphicControl.Destroy;
  1028. begin
  1029.    FBackGround.Free;
  1030.    FDIBCanvas.Free;
  1031.    inherited Destroy;
  1032. end;
  1033. {-- TMMDIBGraphicControl ------------------------------------------------}
  1034. procedure TMMDIBGraphicControl.SetBPP(aValue: integer);
  1035. begin
  1036.    FDIBCanvas.BitsPerPixel := aValue;
  1037.    Invalidate;
  1038. end;
  1039. {-- TMMDIBGraphicControl ------------------------------------------------}
  1040. function TMMDIBGraphicControl.GetBPP: integer;
  1041. begin
  1042.    Result := FDIBCanvas.BitsPerPixel;
  1043. end;
  1044. {-- TMMDIBGraphicControl ------------------------------------------------}
  1045. procedure TMMDIBGraphicControl.SetBounds(aLeft, aTop, aWidth, aHeight: integer);
  1046. begin
  1047.    inherited SetBounds(aLeft,aTop,aWidth,aHeight);
  1048.    FDIBCanvas.SetBounds(aLeft, aTop, aWidth, aHeight);
  1049. end;
  1050. {-- TMMDIBGraphicControl ------------------------------------------------}
  1051. procedure TMMDIBGraphicControl.Loaded;
  1052. begin
  1053.    inherited Loaded;
  1054.    UseBackgroundDIB := FTempUseDIB;
  1055. end;
  1056. {-- TMMDIBGraphicControl ------------------------------------------------}
  1057. function TMMDIBGraphicControl.GetPalette: HPALETTE;
  1058. begin
  1059.    if PaletteRealize then
  1060.       Result := FDIBCanvas.Palette
  1061.    else
  1062.       Result := inherited GetPalette;
  1063. end;
  1064. {-- TMMDIBGraphicControl ------------------------------------------------}
  1065. procedure TMMDIBGraphicControl.SetRealize(aValue: Boolean);
  1066. begin
  1067.    if (aValue <> FDIBCanvas.PaletteRealize) then
  1068.    begin
  1069.       FDIBCanvas.PaletteRealize := aValue;
  1070.       Invalidate;
  1071.    end;
  1072. end;
  1073. {-- TMMDIBGraphicControl ------------------------------------------------}
  1074. function TMMDIBGraphicControl.GetRealize: Boolean;
  1075. begin
  1076.    Result := FDIBCanvas.PaletteRealize;
  1077. end;
  1078. {-- TMMDIBGraphicControl ------------------------------------------------}
  1079. procedure TMMDIBGraphicControl.SetMapped(aValue: Boolean);
  1080. begin
  1081.    if (aValue <> FDIBCanvas.PaletteMapped) then
  1082.    begin
  1083.       FDIBCanvas.PaletteMapped := aValue;
  1084.       Invalidate;
  1085.    end;
  1086. end;
  1087. {-- TMMDIBGraphicControl ------------------------------------------------}
  1088. function TMMDIBGraphicControl.GetMapped: Boolean;
  1089. begin
  1090.    Result := FDIBCanvas.PaletteMapped;
  1091. end;
  1092. {-- TMMDIBGraphicControl ------------------------------------------------}
  1093. procedure TMMDIBGraphicControl.SetBackGround(aBitmap: TBitmap);
  1094. begin
  1095.    FBackGround.Assign(aBitmap);
  1096. end;
  1097. {-- TMMDIBGraphicControl ------------------------------------------------}
  1098. procedure TMMDIBGraphicControl.BackGroundChanged(Sender: TObject);
  1099. begin
  1100.    if not (csLoading in ComponentState) then
  1101.    begin
  1102.       if (csDesigning in ComponentState) then
  1103.       begin
  1104.          if (FBackGround.Empty) then
  1105.          begin
  1106.             PaletteRealize := False;
  1107.             PaletteMapped := False;
  1108.             FUseBackDIB := False;
  1109.          end
  1110.          else
  1111.          begin
  1112.             PaletteRealize := True;
  1113.             FUseBackDIB := True;
  1114.          end;
  1115.       end;
  1116.       if FUseBackDIB then
  1117.          FDIBCanvas.BackGroundBitmap := FBackGround
  1118.       else
  1119.          FDIBCanvas.BackGroundBitmap := NIL;
  1120.      Invalidate;
  1121.    end;
  1122. end;
  1123. {-- TMMDIBGraphicControl ------------------------------------------------}
  1124. procedure TMMDIBGraphicControl.SetUseBackDIB(aValue: Boolean);
  1125. begin
  1126.    if csLoading in ComponentState then
  1127.    begin
  1128.       FTempUseDIB := aValue;
  1129.       Exit;
  1130.    end;
  1131.    if (aValue <> FUseBackDIB) then
  1132.    begin
  1133.       if aValue And (NOT FBackGround.Empty) then
  1134.          FUseBackDIB := True
  1135.       else
  1136.          FUseBackDIB := False;
  1137.       if (not (csLoading in ComponentState)) then
  1138.       begin
  1139.          PaletteRealize := FUseBackDIB;
  1140.          if FUseBackDIB then FDIBCanvas.BackGroundBitmap := FBackGround
  1141.          else FDIBCanvas.BackGroundBitmap := NIL;
  1142.       end;
  1143.       Invalidate;
  1144.    end;
  1145. end;
  1146. {-- TMMDIBGraphicControl ------------------------------------------------}
  1147. procedure TMMDIBGraphicControl.DrawBackGround;
  1148. begin
  1149.      with FDIBCanvas do
  1150.      begin                                         { copy background DIB }
  1151.           if (FPSurface <> NIL) AND (FPBackSurface <> NIL) then
  1152.              DIB_CopyDIBBits(FPBackSurface,0,0,FWidth,FHeight,0,0)
  1153.           else
  1154.           begin
  1155.                DIB_SetTColor(Color);
  1156.                DIB_Clear;                             { clear background }
  1157.           end;
  1158.      end;
  1159. end;
  1160. {-- TMMDIBGraphicControl ------------------------------------------------}
  1161. procedure TMMDIBGraphicControl.FastDraw(DrawProc: TMMDIBDrawProc; Clear: Boolean);
  1162. var
  1163.   DC: HDC;
  1164.   Control: TWinControl;
  1165. begin
  1166.    {$IFDEF BUILD_ACTIVEX}
  1167.    Control := Self;
  1168.    {$ELSE}
  1169.    Control := Parent;
  1170.    {$ENDIF}
  1171.    if Visible and (Control <> nil) and Control.HandleAllocated then
  1172.    begin
  1173.       DC := GetDC(Control.Handle);
  1174.       try
  1175.         {$IFDEF DELPHI3}
  1176.         Canvas.Lock;
  1177.         {$ENDIF}
  1178.         {$IFNDEF BUILD_ACTIVEX}
  1179.         if RectVisible(DC, Rect(Left, Top, Left + Width, Top + Height)) then
  1180.         begin
  1181.            MoveWindowOrg(DC, Left, Top);
  1182.            IntersectClipRect(DC, 0, 0, Width, Height);
  1183.         {$ELSE}
  1184.         if RectVisible(DC, Rect(0, 0, Width, Height)) then
  1185.         begin
  1186.         {$ENDIF}
  1187.            Canvas.Handle := DC;
  1188.            DrawProc(Clear);
  1189.         end;
  1190.       finally
  1191.         Canvas.Handle := 0;
  1192.         ReleaseDC(Control.Handle, DC);
  1193.         {$IFDEF DELPHI3}
  1194.         Canvas.Unlock;
  1195.         {$ENDIF}
  1196.       end;
  1197.   end;
  1198. end;
  1199. initialization
  1200.   InitializeCriticalSection(DataSection);
  1201. finalization
  1202.   DeleteCriticalSection(DataSection);
  1203. end.