VrFormShape.pas
上传用户:hbszzs
上传日期:2008-08-20
资源大小:628k
文件大小:7k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*****************************************************}
  2. {                                                     }
  3. {     Varian Component Workshop                       }
  4. {                                                     }
  5. {     Varian Software NL (c) 1996-2000                }
  6. {     All Rights Reserved                             }
  7. {                                                     }
  8. {*****************************************************}
  9. unit VrFormShape;
  10. {$I VRLIB.INC}
  11. interface
  12. uses
  13.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  14.   VrControls, VrSysUtils;
  15. type
  16.   TVrRgnData = class(TPersistent)
  17.   private
  18.     FSize: Integer;
  19.     FBuffer: PRgnData;
  20.     procedure SetSize(Value: Integer);
  21.   public
  22.     destructor Destroy; override;
  23.     property Size: Integer read FSize write SetSize;
  24.     property Buffer: PRgnData read FBuffer write FBuffer;
  25.   end;
  26.   TVrFormShape = class(TVrGraphicImageControl)
  27.   private
  28.     FMask: TBitmap;
  29.     FRgnData: TVrRgnData;
  30.     FRgn: HRgn;
  31.     function GetMaskColor: TColor;
  32.     procedure SetMask(Value: TBitmap);
  33.     procedure SetMaskColor(Value: TColor);
  34.     procedure UpdateMask;
  35.     procedure UpdateRegion;
  36.     procedure ReadMask(Reader: TStream);
  37.     procedure WriteMask(Writer: TStream);
  38.     procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
  39.   protected
  40.     procedure Paint; override;
  41.     procedure Loaded; override;
  42.     procedure SetParent(Value: TWinControl); override;
  43.     procedure DefineProperties(Filer: TFiler); override;
  44.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  45.       X, Y: Integer);override;
  46.   public
  47.     constructor Create(AOwner: TComponent); override;
  48.     destructor Destroy; override;
  49.   published
  50.     property Mask: TBitmap read FMask write SetMask;
  51.     property MaskColor: TColor read GetMaskColor write SetMaskColor;
  52.     property DragCursor;
  53. {$IFDEF VER110}
  54.     property DragKind;
  55. {$ENDIF}
  56.     property DragMode;
  57.     property Hint;
  58.     property ParentShowHint;
  59.     property PopupMenu;
  60.     property ShowHint;
  61.     property OnClick;
  62. {$IFDEF VER130}
  63.     property OnContextPopup;
  64. {$ENDIF}
  65.     property OnDblClick;
  66.     property OnDragDrop;
  67.     property OnDragOver;
  68. {$IFDEF VER110}
  69.     property OnEndDock;
  70. {$ENDIF}
  71.     property OnEndDrag;
  72.     property OnMouseDown;
  73.     property OnMouseMove;
  74.     property OnMouseUp;
  75. {$IFDEF VER110}
  76.     property OnStartDock;
  77. {$ENDIF}
  78.     property OnStartDrag;
  79.   end;
  80. implementation
  81. procedure ExtGenerateMask(Bitmap: TBitmap; TransparentColor: TColor;
  82.   RgnData: TVrRgnData);
  83. var
  84.   X, Y: integer;
  85.   Rgn1: HRgn;
  86.   Rgn2: HRgn;
  87.   StartX, EndX: Integer;
  88.   OldCursor: TCursor;
  89. begin
  90.   Rgn1 := 0;
  91.   OldCursor := Screen.Cursor;
  92.   Screen.Cursor := crHourGlass;
  93.   try
  94.     for Y := 0 to Bitmap.Height - 1 do
  95.     begin
  96.       X := 0;
  97.       repeat
  98.         while (Bitmap.Canvas.Pixels[X, Y] = TransparentColor) and
  99.           (X < Bitmap.Width - 1) do Inc(X);
  100.         StartX := X;
  101.         Inc(X);
  102.         while (Bitmap.Canvas.Pixels[X, Y] <> TransparentColor) and
  103.          (X < Bitmap.Width - 1) do Inc(X);
  104.         EndX := X;
  105.         if StartX < Bitmap.Width - 1 then
  106.         begin
  107.           if Rgn1 = 0 then
  108.             Rgn1 := CreateRectRgn(StartX + 1, Y, EndX, Y + 1)
  109.           else
  110.           begin
  111.             Rgn2 := CreateRectRgn(StartX + 1, Y, EndX, Y + 1);
  112.             if Rgn2 <> 0 then CombineRgn(Rgn1, Rgn1, Rgn2, RGN_OR);
  113.             DeleteObject(Rgn2);
  114.           end;
  115.         end;
  116.       until X >= Bitmap.Width - 1;
  117.     end;
  118.     if (Rgn1 <> 0) then
  119.     begin
  120.       RgnData.Size := GetRegionData(Rgn1, 0, nil);
  121.       GetRegionData(Rgn1, RgnData.Size, RgnData.Buffer);
  122.       DeleteObject(Rgn1);
  123.     end;
  124.   finally
  125.     Screen.Cursor := OldCursor;
  126.   end;
  127. end;
  128. { TVrRgnData }
  129. destructor TVrRgnData.Destroy;
  130. begin
  131.   SetSize(0);
  132.   inherited Destroy;
  133. end;
  134. procedure TVrRgnData.SetSize(Value: Integer);
  135. begin
  136.   if FSize <> Value then
  137.   begin
  138.     FSize := Value;
  139.     ReallocMem(FBuffer, Value);
  140.   end;
  141. end;
  142. { TVrFormShape }
  143. constructor TVrFormShape.Create(AOwner: TComponent);
  144. begin
  145.   inherited Create(AOwner);
  146.   ControlStyle := ControlStyle + [csOpaque];
  147.   Align := alClient;
  148.   Color := clOlive;
  149.   ParentColor := false;
  150.   Transparent := True;
  151.   FMask := TBitmap.Create;
  152.   FRgnData := TVrRgnData.Create;
  153. end;
  154. destructor TVrFormShape.Destroy;
  155. begin
  156.   FMask.Free;
  157.   FRgnData.Free;
  158.   if FRgn <> 0 then DeleteObject(FRgn);
  159.   inherited Destroy;
  160. end;
  161. procedure TVrFormShape.SetParent(Value: TWinControl);
  162. begin
  163.   if Value <> nil then
  164.   begin
  165.     if not (Value is TForm) then
  166.       raise Exception.Create('VrFormShape requires a FORM as parent!');
  167.     with TForm(Value) do Borderstyle := bsNone;
  168.   end;
  169.   inherited;
  170. end;
  171. procedure TVrFormShape.Loaded;
  172. begin
  173.   inherited Loaded;
  174.   if not (csDesigning in ComponentState) then
  175.     UpdateRegion;
  176. end;
  177. procedure TVrFormShape.UpdateMask;
  178. begin
  179.   ExtGenerateMask(FMask, Self.Color, FRgnData);
  180.   if not Designing then UpdateRegion;
  181. end;
  182. procedure TVrFormShape.UpdateRegion;
  183. begin
  184.   if FRgn <> 0 then
  185.   begin
  186.     DeleteObject(FRgn);
  187.     FRgn := 0;
  188.   end;
  189.   if FRgnData.Size > 0 then
  190.   begin
  191.     FRgn := ExtCreateRegion (nil, FRgnData.Size, FRgnData.Buffer^);
  192.     SetWindowRgn(Parent.Handle, FRgn, True);
  193.   end;
  194. end;
  195. procedure TVrFormShape.SetMask(Value: TBitmap);
  196. begin
  197.   FMask.Assign(Value);
  198.   if not Loading then UpdateMask;
  199.   UpdateControlCanvas;
  200. end;
  201. function TVrFormShape.GetMaskColor: TColor;
  202. begin
  203.   Result := Self.Color;
  204. end;
  205. procedure TVrFormShape.SetMaskColor(Value: TColor);
  206. begin
  207.   if Self.Color <> Value then
  208.   begin
  209.     Self.Color := Value;
  210.     if not Loading then
  211.     begin
  212.       UpdateMask;
  213.       UpdateControlCanvas;
  214.     end;
  215.   end;
  216. end;
  217. procedure TVrFormShape.Paint;
  218. begin
  219.   if (FMask.Empty) or (Designing) then
  220.     ClearBitmapCanvas;
  221.   if not FMask.Empty then
  222.     BitmapCanvas.Draw(0, 0, FMask);
  223.   if Designing then
  224.     with BitmapCanvas do
  225.     begin
  226.       Pen.Style := psDot;
  227.       Brush.Style := bsClear;
  228.       Rectangle(0, 0, Width, Height);
  229.     end;
  230.   inherited Paint;
  231. end;
  232. procedure TVrFormShape.MouseDown(Button: TMouseButton; Shift: TShiftState;
  233.   X, Y: Integer);
  234. begin
  235.   if Button = mbleft then
  236.   begin
  237.     ReleaseCapture;
  238.     TWinControl(Parent).Perform(WM_SYSCOMMAND, $F012, 0);
  239.   end;
  240. end;
  241. procedure TVrFormShape.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  242. begin
  243.   Message.Result := 1;
  244. end;
  245. procedure TVrFormShape.ReadMask(Reader: TStream);
  246. var
  247.   Size: Integer;
  248. begin
  249.   Reader.Read(Size, Sizeof(Integer));
  250.   if Size <> 0 then
  251.   begin
  252.     FRgnData.Size := Size;
  253.     Reader.Read(FRgnData.Buffer^, Size);
  254.   end;
  255. end;
  256. procedure TVrFormShape.WriteMask(Writer: TStream);
  257. begin
  258.   Writer.Write(FRgnData.Size, Sizeof(Integer));
  259.   if FRgnData.Size <> 0 then
  260.     Writer.Write(FRgnData.Buffer^, FRgnData.Size);
  261. end;
  262. procedure TVrFormShape.DefineProperties(Filer: TFiler);
  263. begin
  264.   inherited DefineProperties(Filer);
  265.   Filer.DefineBinaryProperty('RgnData', ReadMask, WriteMask, True);
  266. end;
  267. end.