скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Отобразить определенного формата файлы базы данных



unit DdhDynDb;

interface

uses
  Controls, Db, Forms, Classes, DbTables;

function ConvertClass(FieldClass: TFieldClass): TControlClass;

procedure NormalizeString(var S: string);

procedure ConnectDataFields(DbComp: TControl;
  DataSource: TDataSource; FieldName: string);

function GenerateForm(StrList: TStringList;
  SourceTable: TTable): TForm;

function GenerateSource(AForm: TForm;
  FormName, UnitName: string): string;

implementation

uses
  TypInfo, DbCtrls, SysUtils, StdCtrls, ExtCtrls, Windows;

const
  FieldTypeCount = 15;

type
  CVTable = array[1..FieldTypeCount, 1..2] of TClass;

  // TBytesField and TVarBytesField are missing
const
  ConvertTable: CVTable = (
    (TAutoIncField, TDBEdit),
    (TStringField, TDBEdit),
    (TIntegerField, TDBEdit),
    (TSmallintField, TDBEdit),
    (TWordField, TDBEdit),
    (TFloatField, TDBEdit),
    (TCurrencyField, TDBEdit),
    (TBCDField, TDBEdit),
    (TBooleanField, TDBCheckBox),
    (TDateTimeField, TDBEdit),
    (TDateField, TDBEdit),
    (TTimeField, TDBEdit),
    (TMemoField, TDBMemo),
    (TBlobField, TDBImage), {just a guess}
    (TGraphicField, TDBImage));

function ConvertClass(FieldClass: TFieldClass):
  TControlClass;
var
  I: Integer;
begin
  Result := nil;
  for I := 1 to FieldTypeCount do
    if ConvertTable[I, 1] = FieldClass then
    begin
      Result := TControlClass(
        ConvertTable[I, 2]);
      break; // jump out of for loop
    end;
  if Result = nil then
    raise Exception.Create('ConvertClass failed');
end;

procedure NormalizeString(var S: string);
var
  N: Integer;
begin
  // remove the T
  Delete(S, 1, 1);
  {chek if the string is a valid Pascal identifier:
  if not, replace spaces and other characters with underscores}
  if not IsValidIdent(S) then
    for N := 1 to Length(S) do
      if not ((S[N] in ['A'..'Z']) or (S[N] in ['a'..'z'])
        or ((S[N] in ['0'..'9']) and (N <> 1))) then
        S[N] := '_';
end;

procedure ConnectDataFields(DbComp: TControl;
  DataSource: TDataSource; FieldName: string);
var
  PropInfo: PPropInfo;
begin
  if not Assigned(DbComp) then
    raise Exception.Create(
      'ConnectDataFields failed: Invalid control');

  // set the DataSource property
  PropInfo := GetPropInfo(
    DbComp.ClassInfo, 'DataSource');
  if PropInfo = nil then
    raise Exception.Create(
      'ConnectDataFields failed: Missing DataSource property');
  SetOrdProp(DbComp, PropInfo,
    Integer(Pointer(DataSource)));

  // set the DataField property
  PropInfo := GetPropInfo(
    DbComp.ClassInfo, 'DataField');
  if PropInfo = nil then
    raise Exception.Create(
      'ConnectDataFields failed: Missing DataField property');
  SetStrProp(DbComp, PropInfo, FieldName);
end;

function GenerateForm(StrList: TStringList;
  SourceTable: TTable): TForm;
var
  I, NumField, YComp, HForm, Hmax: Integer;
  NewName: string;
  NewLabel: TLabel;
  NewDBComp: TControl;
  CtrlClass: TControlClass;
  ATable: TTable;
  ADataSource: TDataSource;
  APanel: TPanel;
  ANavigator: TDBNavigator;
  AScrollbox: TScrollBox;
begin
  // generate the form and connect the table
  Result := TForm.Create(Application);
  Result.Position := poScreenCenter;
  Result.Width := Screen.Width div 2;
  Result.Caption := 'Table Form';

  // create a Table component in the result form
  ATable := TTable.Create(Result);
  ATable.DatabaseName := SourceTable.DatabaseName;
  ATable.TableName := SourceTable.TableName;
  ATable.Active := True;
  ATable.Name := 'Table1';
  // component position (at design time)
  ATable.DesignInfo := MakeLong(20, 20);

  // create a DataSource
  ADataSource := TDataSource.Create(Result);
  ADataSource.DataSet := ATable;
  ADataSource.Name := 'DataSource1';
  // component position (at design time)
  ADataSource.DesignInfo := MakeLong(60, 20);

  // create a toolbar panel
  APanel := TPanel.Create(Result);
  APanel.Parent := Result;
  APanel.Align := alTop;
  APanel.Name := 'Panel1';
  APanel.Caption := '';

  // place a DBNavigator inside it
  ANavigator := TDBNavigator.Create(Result);
  ANavigator.Parent := APanel;
  ANavigator.Left := 8;
  ANavigator.Top := 8;
  ANAvigator.Height := APanel.Height - 16;
  ANavigator.DataSource := ADataSource;
  ANavigator.Name := 'DbNavigator1';

  // create a scroll box
  AScrollbox := TScrollBox.Create(Result);
  AScrollbox.Parent := Result;
  AScrollbox.Width := Result.ClientWidth;
  AScrollbox.Align := alClient;
  AScrollbox.BorderStyle := bsNone;
  AScrollbox.Name := 'ScrollBox1';

  // generates field editors
  YComp := 10;
  for I := 0 to StrList.Count - 1 do
  begin
    NumField := Integer(StrList.Objects[I]);

    // create a label with the field name
    NewLabel := TLabel.Create(Result);
    NewLabel.Parent := AScrollBox;
    NewLabel.Name := 'Label' + IntToStr(I);
    NewLabel.Caption := StrList[I];
    NewLabel.Top := YComp;
    NewLabel.Left := 10;
    NewLabel.Width := 120;

    // create the data aware control
    CtrlClass := ConvertClass(
      ATable.FieldDefs[NumField].FieldClass);
    NewDBComp := CtrlClass.Create(Result);
    NewDBComp.Parent := AScrollBox;
    NewName := CtrlClass.ClassName +
      ATable.FieldDefs[NumField].Name;
    NormalizeString(NewName);
    NewDBComp.Name := NewName;
    NewDBComp.Top := YComp;
    NewDBComp.Left := 140;
    NewDbComp.Width :=
      AScrollBox.Width - 150; // width of label plus border

    // connect the control with the data source
    // and field using RTTI support
    ConnectDataFields(NewDbComp,
      ADataSource,
      ATable.FieldDefs[NumField].Name);

    // compute the position of the next component
    Inc(YComp, NewDBComp.Height + 10);
  end; // for each field

  // computed requested height for client area
  HForm := YComp + APanel.Height;
  // max client area hight = screen height - 40 - form border
  HMax := (Screen.Height - 40 -
    (Result.Height - Result.ClientHeight));
  // limit form height to HMax and reserve space for scrollbar
  if HForm > HMax then
  begin
    HForm := HMax;
    Result.Width := Result.Width +
      GetSystemMetrics(SM_CXVSCROLL);
  end;
  Result.ClientHeight := HForm;
end;

function GenerateSource(AForm: TForm;
  FormName, UnitName: string): string;
var
  I: Integer;
begin
  SetLength(Result, 20000);

  // generate the first part of the unit source
  Result :=
    'unit ' + UnitName + ';'#13#13 +
    'interface'#13#13 +
    'uses'#13 +
    '  SysUtils, WinTypes, WinProcs, Messages, Classes,'#13 +
    '  Forms, Graphics, Controls, Dialogs, DB, DBCtrls,'#13 +
    '  DBTables, ExtCtrls;'#13#13 +
    'type'#13 +
    '  T' + FormName + ' = class(TForm)'#13;

  // add each component of the form
  for I := 0 to AForm.ComponentCount - 1 do
    Result := Result +
      '    ' + AForm.Components[I].Name +
      ': ' + AForm.Components[I].ClassName + ';'#13;

  // generate the final part of the source code
  Result := Result +
    '  private'#13 +
    '    { Private declarations }'#13 +
    '  public'#13 +
    '    { Public declarations }'#13 +
    '  end;'#13#13 +
    'var'#13 +
    '  ' + FormName + ': T' + FormName + ';'#13#13 +
    'implementation'#13#13 +
    '{$R *.DFM}'#13#13 +
    'end.'#13;
end;

end.
unit DdhDbwF;

interface

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

type
  TFormDbWiz = class(TForm)
    Notebook1: TNotebook;
    Label1: TLabel;
    ListDatabases: TListBox;
    BitBtnNext1: TBitBtn;
    BitBtnNext2: TBitBtn;
    Label2: TLabel;
    ListTables: TListBox;
    BitBtnBack2: TBitBtn;
    ListFields: TListBox;
    Label3: TLabel;
    BitBtnNext3: TBitBtn;
    BitBtnBack3: TBitBtn;
    Label4: TLabel;
    BitBtnNext4: TBitBtn;
    BitBtnBack4: TBitBtn;
    GroupFilter: TRadioGroup;
    BitBtnAll: TBitBtn;
    BitBtnNone: TBitBtn;
    StringGrid1: TStringGrid;
    Table1: TTable;
    procedure Notebook1PageChanged(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ListDatabasesClick(Sender: TObject);
    procedure BitBtnNext1Click(Sender: TObject);
    procedure ListTablesClick(Sender: TObject);
    procedure BitBtnBack2Click(Sender: TObject);
    procedure BitBtnNext2Click(Sender: TObject);
    procedure BitBtnBack3Click(Sender: TObject);
    procedure BitBtnAllClick(Sender: TObject);
    procedure BitBtnNoneClick(Sender: TObject);
    procedure BitBtnNext3Click(Sender: TObject);
    procedure BitBtnBack4Click(Sender: TObject);
    procedure ListFieldsClick(Sender: TObject);
    procedure BitBtnNext4Click(Sender: TObject);
  private
    { Private declarations }
  public
    SourceCode, FormName, UnitName: string;
    ResultForm: TForm;
    procedure GeneratedFormClose(
      Sender: TObject; var Action: TCloseAction);
  end;

var
  FormDbWiz: TFormDbWiz;

implementation

{$R *.DFM}

uses
  DdhDynDb, ExptIntf;

////// form code //////

procedure TFormDbWiz.Notebook1PageChanged(Sender: TObject);
begin
  // copy the name of the page into the caption
  Caption := Format(
    'Ddh DB Form Wizard - Page %d/%d: ',
    [NoteBook1.PageIndex + 1,
    NoteBook1.Pages.Count,
      NoteBook1.ActivePage]);
end;

procedure TFormDbWiz.FormCreate(Sender: TObject);
begin
  // fill the first listbox with database names
  Session.GetDatabaseNames(
    ListDatabases.Items);
  // start in the first page
  Notebook1.PageIndex := 0;
  // default values (modified by the wizard)
  FormName := 'TResultForm';
  UnitName := 'ResultUnit';
end;

procedure TFormDbWiz.ListDatabasesClick(Sender: TObject);
begin
  // database selected: enable the Next button
  BitBtnNext1.Enabled := True;
end;

procedure TFormDbWiz.BitBtnNext1Click(Sender: TObject);
var
  CurrentDB, CurrentFilter: string;
begin
  // get the database and filters
  CurrentDB := ListDatabases.Items[
    ListDatabases.ItemIndex];
  CurrentFilter := GroupFilter.Items[
    GroupFilter.ItemIndex];
  // retrieve the tables
  Session.GetTableNames(CurrentDB,
    CurrentFilter, True, False, ListTables.Items);
  // move to the next page
  NoteBook1.PageIndex := 1;
  BitBtnNext2.Enabled := False;
end;

procedure TFormDbWiz.ListTablesClick(Sender: TObject);
begin
  // table selected: enable next button
  BitBtnNext2.Enabled := True;
end;

procedure TFormDbWiz.BitBtnBack2Click(Sender: TObject);
begin
  // go back to first page
  NoteBook1.PageIndex := 0;
end;

procedure TFormDbWiz.BitBtnNext2Click(Sender: TObject);
var
  I: Integer;
begin
  // set the properties of the selected table
  with Table1 do
  begin
    DatabaseName := ListDatabases.Items[
      ListDatabases.ItemIndex];
    TableName := ListTables.Items[
      ListTables.ItemIndex];
    // load the field definitions
    FieldDefs.Update;
  end;
  // clear the list box, then fill it
  ListFields.Clear;
  for I := 0 to Table1.FieldDefs.Count - 1 do
    // add number, name, and class name of each field
    ListFields.Items.Add(Format(
      '%d) %s [%s]',
      [Table1.FieldDefs[I].FieldNo,
      Table1.FieldDefs[I].Name,
        Table1.FieldDefs[I].FieldClass.ClassName]));
  // move to the next page
  NoteBook1.PageIndex := 2;
  BitBtnNext3.Enabled := False;
end;

procedure TFormDbWiz.BitBtnBack3Click(Sender: TObject);
begin
  // back to the second page
  NoteBook1.PageIndex := 1;
end;

procedure TFormDbWiz.BitBtnAllClick(Sender: TObject);
var
  I: Integer;
begin
  // select every available field
  for I := 0 to ListFields.Items.Count - 1 do
    ListFields.Selected[I] := True;
  // enable Next button
  BitBtnNext3.Enabled := True;
end;

procedure TFormDbWiz.BitBtnNoneClick(Sender: TObject);
var
  I: Integer;
begin
  // deselect all the fields
  for I := 0 to ListFields.Items.Count - 1 do
    ListFields.Selected[I] := False;
  // disable next button (no fields are selected)
  BitBtnNext3.Enabled := False;
end;

procedure TFormDbWiz.ListFieldsClick(Sender: TObject);
begin
  // enable button if there at least one field selected
  BitBtnNext3.Enabled := ListFields.SelCount > 0;
end;

procedure TFormDbWiz.BitBtnNext3Click(Sender: TObject);
var
  I, RowNum: Integer;
begin
  // reserve enough rows in the string grid
  StringGrid1.RowCount := ListFields.Items.Count;
  // empty the string grid
  for I := 0 to StringGrid1.RowCount - 1 do
  begin
    StringGrid1.Cells[0, I] := '';
    StringGrid1.Cells[1, I] := '';
  end;
  // for each field, if selected list it with the
  // corresponding data aware component
  RowNum := 0;
  for I := 0 to ListFields.Items.Count - 1 do
    if ListFields.Selected[I] then
    begin
      StringGrid1.Cells[0, RowNum] := Format('%d) %s [%s]',
        // field number, name, classname of data aware control
        [Table1.FieldDefs[I].FieldNo,
        Table1.FieldDefs[I].Name,
          ConvertClass(Table1.FieldDefs[I].FieldClass).ClassName]);
      StringGrid1.Cells[1, RowNum] := Table1.FieldDefs[I].Name;
      Inc(RowNum);
    end;
  // set the real number of rows
  StringGrid1.RowCount := RowNum;
  NoteBook1.PageIndex := 3;
end;

procedure TFormDbWiz.BitBtnBack4Click(Sender: TObject);
begin
  NoteBook1.PageIndex := 2;
end;

// generate button

procedure TFormDbWiz.BitBtnNext4Click(Sender: TObject);
var
  StrList: TStringList;
  I, RowNum: Integer;
begin
  StrList := TStringList.Create;
  Screen.Cursor := crHourGlass;
  try
    RowNum := 0;
    for I := 0 to ListFields.Items.Count - 1 do
      if ListFields.Selected[I] then
      begin
        StrList.AddObject(
          StringGrid1.Cells[1, RowNum], TObject(I));
        // move to next row in string grid
        Inc(RowNum);
      end;
    ResultForm := GenerateForm(StrList, Table1);
    if not Assigned(ToolServices) then
    begin
      // stand alone form
      ResultForm.OnClose := GeneratedFormClose;
      ResultForm.Show;
    end
    else
    begin
      // wizard
      SourceCode := GenerateSource(ResultForm,
        FormName, UnitName);
      ModalResult := mrOK;
    end;
  finally
    Screen.Cursor := crDefault;
    StrList.Free;
  end;
end;

procedure TFormDbWiz.GeneratedFormClose(
  Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

end.
Скачать весь проект





Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook