📄 toolctrlseh.pas
字号:
begin
Field^ := nil;
FDBLookupControl.SetFocus;
end;
end;
procedure TLookupCtrlDataLinkEh.LayoutChanged;
begin
if FDBLookupControl <> nil then FDBLookupControl.UpdateDataFields;
end;
procedure TLookupCtrlDataLinkEh.RecordChanged(Field: TField);
begin
if FDBLookupControl <> nil then FDBLookupControl.DataLinkRecordChanged(Field);
end;
{ TListSourceLink }
constructor TLookupCtrlListLinkEh.Create;
begin
inherited Create;
// VisualControl := True;
end;
procedure TLookupCtrlListLinkEh.ActiveChanged;
begin
if FDBLookupControl <> nil then FDBLookupControl.UpdateListFields;
end;
procedure TLookupCtrlListLinkEh.DataSetChanged;
begin
if FDBLookupControl <> nil then FDBLookupControl.ListLinkDataChanged;
end;
procedure TLookupCtrlListLinkEh.LayoutChanged;
begin
if FDBLookupControl <> nil then FDBLookupControl.UpdateListFields;
end;
{ TDBLookupControlEh }
var
SearchTickCount: Integer = 0;
constructor TDBLookupControlEh.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 := TLookupCtrlDataLinkEh.Create;
FDataLink.FDBLookupControl := Self;
FListLink := TLookupCtrlListLinkEh.Create;
FListLink.FDBLookupControl := Self;
FListFields := TList.Create;
FKeyValue := Null;
end;
destructor TDBLookupControlEh.Destroy;
begin
inherited Destroy;
FListFields.Free;
FListFields := nil;
FListLink.FDBLookupControl := nil;
FListLink.Free;
FListLink := nil;
FDataLink.FDBLookupControl := nil;
FDataLink.Free;
FDataLink := nil;
end;
function TDBLookupControlEh.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 TDBLookupControlEh.CheckNotCircular;
begin
if FListLink.Active and FListLink.DataSet.IsLinkedTo(DataSource) then
DatabaseError(SCircularDataLink);
end;
procedure TDBLookupControlEh.CheckNotLookup;
begin
if FLookupMode then DatabaseError(SPropDefByLookup);
if FDataLink.DataSourceFixed then DatabaseError(SDataSourceFixed);
end;
procedure TDBLookupControlEh.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 TDBLookupControlEh.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 TDBLookupControlEh.GetBorderSize: Integer;
var
Params: TCreateParams;
R: TRect;
begin
CreateParams(Params);
SetRect(R, 0, 0, 0, 0);
AdjustWindowRectEx(R, Params.Style, False, Params.ExStyle);
Result := R.Bottom - R.Top;
end;
function TDBLookupControlEh.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
function TDBLookupControlEh.GetKeyFieldName: string;
begin
if FLookupMode then Result := '' else Result := FKeyFieldName;
end;
function TDBLookupControlEh.GetListSource: TDataSource;
begin
if FLookupMode then Result := nil else Result := FListLink.DataSource;
end;
function TDBLookupControlEh.GetReadOnly: Boolean;
begin
Result := FDataLink.ReadOnly;
end;
function TDBLookupControlEh.GetTextHeight: Integer;
var
DC: HDC;
SaveFont: HFont;
Metrics: TTextMetric;
begin
DC := GetDC(0);
SaveFont := SelectObject(DC, Font.Handle);
GetTextMetrics(DC, Metrics);
SelectObject(DC, SaveFont);
ReleaseDC(0, DC);
Result := Metrics.tmHeight;
end;
procedure TDBLookupControlEh.KeyValueChanged;
begin
end;
procedure TDBLookupControlEh.UpdateListFields;
var
DataSet: TDataSet;
ResultField: TField;
i: Integer;
begin
FListActive := False;
//FKeyField := nil;
FListField := nil;
FListFields.Clear;
if FListLink.Active and (FKeyFieldName <> '') then
begin
CheckNotCircular;
DataSet := FListLink.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;
end;
procedure TDBLookupControlEh.ListLinkDataChanged;
begin
end;
function TDBLookupControlEh.LocateKey: Boolean;
var
KeySave: Variant;
begin
Result := False;
try
KeySave := FKeyValue;
if not VarIsNull(FKeyValue) and FListLink.DataSet.Active and
FListLink.DataSet.Locate(FKeyFieldName, FKeyValue, []) then
begin
Result := True;
FKeyValue := KeySave;
end;
except
end;
end;
procedure TDBLookupControlEh.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 (FListLink <> nil) and (AComponent = ListSource)
then ListSource := nil;
end;
end;
procedure TDBLookupControlEh.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 FListLink.DataSet.Locate(FListField.FieldName, S,
[loCaseInsensitive, loPartialKey]) then
begin
SelectKeyValue(FListLink.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 TDBLookupControlEh.SelectKeyValue(const Value: Variant);
begin
if Length(FMasterFields)> 0 then
begin
if FDataLink.Edit then
FDataLink.DataSet.FieldValues[FMasterFieldNames] := Value;
end else
SetKeyValue(Value);
Repaint;
Click;
end;
procedure TDBLookupControlEh.SetDataFieldName(const Value: string);
begin
if FDataFieldName <> Value then
begin
FDataFieldName := Value;
UpdateDataFields;
end;
end;
procedure TDBLookupControlEh.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 TDBLookupControlEh.SetKeyFieldName(const Value: string);
begin
CheckNotLookup;
if FKeyFieldName <> Value then
begin
FKeyFieldName := Value;
UpdateListFields;
end;
end;
procedure TDBLookupControlEh.SetKeyValue(const Value: Variant);
begin
if not VarEquals(FKeyValue, Value) then
begin
FKeyValue := Value;
KeyValueChanged;
end;
end;
procedure TDBLookupControlEh.SetListFieldName(const Value: string);
begin
if FListFieldName <> Value then
begin
FListFieldName := Value;
UpdateListFields;
end;
end;
procedure TDBLookupControlEh.SetListSource(Value: TDataSource);
begin
CheckNotLookup;
FListLink.DataSource := Value;
if Value <> nil then Value.FreeNotification(Self);
end;
procedure TDBLookupControlEh.SetLookupMode(Value: Boolean);
begin
if FLookupMode <> Value then
if Value then
begin
FMasterFields := GetFieldsProperty(FDataFields[0].DataSet, Self, FDataFields[0].KeyFields);
FLookupSource.DataSet := FDataFields[0].LookupDataSet;
FKeyFieldName := FDataFields[0].LookupKeyFields;
FLookupMode := True;
FListLink.DataSource := FLookupSource;
end else
begin
FListLink.DataSource := nil;
FLookupMode := False;
FKeyFieldName := '';
FLookupSource.DataSet := nil;
FMasterFields := FDataFields;
end;
end;
procedure TDBLookupControlEh.SetReadOnly(Value: Boolean);
begin
FDataLink.ReadOnly := Value;
end;
procedure TDBLookupControlEh.WMGetDlgCode(var Message: TMessage);
begin
Message.Result := DLGC_WANTARROWS or DLGC_WANTCHARS;
end;
procedure TDBLookupControlEh.WMKillFocus(var Message: TMessage);
begin
FHasFocus := False;
inherited;
Invalidate;
end;
procedure TDBLookupControlEh.WMSetFocus(var Message: TMessage);
begin
SearchText := '';
FHasFocus := True;
inherited;
Invalidate;
end;
procedure TDBLookupControlEh.CMEnabledChanged(var Message: TMessage);
begin
inherited;
Invalidate;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -