unit MasterDetailForm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  BaseForm, AnyPrint, AnyGrids, ComCtrls, Buttons, ExtCtrls, DBCtrls, Db,
  ADODB,Any_Hint;


type
  TfrmMasterDetail = class(TfrmBase)
    DataSource1: TDataSource;
    ADOQuery1: TADOQuery;
    DBNavigator1: TDBNavigator;
    DataSource2: TDataSource;
    ADOQuery2: TADOQuery;
    ADOTable1: TADOTable;
    ADOConnection1: TADOConnection;
    ADOQuery2StudentID: TIntegerField;
    ADOQuery2CourseID: TIntegerField;
    ADOQuery2CourseName: TStringField;
    ADOQuery2Hour: TIntegerField;
    ADOQuery2Teacher: TStringField;
    ADOQuery2Discription: TStringField;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure ADOQuery2CalcFields(DataSet: TDataSet);
    procedure AnyGridSetText(Sender: TObject; Row, Col: Integer;
      var Text: WideString);
    procedure ADOQuery2NewRecord(DataSet: TDataSet);
    procedure ADOQuery1AfterScroll(DataSet: TDataSet);
    procedure ADOQuery1AfterPost(DataSet: TDataSet);
    procedure AnyGridGetText(Sender: TObject; Row, Col: Integer;
      var Text: WideString);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ADOQuery2BeforeInsert(DataSet: TDataSet);
    procedure FormShow(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private

  public
    { Public declarations }
  end;

var
  frmMasterDetail: TfrmMasterDetail;

implementation

{$R *.DFM}

procedure TfrmMasterDetail.FormCreate(Sender: TObject);
var
  i:integer;
begin
  inherited;
  ADOConnection1.Connected:=False;
  ADOConnection1.ConnectionString:=Format('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%sdb.mdb;Persist Security Info=False',[ExtractFilePath(Application.ExeName)]);
  ADOConnection1.Connected:=True;
  ADOTable1.Open;
  ADOQuery1.Open;
  ADOQuery2.Open;
  AnyGrid.Columns(0).CellType:=ctCombo;
  for i:=0 to AnyGrid.TitleRows-1 do
    AnyGrid.Cells(i,0).CellType:=ctEdit;
  while not ADOTable1.Eof do
  begin
    AnyGrid.Columns(0).Items.Add(ADOTable1.FieldByName('CourseName').AsString);
    ADOTable1.Next;
  end;
end;

procedure TfrmMasterDetail.ADOQuery2CalcFields(DataSet: TDataSet);
begin
  if DataSet.FieldByName('CourseID').AsString='' then
  begin
    DataSet.FieldByName('Hour').AsString:='';
    DataSet.FieldByName('Teacher').AsString:='';
    DataSet.FieldByName('Discription').AsString:='';
  end
  else if ADOTable1.Locate('IDCourse',DataSet.FieldByName('CourseID').AsString,[]) then
  begin
    DataSet.FieldByName('Hour').AsString:=ADOTable1.FieldByName('Hour').AsString;
    DataSet.FieldByName('Teacher').AsString:=ADOTable1.FieldByName('Teacher').AsString;
    DataSet.FieldByName('Discription').AsString:=ADOTable1.FieldByName('Discription').AsString;
  end;
end;

procedure TfrmMasterDetail.AnyGridSetText(Sender: TObject; Row,
  Col: Integer; var Text: WideString);
var
  CellName:string;
begin
  if (Row>=AnyGrid.TitleRows) and (Col=0) then //更新了"选修课程"
  begin
    if (ADOQuery2.FieldByName('CourseID').AsString<>'')
      and ADOTable1.Locate('IDCourse',ADOQuery2.FieldByName('CourseID').AsString,[])
      and (ADOQuery2.State in [dsEdit,dsInsert]) then
    begin
      ADOQuery2.FieldByName('Hour').AsString:=ADOTable1.FieldByName('Hour').AsString;
      ADOQuery2.FieldByName('Teacher').AsString:=ADOTable1.FieldByName('Teacher').AsString;
      ADOQuery2.FieldByName('Discription').AsString:=ADOTable1.FieldByName('Discription').AsString;
      AnyGrid.Invalidate;
    end;
  end
  else
  begin
    if AnyGrid.PeekCell(Row,Col) then
    begin
      CellName:=AnyGrid.Cells(Row,Col).Name;
    end
    else
      CellName:='';
    if SameText(CellName,'Gender') or SameText(CellName,'Department') then
      Text:=IntToStr(AnyGrid.Cells(Row,Col).Items.IndexOf(Text));
  end;
end;

procedure TfrmMasterDetail.ADOQuery2NewRecord(DataSet: TDataSet);
begin
  DataSet.FieldByName('StudentID').AsInteger:=ADOQuery1.FieldByName('IDStudent').AsInteger
end;

procedure TfrmMasterDetail.ADOQuery1AfterScroll(DataSet: TDataSet);
begin
  ADOQuery2.Close;
  ADOQuery2.SQL.Text:=Format('select * from Course  where (StudentID=%d)',
      [ADOQuery1.FieldByName('IDStudent').AsInteger]);
  ADOQuery2.Open;
end;

procedure TfrmMasterDetail.ADOQuery1AfterPost(DataSet: TDataSet);
begin
  if not (ADOQuery2.State in [dsEdit, dsInsert]) and (ADOQuery2.RecordCount=0) then
    ADOQuery2.Insert;
end;

procedure TfrmMasterDetail.AnyGridGetText(Sender: TObject; Row,
  Col: Integer; var Text: WideString);
var
  CellName:string;
begin                                      
  if AnyGrid.PeekCell(Row,Col) then
  begin
    CellName:=AnyGrid.Cells(Row,Col).Name;
  end
  else
    CellName:='';
  if SameText(CellName,'Gender') or SameText(CellName,'Department') then
    Text:=AnyGrid.Cells(Row,Col).Items[StrToIntDef(Text,0)];
end;

procedure TfrmMasterDetail.FormClose(Sender: TObject;
  var Action: TCloseAction);
var
  MasterModified:Boolean;
  DetailMidified:Boolean;
begin
  MasterModified:=ADOQuery1.Modified and (ADOQuery1.State in [ dsEdit, dsInsert]);
  DetailMidified:=ADOQuery2.Modified and (ADOQuery2.State in [ dsEdit, dsInsert]);
  if MasterModified or DetailMidified then
    case Application.MessageBox('是否要保存所做的修改？','提示',MB_ICONINFORMATION+MB_YESNOCANCEL) of
      IDYES:
      begin
        if MasterModified then ADOQuery1.Post;
        if DetailMidified then ADOQuery2.Post;
      end;
      IDCANCEL:begin
        Action:=caNone;
        Exit;
      end;
    end;
  inherited;
end;

procedure TfrmMasterDetail.ADOQuery2BeforeInsert(DataSet: TDataSet);
begin
  if ADOQuery1.State = dsInsert then
  begin
    Application.MessageBox('请先保存学生信息的录入。','提示',MB_ICONINFORMATION+MB_OK);
    ADOQuery2.Cancel;
    Abort;
  end;
end;

procedure TfrmMasterDetail.FormShow(Sender: TObject);
begin
  inherited;
  Timer1.Enabled:=True;
end;

procedure TfrmMasterDetail.Timer1Timer(Sender: TObject);
var
  P:TPoint;
  R:TRect;
begin
  Timer1.Enabled:=False;
  with TCariHint.Create(Self) do
  begin
    Direction:=hdDownRight;
    if AnyGrid.PeekCell(AnyGrid.TitleRows,1) then
      R:=AnyGrid.Cells(AnyGrid.TitleRows,1).Rect
    else
      R:=AnyGrid.CellRect(AnyGrid.TitleRows,1);
    P.x:=R.Left+(R.Right-R.Left) div 2;
    P.y:=R.Top;
    P:=AnyGrid.ClientToScreen(P);
    ActivateHintPos('在此处：'#13#10'1. Insert 按键可插入一行明细数据。'#13#10'2. Ctrl + Delete 按键可删除一行明细数据。',P,7000);
  end;
end;

end.
