📄 jvdbcontrols.pas
字号:
inherited ReadOnly := False;
end;
procedure TJvDBMaskEdit.DoExit;
var
NewValue: string;
Accept, Post: Boolean;
begin
Accept := True;
Post := False;
NewValue := Text;
// When we hit enter, check if there was a change, and if so,
// we can fire the confirmation event.
if FOriginalValue <> NewValue then
if Assigned(FOnAcceptNewValue) then
begin
FOnAcceptNewValue(Self, FOriginalValue, NewValue, Accept, Post);
if not Accept then
Text := FOriginalValue;
end;
try
if Accept then
FDataLink.UpdateRecord;
except
SelectAll;
SetFocus;
raise;
end;
SetFocused(False);
CheckCursor;
if Accept then
inherited DoExit;
{ A nifty little way to keep simple database applications happy.
Just set POST flag in your validation, and the dataset is updated.
If you don't like this feature, just DON'T set Post to true, it
defaults to false.
}
if (Accept and Post) and (Assigned(DataSource)) then
if Assigned(DataSource.DataSet) and (DataSource.DataSet.Active) then
if DataSource.DataSet.State = dsEdit then
DataSource.DataSet.Post;
end;
procedure TJvDBMaskEdit.WMPaint(var Msg: TWMPaint);
(*const
AlignmentValues: array [Boolean, TAlignment] of TAlignment = (
(taLeftJustify, taRightJustify, taCenter),
(taRightJustify, taLeftJustify, taCenter)
); *)
const
AlignStyle: array [Boolean, TAlignment] of DWORD =
((WS_EX_LEFT, WS_EX_RIGHT, WS_EX_LEFT),
(WS_EX_RIGHT, WS_EX_LEFT, WS_EX_LEFT));
var
Left: Integer;
Margins: TPoint;
R: TRect;
DC: HDC;
PS: TPaintStruct;
S: string;
AAlignment: TAlignment;
ExStyle: DWORD;
begin
if csDestroying in ComponentState then
Exit;
AAlignment := FAlignment;
if UseRightToLeftAlignment then
ChangeBiDiModeAlignment(AAlignment);
if ((AAlignment = taLeftJustify) or FFocused) and
not (csPaintCopy in ControlState) then
begin
if SysLocale.MiddleEast and HandleAllocated and (IsRightToLeft) then
begin { This keeps the right aligned text, right aligned }
ExStyle := DWORD(GetWindowLong(Handle, GWL_EXSTYLE)) and (not WS_EX_RIGHT) and
(not WS_EX_RTLREADING) and (not WS_EX_LEFTSCROLLBAR);
if UseRightToLeftReading then
ExStyle := ExStyle or WS_EX_RTLREADING;
if UseRightToLeftScrollbar then
ExStyle := ExStyle or WS_EX_LEFTSCROLLBAR;
ExStyle := ExStyle or
AlignStyle[UseRightToLeftAlignment, AAlignment];
if DWORD(GetWindowLong(Handle, GWL_EXSTYLE)) <> ExStyle then
SetWindowLong(Handle, GWL_EXSTYLE, ExStyle);
end;
// MAIN THING FOR MOST PEOPLE IS WE JUST CALL OUR BASE CLASS METHOD HERE:
inherited; // This is where the main Non Control-Grid Paint Code lives.
Exit;
end;
{ Handler code here is for
Data Aware Controls drawing themselves into their own internal
canvas, for purpose of being displayed in a DBControl Grid:
}
DC := Msg.DC;
if DC = 0 then
DC := BeginPaint(Handle, PS);
FCanvas.Handle := DC;
try
FCanvas.Font := Font;
with FCanvas do
begin
R := ClientRect;
if not (NewStyleControls and Ctl3D) and (BorderStyle = bsSingle) then
begin
Brush.Color := clWindowFrame;
FrameRect(R);
InflateRect(R, -1, -1);
end;
Brush.Color := Color;
if not Enabled then
Font.Color := clGrayText;
if (csPaintCopy in ControlState) and (FDataLink.Field <> nil) then
begin
S := FDataLink.Field.DisplayText;
case CharCase of
ecUpperCase:
S := AnsiUpperCase(S);
ecLowerCase:
S := AnsiLowerCase(S);
end;
end
else
S := EditText;
if PasswordChar <> #0 then
FillChar(S[1], Length(S), PasswordChar);
Margins := GetTextMargins;
case AAlignment of
taLeftJustify:
Left := Margins.X;
taRightJustify:
Left := ClientWidth - TextWidth(S) - Margins.X - 1;
else
Left := (ClientWidth - TextWidth(S)) div 2;
end;
if SysLocale.MiddleEast then
UpdateTextFlags;
TextRect(R, Left, Margins.Y, S);
end;
finally
FCanvas.Handle := 0;
if Msg.DC = 0 then
EndPaint(Handle, PS);
end;
end;
procedure TJvDBMaskEdit.CMGetDataLink(var Msg: TMessage);
begin
Msg.Result := Integer(FDataLink);
end;
function TJvDBMaskEdit.GetTextMargins: TPoint;
var
DC: HDC;
SaveFont: HFont;
I: Integer;
SysMetrics, Metrics: TTextMetric;
begin
if NewStyleControls then
begin
if BorderStyle = bsNone then
I := 0
else
if Ctl3D then
I := 1
else
I := 2;
Result.X := SendMessage(Handle, EM_GETMARGINS, 0, 0) and $0000FFFF + I;
Result.Y := I;
end
else
begin
if BorderStyle = bsNone then
I := 0
else
begin
DC := GetDC(HWND_DESKTOP);
GetTextMetrics(DC, SysMetrics);
SaveFont := SelectObject(DC, Font.Handle);
GetTextMetrics(DC, Metrics);
SelectObject(DC, SaveFont);
ReleaseDC(HWND_DESKTOP, DC);
I := SysMetrics.tmHeight;
if I > Metrics.tmHeight then
I := Metrics.tmHeight;
I := I div 4;
end;
Result.X := I;
Result.Y := I;
end;
end;
function TJvDBMaskEdit.ExecuteAction(Action: TBasicAction): Boolean;
begin
Result := inherited ExecuteAction(Action) or (FDataLink <> nil) and
FDataLink.ExecuteAction(Action);
end;
function TJvDBMaskEdit.UpdateAction(Action: TBasicAction): Boolean;
begin
Result := inherited UpdateAction(Action) or (FDataLink <> nil) and
FDataLink.UpdateAction(Action);
end;
//=== { TJvDBComboEdit } =====================================================
procedure ResetMaxLength(DBEdit: TJvDBComboEdit);
var
F: TField;
begin
with DBEdit do
if (MaxLength > 0) and (DataSource <> nil) and
(DataSource.DataSet <> nil) then
begin
F := DataSource.DataSet.FindField(DataField);
if Assigned(F) and (F.DataType = ftString) and
(F.Size = MaxLength) then
MaxLength := 0;
end;
end;
constructor TJvDBComboEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle + [csReplicatable];
FCanvas := TControlCanvas.Create;
FCanvas.Control := Self;
FDataLink := TFieldDataLink.Create;
FDataLink.Control := Self;
FDataLink.OnDataChange := DataChange;
FDataLink.OnEditingChange := EditingChange;
FDataLink.OnUpdateData := UpdateData;
inherited ReadOnly := True;
AlwaysEnableButton := True;
AlwaysShowPopup := False;
end;
destructor TJvDBComboEdit.Destroy;
begin
FDataLink.Free;
FDataLink := nil;
inherited Destroy;
// (rom) destroy Canvas AFTER inherited Destroy
FCanvas.Free;
end;
procedure TJvDBComboEdit.Loaded;
begin
inherited Loaded;
ResetMaxLength(Self);
if csDesigning in ComponentState then
DataChange(Self);
end;
procedure TJvDBComboEdit.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FDataLink <> nil) and (AComponent = DataSource) then
DataSource := nil;
end;
procedure TJvDBComboEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if ((Key = VK_DELETE) and (Shift * KeyboardShiftStates = [])) or
((Key = VK_INSERT) and (Shift * KeyboardShiftStates = [ssShift])) then
FDataLink.Edit;
end;
procedure TJvDBComboEdit.KeyPress(var Key: Char);
begin
inherited KeyPress(Key);
if (Key in [#32..#255]) and (FDataLink.Field <> nil) and
not FDataLink.Field.IsValidChar(Key) then
begin
DoBeepOnError;
Key := #0;
end;
case Key of
CtrlH, CtrlV, CtrlX, #32..#255:
FDataLink.Edit;
Esc:
begin
FDataLink.Reset;
SelectAll;
Key := #0;
end;
end;
end;
function TJvDBComboEdit.EditCanModify: Boolean;
begin
Result := FDataLink.Edit;
end;
procedure TJvDBComboEdit.Reset;
begin
FDataLink.Reset;
SelectAll;
end;
procedure TJvDBComboEdit.SetFocused(Value: Boolean);
begin
if FFocused <> Value then
begin
FFocused := Value;
if (Alignment <> taLeftJustify) and not IsMasked then
Invalidate;
FDataLink.Reset;
end;
end;
procedure TJvDBComboEdit.Change;
begin
FDataLink.Modified;
inherited Change;
end;
function TJvDBComboEdit.GetCanvas: TCanvas;
begin
Result := FCanvas;
end;
function TJvDBComboEdit.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;
procedure TJvDBComboEdit.SetDataSource(Value: TDataSource);
begin
if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then
FDataLink.DataSource := Value;
if Value <> nil then
Value.FreeNotification(Self);
end;
function TJvDBComboEdit.GetDataField: string;
begin
Result := FDataLink.FieldName;
end;
procedure TJvDBComboEdit.SetDataField(const Value: string);
begin
if not (csDesigning in ComponentState) then
ResetMaxLength(Self);
FDataLink.FieldName := Value;
end;
function TJvDBComboEdit.GetReadOnly: Boolean;
begin
if FDataLink <> nil then
Result := FDataLink.ReadOnly
else
Result := True;
end;
procedure TJvDBComboEdit.SetReadOnly(Value: Boolean);
begin
if FDataLink <> nil then
FDataLink.ReadOnly := Value;
end;
function TJvDBComboEdit.GetField: TField;
begin
Result := FDataLink.Field;
end;
procedure TJvDBComboEdit.DataChange(Sender: TObject);
begin
if FDataLink.Field <> nil then
begin
if Alignment <> FDataLink.Field.Alignment then
begin
EditText := ''; {forces update}
Alignment := FDataLink.Field.Alignment;
end;
EditMask := FDataLink.Field.EditMask;
if not (csDesigning in ComponentState) then
if (FDataLink.Field.DataType = ftString) and (MaxLength = 0) then
MaxLength := FDataLink.Field.Size;
if FFocused and FDataLink.CanModify then
Text := FDataLink.Field.Text
else
begin
EditText := FDataLink.Field.DisplayText;
{if FDataLink.Editing then Modified := True;}
end;
end
else
begin
Alignment := taLeftJustify;
EditMask := '';
if csDesigning in ComponentState then
EditText := Name
else
EditText := '';
end;
end;
procedure TJvDBComboEdit.EditingChange(Sender: TObject);
begin
inherited ReadOnly := not FDataLink.Editing;
end;
procedure TJvDBComboEdit.UpdateData(Sender: TObject);
begin
ValidateEdit;
FDataLink.Field.Text := Text;
end;
procedure TJvDBComboEdit.WMPaste(var Msg: TMessage);
begin
FDataLink.Edit;
inherited;
end;
procedure TJvDBComboEdit.WMCut(var Msg: TMessage);
begin
FDataLink.Edit;
inherited;
end;
procedure TJvDBComboEdit.DoEnter;
begin
SetFocused(True);
inherited DoEnter;
if SysLocale.FarEast and FDataLink.CanModify then
inherited ReadOnly := False;
end;
procedure TJvDBComboEdit.DoExit;
begin
try
FDataLink.UpdateRecord;
except
SelectAll;
if CanFocus then
SetFocus;
raise;
end;
SetFocused(False);
CheckCursor;
inherited DoExit;
end;
procedure TJvDBComboEdit.WMPaint(var Msg: TWMPaint);
var
S: string;
begin
if csDestroying in ComponentState then
Exit;
if (csPaintCopy in ControlState) and (FDataLink.Field <> nil) then
begin
S := FDataLink.Field.DisplayText;
case CharCase of
ecUpperCase:
S := AnsiUpperCase(S);
ecLowerCase:
S := AnsiLowerCase(S);
end;
end
else
S := EditText;
if not PaintComboEdit(Self, S, Alignment, True, FCanvas, Msg) then
inherited;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -