home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 December / Chip_2001-12_cd1.bin / zkuste / delphi / kolekce / d3456 / ALEXSOFT.ZIP / DBINSERT.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-09-29  |  7.5 KB  |  245 lines

  1. (*////////////////////////////////////////////////////////////////////////////
  2. //   Part of AlexSoft VCL/DLL Library.                                      //
  3. //   All rights reserved. (c) Copyright 1998.                               //
  4. //   Created by: Alex Rabichooc                                             //
  5. //**************************************************************************//
  6. //  Users of this unit must accept this disclaimer of warranty:             //
  7. //    "This unit is supplied as is. The author disclaims all warranties,    //
  8. //    expressed or implied, including, without limitation, the warranties   //
  9. //    of merchantability and of fitness for any purpose.                    //
  10. //    The author assumes no liability for damages, direct or                //
  11. //    consequential, which may result from the use of this unit."           //
  12. //                                                                          //
  13. //  This Unit is donated to the public as public domain.                    //
  14. //                                                                          //
  15. //  This Unit can be freely used and distributed in commercial and          //
  16. //  private environments provided this notice is not modified in any way.   //
  17. //                                                                          //
  18. //  If you do find this Unit handy and you feel guilty for using such a     //
  19. //  great product without paying someone - sorry :-)                        //
  20. //                                                                          //
  21. //  Please forward any comments or suggestions to Alex Rabichooc at:        //
  22. //                                                                          //
  23. //  a_rabichooc@yahoo.com or alex@carmez.mldnet.com                         //
  24. /////////////////////////////////////////////////////////////////////////////*)
  25.  
  26. {---------------------------------------------------------------------------
  27.   TRaDBInsert - Allows you to copy data from a current record to a new one.
  28. ----------------------------------------------------------------------------}
  29.  
  30. unit DBInsert;
  31.  
  32. interface
  33.  
  34. uses
  35.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  36.   StdCtrls, db;
  37.  
  38. type
  39.   TRaDBInsert = class;
  40.  
  41.   TRaDBInsertDataLink = class(TDataLink)
  42.   private
  43.     FDBInsert: TRaDBInsert;
  44.     FRecBuffer: Pointer;
  45.     function GetBufSize: Integer;
  46.     function DataSize(AField: TField): integer;
  47.     procedure GetData(AField: TField; Buffer: Pointer);
  48.     procedure SetData(AField: TField; Buffer: Pointer);
  49.   protected
  50.     procedure ActiveChanged; override;
  51.     procedure DataSetChanged; override;
  52.     procedure EditingChanged; override;
  53.   public
  54.     constructor Create(ADBInsert: TRaDBInsert);
  55.     destructor Destroy; override;
  56.   end;
  57.  
  58.   TRaDBInsert = class(TCheckBox)
  59.   private
  60.     FDataLink: TRaDBInsertDataLink;
  61.     FDataSource: TDataSource;
  62.     procedure CMChanged(var Message: TMessage); message CM_CHANGED;
  63.     function GetDataSource: TDataSource;
  64.     procedure SetDataSource(Value: TDataSource);
  65.   protected
  66.     procedure Notification(AComponent: TComponent;
  67.                                            Operation: TOperation); override;
  68.   public
  69.     constructor Create(AOwner: TComponent); override;
  70.     destructor Destroy; override;
  71.   published
  72.     property DataSource: TDataSource read GetDataSource write SetDataSource;
  73.   end;
  74.  
  75. implementation
  76. uses dbXCnsts;
  77.  
  78. {TRaDBInsertDataLink}
  79. constructor TRaDBInsertDataLink.Create(ADBInsert: TRaDBInsert);
  80. begin
  81.   inherited Create;
  82.   FDBInsert := ADBInsert;
  83. end;
  84.  
  85. destructor TRaDBInsertDataLink.Destroy;
  86. begin
  87.   if FRecBuffer <> nil then
  88.   begin
  89.      FreeMem(FRecBuffer);
  90.      FRecBuffer := nil;
  91.   end;
  92.   FDBInsert := nil;
  93.   inherited Destroy;
  94. end;
  95.  
  96. function TRaDBInsertDataLink.GetBufSize: Integer;
  97. var i: Integer;
  98. begin
  99.    Result := 0;
  100.    for i := 0 to DataSet.FieldCount-1 do
  101.       if not DataSet.Fields[i].IsBlob and not DataSet.Fields[i].ReadOnly then
  102.         Inc(Result, DataSize(DataSet.Fields[i]));
  103. end;
  104.  
  105. procedure TRaDBInsertDataLink.ActiveChanged;
  106. begin
  107.   if FRecBuffer <> nil then
  108.   begin
  109.      FreeMem(FRecBuffer);
  110.      FRecBuffer := nil;
  111.   end;
  112.   if (FDBInsert <> nil) and Active then
  113.     GetMem(FRecBuffer, GetBufSize);
  114. end;
  115.  
  116. procedure TRaDBInsertDataLink.EditingChanged;
  117. var i, FieldOffset: Integer;
  118. begin
  119.   if (FDBInsert <> nil) and
  120.      (FDBInsert.Checked) and
  121.      (DataSource <> nil) and
  122.      (DataSet <> nil) and
  123.      not (csDesigning in FDBInsert.ComponentState) and
  124.      (DataSource.State = dsInsert) and
  125.      (FRecBuffer <> nil) then
  126.   begin
  127.      FieldOffset := 0;
  128.      for i := 0 to DataSet.FieldCount-1 do
  129.      with DataSet.Fields[i] do
  130.      begin
  131.         if not IsBlob and not ReadOnly then
  132.         begin
  133.            Self.SetData(DataSet.Fields[i], Pointer(LongInt(FRecBuffer)+FieldOffset));
  134.            Inc(FieldOffset, Self.DataSize(DataSet.Fields[i]));
  135.         end;
  136.      end;
  137.   end;
  138. end;
  139.  
  140. procedure TRaDBInsertDataLink.DataSetChanged;
  141. var i, FieldOffset: Integer;
  142. begin
  143.   if (FDBInsert <> nil) and
  144.      (DataSource <> nil) and
  145.      (DataSet <> nil) and
  146.      not (csDesigning in FDBInsert.ComponentState) and
  147.      not (DataSource.State in [dsEdit, dsInsert]) and Active then
  148.   begin
  149.      FieldOffset := 0;
  150.      for i := 0 to DataSet.FieldCount-1 do
  151.      with DataSet.Fields[i] do
  152.      begin
  153.         if not IsBlob and not ReadOnly then
  154.         begin
  155.            Self.GetData(DataSet.Fields[i], Pointer(LongInt(FRecBuffer)+FieldOffset));
  156.            Inc(FieldOffset, Self.DataSize(DataSet.Fields[i]));
  157.         end;
  158.      end;
  159.   end;
  160. end;
  161.  
  162. function TRaDBInsertDataLink.DataSize(AField: TField): integer;
  163. begin
  164.   if AField = nil then
  165.     Result := 0
  166.    else
  167.   {$IFNDEF VER120}
  168.   {$IFNDEF VER110}
  169.   if AField is TWideStringField then
  170.     Result := 1+AField.Size
  171.    else
  172.   {$ENDIF}
  173.   {$ENDIF}
  174.     Result := AField.DataSize;
  175. end;
  176.  
  177. procedure TRaDBInsertDataLink.GetData(AField: TField; Buffer: Pointer);
  178. begin
  179.   if AField <> nil then
  180.   {$IFNDEF VER120}
  181.   {$IFNDEF VER110}
  182.     if AField is TWideStringField then
  183.       StrCopy(Buffer, PChar(AField.AsString))
  184.      else
  185.   {$ENDIF}
  186.   {$ENDIF}
  187.        AField.GetData(Buffer);
  188. end;
  189.  
  190. procedure TRaDBInsertDataLink.SetData(AField: TField; Buffer: Pointer);
  191. begin
  192.   if AField <> nil then
  193.   {$IFNDEF VER120}
  194.   {$IFNDEF VER110}
  195.     if AField is TWideStringField then
  196.       AField.AsString := PChar(Buffer)
  197.      else
  198.   {$ENDIF}
  199.   {$ENDIF}
  200.        AField.SetData(Buffer);
  201. end;
  202.  
  203. {TRaDBInsert}
  204. constructor TRaDBInsert.Create(AOwner: TComponent);
  205. begin
  206.    Inherited Create(AOwner);
  207.    FDataLink := TRaDBInsertDataLink.Create(Self);
  208.    Caption := SDuplicateRecord;
  209. end;
  210.  
  211. destructor TRaDBInsert.Destroy;
  212. begin
  213.   if FDataLink <> nil then
  214.      FDataLink.Destroy;
  215.   inherited Destroy;
  216. end;
  217.  
  218. procedure TRaDBInsert.CMChanged(var Message: TMessage);
  219. begin
  220.    Inherited;
  221.    if FDataLink <> nil then
  222.       FDataLink.DataSetChanged;
  223. end;
  224.  
  225. procedure TRaDBInsert.Notification(AComponent: TComponent; Operation: TOperation);
  226. begin
  227.   inherited Notification(AComponent, Operation);
  228.   if (Operation = opRemove) and (FDataLink <> nil) and
  229.     (AComponent = DataSource) then DataSource := nil;
  230. end;
  231.  
  232. procedure TRaDBInsert.SetDataSource(Value: TDataSource);
  233. begin
  234.   FDataLink.DataSource := Value;
  235.   FDataSource := Value;
  236.   if Value <> nil then Value.FreeNotification(Self);
  237. end;
  238.  
  239. function TRaDBInsert.GetDataSource: TDataSource;
  240. begin
  241.   Result := FDataLink.DataSource;
  242. end;
  243.  
  244. end.
  245.