📄 dblookupgridseh.pas
字号:
destructor TDBLookupGridColumnEh.Destroy;
begin
FSpecCell.Free;
inherited Destroy;
end;
function TDBLookupGridColumnEh.GetGrid: TDBLookupGridEh;
begin
Result := TDBLookupGridEh(inherited Grid);
end;
procedure TDBLookupGridColumnEh.SetIndex(Value: Integer);
var i: Integer;
s: String;
procedure SetSpecCell;
var ss: TStringList;
i: Integer;
begin
with Grid as TDBLookupGridEh do
begin
ss := TStringList.Create;
try
for i := 0 to Columns.Count - 1 do
ss.Add(SpecRow.CellText[i]);
ss.Move(Index,Value);
s := '';
for i := 0 to Columns.Count - 1 do
s := s + ss[i] + ';';
Delete(s, Length(s), 1);
SpecRow.CellsText := s;
finally
ss.Free;
end;
end;
end;
begin
with Grid as TDBLookupGridEh do
begin
if SeenPassthrough and DataLink.Active and (Index <> Value) then
begin
BeginUpdate;
try
if Index = ListFieldIndex then
ListFieldIndex := Value
else
begin
if ListFieldIndex > Index then
ListFieldIndex := ListFieldIndex - 1;
if ListFieldIndex >= Value then
ListFieldIndex := ListFieldIndex + 1;
end;
SetSpecCell;
IsStored := True;
try
inherited SetIndex(Value);
finally
IsStored := False;
end;
s := '';
for i := 0 to Columns.Count - 1 do
s := s + Columns[i].Field.FieldName + ';';
Delete(s, Length(s), 1);
ListField := s;
finally
EndUpdate;
end;
end else
begin
if DataLink.Active and (Index <> Value) then
SetSpecCell;
inherited SetIndex(Value);
end;
end
end;
procedure TDBLookupGridColumnEh.SetSpecCell(const Value: TGridColumnSpecCellEh);
begin
FSpecCell.Assign(Value);
end;
procedure TDBLookupGridColumnEh.SetWidth(Value: Integer);
begin
if SeenPassthrough then
begin
IsStored := True;
try
inherited SetWidth(Value);
finally
IsStored := False;
end;
end else
inherited SetWidth(Value);
end;
{ TDBLookupGridEh }
constructor TDBLookupGridEh.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// if NewStyleControls
// then ControlStyle := [csOpaque]
// else ControlStyle := [csOpaque, csFramed];
ParentColor := False;
TabStop := True;
FLookupSource := TDataSource.Create(Self);
FDataLink := TLookupGridDataLinkEh.Create;
FDataLink.FDBLookupGrid := Self;
FListFields := TList.Create;
FKeyValue := Null;
FSpecRow := TSpecRowEh.Create(Self);
FSpecRow.OnChanged := SpecRowChanged;
inherited Options := [dgColLines, dgRowSelect];
OptionsEh := OptionsEh + [dghTraceColSizing];
FOptions := [dlgColLinesEh];
HorzScrollBar.Tracking := True;
VertScrollBar.Tracking := True;
Flat := True;
//UseMultiTitle := True;
ReadOnly := True;
DrawMemoText := True;
TabStop := False;
FLGAutoFitColWidths := False;
//HorzScrollBar.Visible := True;
VTitleMargin := 5;
ReadOnly := False;
end;
destructor TDBLookupGridEh.Destroy;
begin
FSpecRow.Free;
FListFields.Free;
FListFields := nil;
FDataLink.FDBLookupGrid := nil;
FDataLink.Free;
FDataLink := nil;
inherited Destroy;
end;
function TDBLookupGridEh.CanModify: Boolean;
function MasterFieldsCanModify: Boolean;
var i:Integer;
begin
Result := True;
for i := 0 to Length(FMasterFields)-1 do
if not FMasterFields[i].CanModify then
begin
Result := False;
Exit;
end;
end;
begin
Result := FListActive and not ReadOnly and ((FDataLink.DataSource = nil) or
(Length(FMasterFields) <> 0) and MasterFieldsCanModify);
end;
procedure TDBLookupGridEh.CheckNotCircular;
begin
if ListLink.Active and ListLink.DataSet.IsLinkedTo(DataSource) then
DatabaseError(SCircularDataLink);
end;
procedure TDBLookupGridEh.CheckNotLookup;
begin
if FLookupMode then DatabaseError(SPropDefByLookup);
if FDataLink.DataSourceFixed then DatabaseError(SDataSourceFixed);
end;
procedure TDBLookupGridEh.UpdateDataFields;
function MasterFieldNames: String;
var i:Integer;
begin
Result := '';
for i := 0 to Length(FMasterFields)-1 do
if Result = '' then
Result := FMasterFields[i].FieldName else
Result := Result + ';' + FMasterFields[i].FieldName;
end;
begin
//FDataField := nil;
//FMasterField := nil;
FMasterFieldNames := '';
if FDataLink.Active and (FDataFieldName <> '') then
begin
CheckNotCircular;
FDataFields := GetFieldsProperty(FDataLink.DataSet, Self, FDataFieldName);
if (Length(FDataFields) = 1) and (FDataFields[0].FieldKind = fkLookup)
then FMasterFields := GetFieldsProperty(FDataLink.DataSet, Self, FDataFields[0].KeyFields)
else FMasterFields := FDataFields;
FMasterFieldNames := MasterFieldNames;
end;
SetLookupMode((Length(FDataFields) = 1) and (FDataFields[0].FieldKind = fkLookup));
DataLinkRecordChanged(nil);
end;
procedure TDBLookupGridEh.DataLinkRecordChanged(Field: TField);
function FieldFound(Value:TField) :Boolean;
var i:Integer;
begin
Result := False;
for i := 0 to Length(FMasterFields)-1 do
if FMasterFields[i] = Value then
begin
Result := True;
Exit;
end;
end;
begin
if (Field = nil) or FieldFound(Field) then
if Length(FMasterFields) > 0
then SetKeyValue(FDataLink.DataSet.FieldValues[FMasterFieldNames])
else SetKeyValue(Null);
end;
function TDBLookupGridEh.GetBorderSize: Integer;
//var
// Params: TCreateParams;
// R: TRect;
begin
Result := 0;
if not HandleAllocated then Exit;
Result := Height - ClientHeight;
{CreateParams(Params);
SetRect(R, 0, 0, 0, 0);
AdjustWindowRectEx(R, Params.Style, False, Params.ExStyle);
Result := R.Bottom - R.Top; // + FBorderWidth*2;
}
end;
function TDBLookupGridEh.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
function TDBLookupGridEh.GetKeyFieldName: string;
begin
if FLookupMode then Result := '' else Result := FKeyFieldName;
end;
function TDBLookupGridEh.GetListSource: TDataSource;
begin
if FLookupMode then Result := nil else Result := ListLink.DataSource;
end;
function TDBLookupGridEh.GetReadOnly: Boolean;
begin
Result := FDataLink.ReadOnly;
end;
function TDBLookupGridEh.GetDataRowHeight: Integer;
begin
Result := DefaultRowHeight;
if dgRowLines in inherited Options then Inc(Result, GridLineWidth);
end;
function TDBLookupGridEh.GetSpecRowHeight: Integer;
{var
DC: HDC;
SaveFont: HFont;
Metrics: TTextMetric;}
begin
Result := DefaultRowHeight;
if dgRowLines in inherited Options then Inc(Result, GridLineWidth);
{Result := 0;
if not Assigned(SpecRow) then Exit;
DC := GetDC(0);
SaveFont := SelectObject(DC, SpecRow.Font.Handle);
GetTextMetrics(DC, Metrics);
SelectObject(DC, SaveFont);
ReleaseDC(0, DC);
Result := Metrics.tmHeight;}
end;
procedure TDBLookupGridEh.KeyValueChanged;
begin
if not SpecRow.Visible then
SpecRow.Selected := False
else
begin
SpecRow.Selected := VarEquals(FKeyValue,SpecRow.Value);
if not FLockPosition and not SpecRow.Selected and SpecRow.ShowIfNotInKeyList then
if not LocateKey
then SpecRow.Selected := True
else ListLinkDataChanged
end;
if ListActive and not FLockPosition then
if not LocateKey and not SpecRow.Selected then
ListLink.DataSet.First
else
ListLinkDataChanged;
if FListField <> nil then
if SpecRow.Visible and SpecRow.Selected
then FSelectedItem := SpecRow.CellText[ListFieldIndex]
else FSelectedItem := FListField.DisplayText
else FSelectedItem := '';
end;
procedure TDBLookupGridEh.UpdateListFields;
var
DataSet: TDataSet;
ResultField: TField;
i: Integer;
begin
try
FListActive := False;
//FKeyField := nil;
FListField := nil;
FListFields.Clear;
if ListLink.Active and (FKeyFieldName <> '') then
begin
CheckNotCircular;
DataSet := ListLink.DataSet;
FKeyFields := GetFieldsProperty(DataSet, Self, FKeyFieldName);
try
DataSet.GetFieldList(FListFields, FListFieldName);
except
DatabaseErrorFmt(SFieldNotFound, [Self.Name, FListFieldName]);
end;
if FLookupMode then
begin
ResultField := GetFieldProperty(DataSet, Self, FDataFields[0].LookupResultField);
if FListFields.IndexOf(ResultField) < 0 then
FListFields.Insert(0, ResultField);
FListField := ResultField;
end else
begin
if FListFields.Count = 0 then
for i := 0 to Length(FKeyFields)-1 do FListFields.Add(FKeyFields[i]);
if (FListFieldIndex >= 0) and (FListFieldIndex < FListFields.Count) then
FListField := FListFields[FListFieldIndex] else
FListField := FListFields[0];
end;
FListActive := True;
end;
if FLookupMode
then FKeyFieldName := Field.LookupKeyFields
else FKeyFieldName := KeyField;
if ListLink.Active and (FKeyFieldName <> '') then
begin
DataSet := ListLink.DataSet;
FKeyFields := GetFieldsProperty(DataSet, Self, FKeyFieldName);
if FLookupMode then
begin
ResultField := GetFieldProperty(DataSet, Self, Field.LookupResultField);
FListField := ResultField;
end else
begin
if (ListFieldIndex >= 0) and (ListFieldIndex < ListFields.Count)
then FListField := ListFields[ListFieldIndex]
else FListField := ListFields[0];
end;
end;
finally
if ListActive
then KeyValueChanged
else ListLinkDataChanged;
end;
end;
procedure TDBLookupGridEh.ListLinkDataChanged;
begin
if ListActive then
begin
FRecordIndex := ListLink.ActiveRecord;
FRecordCount := ListLink.RecordCount;
FKeySelected := not VarIsNull(KeyValue) or
not ListLink.DataSet.BOF;
end else
begin
FRecordIndex := 0;
FRecordCount := 0;
FKeySelected := False;
end;
if HandleAllocated then
begin
//LayoutChanged;
UpdateScrollBar;//
UpdateActive;
Invalidate;
end;
end;
function TDBLookupGridEh.LocateKey: Boolean;
var
KeySave: Variant;
begin
Result := False;
try
KeySave := FKeyValue;
if not VarIsNull(FKeyValue) and (ListLink.DataSet <> nil) and
ListLink.DataSet.Active and
ListLink.DataSet.Locate(FKeyFieldName, FKeyValue, []) then
begin
Result := True;
FKeyValue := KeySave;
end;
except
end;
end;
procedure TDBLookupGridEh.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if Operation = opRemove then
begin
if (FDataLink <> nil) and (AComponent = DataSource)
then DataSource := nil;
// if (ListLink <> nil) and (AComponent = ListSource)
// then ListSource := nil;
end;
end;
procedure TDBLookupGridEh.ProcessSearchKey(Key: Char);
var
TickCount: Integer;
S: string;
CharMsg: TMsg;
begin
if (FListField <> nil) and (FListField.FieldKind in [fkData, fkInternalCalc]) and
(FListField.DataType in [ftString]) then
case Key of
#8, #27: SearchText := '';
#32..#255:
if CanModify then
begin
TickCount := GetTickCount;
if TickCount - SearchTickCount > 2000 then SearchText := '';
SearchTickCount := TickCount;
if SysLocale.FarEast and (Key in LeadBytes) then
if PeekMessage(CharMsg, Handle, WM_CHAR, WM_CHAR, PM_REMOVE) then
begin
if CharMsg.Message = WM_Quit then
begin
PostQuitMessage(CharMsg.wparam);
Exit;
end;
SearchText := SearchText + Key;
Key := Char(CharMsg.wParam);
end;
if Length(SearchText) < 32 then
begin
S := SearchText + Key;
try
if ListLink.DataSet.Locate(FListField.FieldName, S,
[loCaseInsensitive, loPartialKey]) then
begin
SelectKeyValue(ListLink.DataSet.FieldValues[FKeyFieldName]{FKeyField.Value});
SearchText := S;
end;
except
{ If you attempt to search for a string larger than what the field
can hold, and exception will be raised. Just trap it and
reset the SearchText back to the old value. }
SearchText := S;
end;
end;
end;
end;
end;
procedure TDBLookupGridEh.SelectKeyValue(const Value: Variant);
begin
if Length(FMasterFields)> 0 then
begin
if FDataLink.Edit then
FDataLink.DataSet.FieldValues[FMasterFieldNames] := Value;
end else
SetKeyValue(Value);
UpdateActive;
Repaint;
Click;
end;
procedure TDBLookupGridEh.SetDataFieldName(const Value: string);
begin
if FDataFieldName <> Value then
begin
FDataFieldName := Value;
UpdateDataFields;
end;
end;
procedure TDBLookupGridEh.SetDataSource(Value: TDataSource);
begin
if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then
FDataLink.DataSource := Value;
if Value <> nil then Value.FreeNotification(Self);
end;
procedure TDBLookupGridEh.SetKeyFieldName(const Value: string);
begin
CheckNotLookup;
if FKeyFieldName <> Value then
begin
FKeyFieldName := Value;
UpdateListFields;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -