Marco's Web Center

Menu for Development

Site Menu
Object Pascal Handbook
Delphi Handbooks Collection
Mastering Borland Delphi 2005
(Old) White Papers
(Old)Tools
(Old) Conferences

My Other Sites
Italian Site (www.marcocantu.it)
the delphi search

Spirit of delphi

Advertising
Home My Blog Books Object Pascal Marco

Home: Code Repository: Mastering Delphi 5

Project THINCLI2

Project Structure


THINCLI2.DPR

program ThinCli2;

uses
  Forms,
  ThinForm in 'ThinForm.pas' {Form1},
  Reconc in 'Reconc.pas' {ReconcileErrorForm},
  DeltForm in 'DeltForm.pas' {FormDelta};

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TFormDelta, FormDelta);
  Application.Run;
end.

THINFORM.PAS

unit ThinForm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, DBClient, Grids, DBGrids, StdCtrls, ExtCtrls, ComCtrls, MConnect,
  MidasCon;

type
  TForm1 = class(TForm)
    ClientDataSet1: TClientDataSet;
    DataSource1: TDataSource;
    Panel1: TPanel;
    ButtonUpdate: TButton;
    ClientDataSet1Name: TStringField;
    ClientDataSet1Capital: TStringField;
    ClientDataSet1Continent: TStringField;
    ClientDataSet1Area: TFloatField;
    ClientDataSet1Population: TFloatField;
    ButtonSnap: TButton;
    ButtonReload: TButton;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    ClientDataSet2: TClientDataSet;
    ButtonDelta: TButton;
    ClientDataSet1Status: TStringField;
    ButtonUndo: TButton;
    DBGrid1: TDBGrid;
    DCOMConnection1: TDCOMConnection;
    procedure ButtonUpdateClick(Sender: TObject);
    procedure ButtonSnapClick(Sender: TObject);
    procedure ButtonReloadClick(Sender: TObject);
    procedure ButtonDeltaClick(Sender: TObject);
    procedure ClientDataSet1CalcFields(DataSet: TDataSet);
    procedure ButtonUndoClick(Sender: TObject);
    procedure ClientDataSet1ReconcileError(DataSet: TClientDataSet;
      E: EReconcileError; UpdateKind: TUpdateKind;
      var Action: TReconcileAction);
    procedure ClientDataSet1AfterPost(DataSet: TDataSet);
    procedure Form1Create(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses
  TypInfo, Reconc, DeltForm;

procedure TForm1.ButtonUpdateClick(Sender: TObject);
begin
  ClientDataSet1.ApplyUpdates (-1);
  FormDelta.Hide;
end;

procedure TForm1.ButtonSnapClick(Sender: TObject);
begin
  if SaveDialog1.Execute then
    ClientDataSet1.SaveToFile (SaveDialog1.FileName);
end;

procedure TForm1.ButtonReloadClick(Sender: TObject);
begin
  if OpenDialog1.Execute then
    ClientDataSet1.LoadFromFile (OpenDialog1.FileName);
end;

procedure TForm1.ButtonDeltaClick(Sender: TObject);
begin
  if ClientDataSet1.ChangeCount > 0 then
  begin
    ClientDataSet2.Data :=
      ClientDataSet1.Delta;
    ClientDataSet2.Open;
    FormDelta.DataSource1.DataSet :=
       ClientDataSet2;
    FormDelta.Show;
  end
  else
    FormDelta.Hide;
end;

procedure TForm1.ClientDataSet1CalcFields(DataSet: TDataSet);
begin
  ClientDataSet1Status.AsString :=
    GetEnumName (TypeInfo(TUpdateStatus),
      Integer (ClientDataSet1.UpdateStatus));
end;

procedure TForm1.ButtonUndoClick(Sender: TObject);
begin
  ClientDataSet1.UndoLastChange (True);
end;

procedure TForm1.ClientDataSet1ReconcileError(DataSet: TClientDataSet;
  E: EReconcileError; UpdateKind: TUpdateKind;
  var Action: TReconcileAction);
begin
  Action := HandleReconcileError(DataSet, UpdateKind, E);
end;

procedure TForm1.ClientDataSet1AfterPost(DataSet: TDataSet);
begin
  if FormDelta.Visible and
    (ClientDataSet1.ChangeCount > 0) then
  begin
    ClientDataSet2.Data := ClientDataSet1.Delta;
  end;
end;

procedure TForm1.Form1Create(Sender: TObject);
begin
  ClientDataSet1.Open;
end;

end.

RECONC.PAS


{*******************************************************}
{                                                       }
{       Delphi Visual Component Library                 }
{       ClientDataSet Standard Reconcile Error Dialog   }
{                                                       }
{       Copyright (c) 1997 Borland International        }
{                                                       }
{*******************************************************}

{ Note: To use this dialog you should add a call to HandleReconcileError in
  the OnReconcileError event handler of TClientDataSet (see the Client dataset
  demos for an example).  Also, after adding this unit to your project you must
  go into the Project Options dialog and remove this form from the list of
  Auto-created forms or an error will occur when compiling. }

unit Reconc;

interface

uses
  SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Grids, DB, DBTables, DBClient, ExtCtrls;

const
  ActionStr: array[TReconcileAction] of string = ('Skip', 'Abort', 'Merge',
    'Correct', 'Cancel', 'Refresh');
  UpdateKindStr: array[TUpdateKind] of string = ('Modified', 'Inserted',
    'Deleted');
  SCaption = 'Update Error - %s';
  SUnchanged = '<Unchanged>';
  SBinary = '(Binary)';
  SFieldName = 'Field Name';
  SOriginal = 'Original Value';
  SConflict = 'Conflicting Value';
  SValue = ' Value';
  SNoData = '<No Records>';
  SNew = 'New';

type
  TReconcileErrorForm = class(TForm)
    UpdateType: TLabel;
    UpdateData: TStringGrid;
    ActionGroup: TRadioGroup;
    CancelBtn: TButton;
    OKBtn: TButton;
    ConflictsOnly: TCheckBox;
    IconImage: TImage;
    ErrorMsg: TMemo;
    ChangedOnly: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure UpdateDataSetEditText(Sender: TObject; ACol, ARow: Integer;
      const Value: string);
    procedure DisplayFieldValues(Sender: TObject);
    procedure UpdateDataSelectCell(Sender: TObject; Col, Row: Integer;
      var CanSelect: Boolean);
  private
    FDataSet: TDataSet;
    FError: EReconcileError;
    FUpdateKind: TUpdateKind;
    FDataFields: TList;
    FCurColIdx: Integer;
    FNewColIdx: Integer;
    FOldColIdx: Integer;
    procedure AdjustColumnWidths;
    procedure InitDataFields;
    procedure InitUpdateData(HasCurValues: Boolean);
    procedure InitReconcileActions;
    procedure SetFieldValues(DataSet: TDataSet);
  public
    constructor CreateForm(DataSet: TDataSet; UpdateKind: TUpdateKind;
      Error: EReconcileError);
  end;

function HandleReconcileError(DataSet: TDataSet;  UpdateKind: TUpdateKind;
  ReconcileError: EReconcileError): TReconcileAction;

implementation

{$R *.DFM}

type
  PFieldData = ^TFieldData;
  TFieldData = record
    Field: TField;
    NewValue: string;
    OldValue: string;
    CurValue: string;
    EditValue: string;
    Edited: Boolean;
  end;

{ Public and Private Methods }

function HandleReconcileError(DataSet: TDataSet; UpdateKind: TUpdateKind;
  ReconcileError: EReconcileError): TReconcileAction;
var
  UpdateForm: TReconcileErrorForm;
begin
  UpdateForm := TReconcileErrorForm.CreateForm(DataSet, UpdateKind, ReconcileError);
  with UpdateForm do
  try
    if ShowModal = mrOK then
    begin
      Result := TReconcileAction(ActionGroup.Items.Objects[ActionGroup.ItemIndex]);
      if Result = raCorrect then SetFieldValues(DataSet);
    end else
      Result := raAbort;
  finally
    Free;
  end;
end;

{ Routine to convert a variant value into a string.
  Handles binary fields types and "empty" (Unchanged) field values specially }

function VarToStr(V: Variant; DataType: TFieldType): string;
const
  BinaryDataTypes: set of TFieldType = [ftBytes, ftVarBytes, ftBlob,
    ftGraphic..ftCursor];
begin
  try
    if VarIsEmpty(V) then
      Result := SUnchanged
    else if DataType in BinaryDataTypes then
      Result := SBinary
    else
      Result := System.VarToStr(V);
  except
    on E: Exception do
      Result := E.Message;
  end;
end;

{ TReconcileErrorForm }

constructor TReconcileErrorForm.CreateForm(DataSet: TDataSet;
  UpdateKind: TUpdateKind; Error: EReconcileError);
begin
  FDataSet := DataSet;
  FUpdateKind := UpdateKind;
  FError := Error;
  inherited Create(Application);
end;

{ Create a list of the data fields in the dataset, and store string values
  associated with NewValue, OldValue, and CurValue in string variables
  to make display switching faster }

procedure TReconcileErrorForm.InitDataFields;
var
  I: Integer;
  FD: PFieldData;
  V: Variant;
  HasCurValues: Boolean;
begin
  HasCurValues := False;
  for I := 0 to FDataSet.FieldCount - 1 do
  with FDataset.Fields[I] do
  begin
    if (FieldKind <> fkData) then Continue;
    FD := New(PFieldData);
    try
      FD.Field := FDataset.Fields[I];
      FD.Edited := False;
      if FUpdateKind <> ukDelete then
        FD.NewValue := VarToStr(NewValue, DataType);
      V := CurValue;
      if not VarIsEmpty(V) then HasCurValues := True;
      FD.CurValue := VarToStr(CurValue, DataType);
      if FUpdateKind <> ukInsert then
        FD.OldValue := VarToStr(OldValue, DataType);
      FDataFields.Add(FD);
    except
      Dispose(FD);
      raise;
    end;
  end;
  InitUpdateData(HasCurValues);
end;

{ Initialize the column indexes and grid titles }

procedure TReconcileErrorForm.InitUpdateData(HasCurValues: Boolean);
var
  FColCount: Integer;
begin
  FColCount := 1;
  UpdateData.ColCount := 4;
  UpdateData.Cells[0,0] := SFieldName;
  if FUpdateKind <> ukDelete then
  begin
    FNewColIdx := FColCount;
    Inc(FColCount);
    UpdateData.Cells[FNewColIdx,0] := UpdateKindStr[FUpdateKind] + SValue;
  end else
  begin
    FOldColIdx := FColCount;
    Inc(FColCount);
    UpdateData.Cells[FOldColIdx,0] := SOriginal;
  end;
  if HasCurValues then
  begin
    FCurColIdx := FColCount;
    Inc(FColCount);
    UpdateData.Cells[FCurColIdx,0] := SConflict;
  end;
  if FUpdateKind = ukModify then
  begin
    FOldColIdx := FColCount;
    Inc(FColCount);
    UpdateData.Cells[FOldColIdx,0] := SOriginal;
  end;
  UpdateData.ColCount := FColCount;
end;

{ Update the reconcile action radio group based on the valid reconcile actions }

procedure TReconcileErrorForm.InitReconcileActions;

  procedure AddAction(Action: TReconcileAction);
  begin
    ActionGroup.Items.AddObject(ActionStr[Action], TObject(Action));
  end;

begin
  AddAction(raSkip);
  AddAction(raCancel);
  AddAction(raCorrect);
  if FCurColIdx > 0 then
  begin
    AddAction(raRefresh);
    AddAction(raMerge);
  end;
  ActionGroup.ItemIndex := 0;
end;

{ Update the grid based on the current display options }

procedure TReconcileErrorForm.DisplayFieldValues(Sender: TObject);
var
  I: Integer;
  CurRow: Integer;
  Action: TReconcileAction;
begin
  if not Visible then Exit;
  Action := TReconcileAction(ActionGroup.Items.Objects[ActionGroup.ItemIndex]);
  UpdateData.Col := 1;
  UpdateData.Row := 1;
  CurRow := 1;
  UpdateData.Cells[0, CurRow] := SNoData;
  for I := 1 to UpdateData.ColCount - 1 do
    UpdateData.Cells[I, CurRow] := '';
  for I := 0 to FDataFields.Count - 1 do
    with PFieldData(FDataFields[I])^ do
    begin
      if ConflictsOnly.Checked and (CurValue = SUnChanged) then Continue;
      if ChangedOnly.Checked and (NewValue = SUnChanged) then Continue;
      UpdateData.RowCount := CurRow + 1;
      UpdateData.Cells[0, CurRow] := Field.DisplayName;
      if FNewColIdx > 0 then
      begin
        case Action of
          raCancel, raRefresh:
            UpdateData.Cells[FNewColIdx, CurRow] := SUnChanged;
          raCorrect:
            if Edited then
              UpdateData.Cells[FNewColIdx, CurRow] := EditValue else
              UpdateData.Cells[FNewColIdx, CurRow] := NewValue;
          else
            UpdateData.Cells[FNewColIdx, CurRow] := NewValue;
        end;
        UpdateData.Objects[FNewColIdx, CurRow] := FDataFields[I];
      end;
      if FCurColIdx > 0 then
        UpdateData.Cells[FCurColIdx, CurRow] := CurValue;
      if FOldColIdx > 0 then
        if (Action in [raMerge, raRefresh]) and (CurValue <> SUnchanged) then
           UpdateData.Cells[FOldColIdx, CurRow] := CurValue else
           UpdateData.Cells[FOldColIdx, CurRow] := OldValue;
      Inc(CurRow);
    end;
  AdjustColumnWidths;
end;

{ For fields that the user has edited, copy the changes back into the
  NewValue property of the associated field }

procedure TReconcileErrorForm.SetFieldValues(DataSet: TDataSet);
var
  I: Integer;
begin
  for I := 0 to FDataFields.Count - 1 do
    with PFieldData(FDataFields[I])^ do
      if Edited then Field.NewValue := EditValue;
end;

procedure TReconcileErrorForm.AdjustColumnWidths;
var
  NewWidth, I: integer;
begin
  with UpdateData do
  begin
    NewWidth := (ClientWidth - ColWidths[0]) div (ColCount - 1);
    for I := 1 to ColCount - 1 do
      ColWidths[I] := NewWidth - 1;
  end;
end;

{ Event handlers }

procedure TReconcileErrorForm.FormCreate(Sender: TObject);
begin
  if FDataSet = nil then Exit;
  FDataFields := TList.Create;
  InitDataFields;
  Caption := Format(SCaption, [FDataSet.Name]);
  UpdateType.Caption := UpdateKindStr[FUpdateKind];
  ErrorMsg.Text := FError.Message;
  if FError.Context <> '' then
    ErrorMsg.Lines.Add(FError.Context);
  ConflictsOnly.Enabled := FCurColIdx > 0;
  ConflictsOnly.Checked := ConflictsOnly.Enabled;
  ChangedOnly.Enabled := FNewColIdx > 0;
  InitReconcileActions;
  UpdateData.DefaultRowHeight := UpdateData.Canvas.TextHeight('SWgjp') + 7; { Do not localize }
end;

procedure TReconcileErrorForm.FormDestroy(Sender: TObject);
var
  I: Integer;
begin
  if Assigned(FDataFields) then
  begin
    for I := 0 to FDataFields.Count - 1 do
      Dispose(PFieldData(FDataFields[I]));
    FDataFields.Destroy;
  end;
end;

{ Set the Edited flag in the DataField list and save the value }

procedure TReconcileErrorForm.UpdateDataSetEditText(Sender: TObject; ACol,
  ARow: Integer; const Value: string);
begin
  PFieldData(UpdateData.Objects[ACol, ARow]).EditValue := Value;
  PFieldData(UpdateData.Objects[ACol, ARow]).Edited := True;
end;

{ Enable the editing in the grid if we are on the NewValue column and the
  current reconcile action is raCorrect }

procedure TReconcileErrorForm.UpdateDataSelectCell(Sender: TObject; Col,
  Row: Integer; var CanSelect: Boolean);
begin
  if (Col = FNewColIdx) and
    (TReconcileAction(ActionGroup.Items.Objects[ActionGroup.ItemIndex]) = raCorrect) then
    UpdateData.Options := UpdateData.Options + [goEditing] else
    UpdateData.Options := UpdateData.Options - [goEditing];
end;

end.

DELTFORM.PAS

unit DeltForm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, Grids, DBGrids;

type
  TFormDelta = class(TForm)
    DBGrid1: TDBGrid;
    DataSource1: TDataSource;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FormDelta: TFormDelta;

implementation

{$R *.DFM}

end.

THINFORM.DFM

object Form1: TForm1
  Left = 207
  Top = 126
  Width = 514
  Height = 278
  Caption = 'Client 3 Tier'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = True
  OnCreate = Form1Create
  PixelsPerInch = 96
  TextHeight = 13
  object Panel1: TPanel
    Left = 0
    Top = 0
    Width = 506
    Height = 41
    Align = alTop
    TabOrder = 0
    object ButtonUpdate: TButton
      Left = 8
      Top = 8
      Width = 75
      Height = 25
      Caption = 'Update'
      TabOrder = 0
      OnClick = ButtonUpdateClick
    end
    object ButtonSnap: TButton
      Left = 88
      Top = 8
      Width = 75
      Height = 25
      Caption = 'SnapShot...'
      TabOrder = 1
      OnClick = ButtonSnapClick
    end
    object ButtonReload: TButton
      Left = 168
      Top = 8
      Width = 75
      Height = 25
      Caption = 'Reload...'
      TabOrder = 2
      OnClick = ButtonReloadClick
    end
    object ButtonDelta: TButton
      Left = 248
      Top = 8
      Width = 75
      Height = 25
      Caption = 'Show Delta'
      TabOrder = 3
      OnClick = ButtonDeltaClick
    end
    object ButtonUndo: TButton
      Left = 328
      Top = 8
      Width = 75
      Height = 25
      Caption = 'Undo'
      TabOrder = 4
      OnClick = ButtonUndoClick
    end
  end
  object DBGrid1: TDBGrid
    Left = 0
    Top = 41
    Width = 506
    Height = 210
    Align = alClient
    DataSource = DataSource1
    TabOrder = 1
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = 'MS Sans Serif'
    TitleFont.Style = []
  end
  object ClientDataSet1: TClientDataSet
    Aggregates = <>
    PacketRecords = 5
    Params = <>
    ProviderName = 'DataSetProvider1'
    RemoteServer = DCOMConnection1
    AfterPost = ClientDataSet1AfterPost
    OnCalcFields = ClientDataSet1CalcFields
    OnReconcileError = ClientDataSet1ReconcileError
    Left = 136
    Top = 72
    object ClientDataSet1Status: TStringField
      DisplayWidth = 15
      FieldKind = fkCalculated
      FieldName = 'Status'
      Size = 30
      Calculated = True
    end
    object ClientDataSet1Name: TStringField
      DisplayWidth = 23
      FieldName = 'Name'
      Size = 24
    end
    object ClientDataSet1Capital: TStringField
      DisplayWidth = 19
      FieldName = 'Capital'
      Size = 24
    end
    object ClientDataSet1Continent: TStringField
      DisplayWidth = 17
      FieldName = 'Continent'
      Size = 24
    end
    object ClientDataSet1Area: TFloatField
      DisplayWidth = 14
      FieldName = 'Area'
    end
    object ClientDataSet1Population: TFloatField
      DisplayWidth = 12
      FieldName = 'Population'
    end
  end
  object DataSource1: TDataSource
    DataSet = ClientDataSet1
    Left = 216
    Top = 72
  end
  object OpenDialog1: TOpenDialog
    DefaultExt = 'CDS'
    Filter = 'Client DataSet (*.cds)|*.cds|Any file (*.*)|*.*'
    Left = 137
    Top = 121
  end
  object SaveDialog1: TSaveDialog
    DefaultExt = 'CDS'
    Filter = 'Client DataSet (*.cds)|*.cds|Any file (*.*)|*.*'
    Left = 56
    Top = 120
  end
  object ClientDataSet2: TClientDataSet
    Aggregates = <>
    Params = <>
    Left = 302
    Top = 71
  end
  object DCOMConnection1: TDCOMConnection
    Connected = True
    ServerGUID = '{C5DDE903-2214-11D1-98D0-444553540000}'
    ServerName = 'AppServTwo.RdmCount'
    Left = 56
    Top = 72
  end
end

RECONC.DFM

object ReconcileErrorForm: TReconcileErrorForm
  Left = 314
  Top = 187
  BorderStyle = bsDialog
  Caption = 'Update Error'
  ClientHeight = 311
  ClientWidth = 527
  Color = clBtnFace
  ParentFont = True
  OldCreateOrder = True
  Position = poScreenCenter
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  OnShow = DisplayFieldValues
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 57
    Top = 13
    Width = 65
    Height = 13
    Caption = 'Update Type:'
  end
  object UpdateType: TLabel
    Left = 134
    Top = 13
    Width = 49
    Height = 13
    Caption = 'Modified'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clBlack
    Font.Height = -11
    Font.Name = 'Default'
    Font.Style = [fsBold]
    ParentFont = False
  end
  object Label3: TLabel
    Left = 57
    Top = 33
    Width = 71
    Height = 13
    Caption = 'Error Message:'
  end
  object IconImage: TImage
    Left = 12
    Top = 12
    Width = 34
    Height = 34
    Picture.Data = {
      055449636F6E0000010002002020100000000000E80200002600000020200200
      00000000300100000E0300002800000020000000400000000100040000000000
      0002000000000000000000000000000000000000000000000000800000800000
      00808000800000008000800080800000C0C0C000808080000000FF0000FF0000
      00FFFF00FF000000FF00FF00FFFF0000FFFFFF00000008888888888888888888
      8888880000008888888888888888888888888880003000000000000000000000
      0008888803BBBBBBBBBBBBBBBBBBBBBBBB7088883BBBBBBBBBBBBBBBBBBBBBBB
      BBB708883BBBBBBBBBBBBBBBBBBBBBBBBBBB08883BBBBBBBBBBBB7007BBBBBBB
      BBBB08803BBBBBBBBBBBB0000BBBBBBBBBB7088003BBBBBBBBBBB0000BBBBBBB
      BBB0880003BBBBBBBBBBB7007BBBBBBBBB708800003BBBBBBBBBBBBBBBBBBBBB
      BB088000003BBBBBBBBBBB0BBBBBBBBBB70880000003BBBBBBBBB707BBBBBBBB
      B08800000003BBBBBBBBB303BBBBBBBB7088000000003BBBBBBBB000BBBBBBBB
      0880000000003BBBBBBB70007BBBBBB708800000000003BBBBBB30003BBBBBB0
      88000000000003BBBBBB00000BBBBB70880000000000003BBBBB00000BBBBB08
      800000000000003BBBBB00000BBBB7088000000000000003BBBB00000BBBB088
      0000000000000003BBBB00000BBB708800000000000000003BBB70007BBB0880
      00000000000000003BBBBBBBBBB70880000000000000000003BBBBBBBBB08800
      000000000000000003BBBBBBBB7088000000000000000000003BBBBBBB088000
      0000000000000000003BBBBBB708800000000000000000000003BBBBB0880000
      00000000000000000003BBBB70800000000000000000000000003BB700000000
      0000000000000000000003330000000000000000F8000003F0000001C0000000
      80000000000000000000000000000001000000018000000380000003C0000007
      C0000007E000000FE000000FF000001FF000001FF800003FF800003FFC00007F
      FC00007FFE0000FFFE0000FFFF0001FFFF0001FFFF8003FFFF8003FFFFC007FF
      FFC007FFFFE00FFFFFE01FFFFFF07FFFFFF8FFFF280000002000000040000000
      0100010000000000800000000000000000000000000000000000000000000000
      FFFFFF000000000000000000000000003FFFFFC07FFFFFE07FFFFFF07FFCFFF0
      7FF87FE03FF87FE03FFCFFC01FFFFFC01FFDFF800FFDFF800FFDFF0007F8FF00
      07F8FE0003F8FE0003F07C0001F07C0001F0780000F0780000F070000078F000
      007FE000003FE000003FC000001FC000001F8000000F8000000F000000060000
      00000000FFFFFFFFFFFFFFFFC000001F8000000F000000070000000700000007
      000000078000000F8000000FC000001FC000001FE000003FE000003FF000007F
      F000007FF80000FFF80000FFFC0001FFFC0001FFFE0003FFFE0003FFFF0007FF
      FF0007FFFF800FFFFF800FFFFFC01FFFFFC01FFFFFE03FFFFFE03FFFFFF07FFF
      FFF8FFFF}
  end
  object UpdateData: TStringGrid
    Left = 9
    Top = 140
    Width = 504
    Height = 131
    ColCount = 4
    DefaultColWidth = 119
    RowCount = 2
    Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goThumbTracking]
    TabOrder = 1
    OnSelectCell = UpdateDataSelectCell
    OnSetEditText = UpdateDataSetEditText
  end
  object ActionGroup: TRadioGroup
    Left = 410
    Top = 10
    Width = 102
    Height = 113
    Caption = ' Reconcile Action '
    TabOrder = 0
    OnClick = DisplayFieldValues
  end
  object CancelBtn: TButton
    Left = 438
    Top = 281
    Width = 75
    Height = 25
    Cancel = True
    Caption = 'Cancel'
    ModalResult = 2
    TabOrder = 5
  end
  object OKBtn: TButton
    Left = 350
    Top = 281
    Width = 75
    Height = 25
    Caption = 'OK'
    Default = True
    ModalResult = 1
    TabOrder = 4
  end
  object ConflictsOnly: TCheckBox
    Left = 11
    Top = 282
    Width = 153
    Height = 17
    Caption = 'Show conflicting fields only'
    TabOrder = 2
    OnClick = DisplayFieldValues
  end
  object ErrorMsg: TMemo
    Left = 56
    Top = 52
    Width = 342
    Height = 71
    TabStop = False
    Color = clBtnFace
    ReadOnly = True
    TabOrder = 6
  end
  object ChangedOnly: TCheckBox
    Left = 185
    Top = 282
    Width = 141
    Height = 17
    Caption = 'Show changed fields only'
    TabOrder = 3
    OnClick = DisplayFieldValues
  end
end

DELTFORM.DFM

object FormDelta: TFormDelta
  Left = 207
  Top = 407
  Width = 513
  Height = 237
  Caption = 'ClientDataSet Delta'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = True
  PixelsPerInch = 96
  TextHeight = 13
  object DBGrid1: TDBGrid
    Left = 0
    Top = 0
    Width = 505
    Height = 210
    Align = alClient
    DataSource = DataSource1
    TabOrder = 0
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = 'MS Sans Serif'
    TitleFont.Style = []
  end
  object DataSource1: TDataSource
    Left = 40
    Top = 24
  end
end