📄 rxlookup.pas
字号:
TBitmap(Image).TransparentColor)
{$IFDEF WIN32}
else if Image is TIcon then begin
Ico := CreateRealSizeIcon(TIcon(Image));
try
GetIconSize(Ico, W, H);
DrawIconEx(Canvas.Handle, (Rect.Right + Rect.Left - W) div 2,
(Rect.Top + Rect.Bottom - H) div 2, Ico, W, H, 0, 0, DI_NORMAL);
finally
DestroyIcon(Ico);
end;
end
{$ENDIF}
else Canvas.Draw(X, Y, Image);
finally
RestoreDC(Canvas.Handle, SaveIndex);
end;
end;
end;
function TRxLookupControl.GetPicture(Current, Empty: Boolean;
var TextMargin: Integer): TGraphic;
begin
TextMargin := 0;
Result := nil;
if Assigned(FOnGetImage) then FOnGetImage(Self, Empty, Result, TextMargin);
end;
procedure TRxLookupControl.WMGetDlgCode(var Message: TMessage);
begin
Message.Result := DLGC_WANTARROWS or DLGC_WANTCHARS;
end;
procedure TRxLookupControl.WMKillFocus(var Message: TMessage);
begin
FFocused := False;
Invalidate;
end;
procedure TRxLookupControl.WMSetFocus(var Message: TMessage);
begin
FFocused := True;
Invalidate;
end;
function TRxLookupControl.Locate(const SearchField: TField;
const AValue: string; Exact: Boolean): Boolean;
begin
FLocate.IndexSwitch := FIndexSwitch;
Result := False;
try
if not ValueIsEmpty(AValue) and (SearchField <> nil) then begin
Result := FLocate.Locate(SearchField.FieldName, AValue, Exact,
not IgnoreCase);
if Result then begin
if SearchField = FDisplayField then FValue := FKeyField.AsString;
UpdateDisplayValue;
end;
end;
except
end;
end;
function TRxLookupControl.EmptyRowVisible: Boolean;
begin
Result := DisplayEmpty <> EmptyStr;
end;
procedure TRxLookupControl.UpdateDisplayValue;
begin
if not ValueIsEmpty(FValue) then begin
if FDisplayField <> nil then
FDisplayValue := FDisplayField.AsString
else FDisplayValue := '';
end
else FDisplayValue := '';
end;
function TRxLookupControl.GetWindowWidth: Integer;
var
I: Integer;
begin
Result := 0;
for I := 0 to FListFields.Count - 1 do
Inc(Result, TField(FListFields[I]).DisplayWidth);
Canvas.Font := Font;
Result := Min(Result * Canvas.TextWidth('M') + FListFields.Count * 4 +
GetSystemMetrics(SM_CXVSCROLL), Screen.Width);
end;
{ TRxDBLookupList }
constructor TRxDBLookupList.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Width := 121;
Ctl3D := True;
FBorderStyle := bsSingle;
{$IFDEF WIN32}
ControlStyle := [csOpaque, csDoubleClicks];
{$ELSE}
ControlStyle := [csFramed, csOpaque, csDoubleClicks];
{$ENDIF}
RowCount := 7;
end;
procedure TRxDBLookupList.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do begin
Style := Style or WS_VSCROLL;
if FBorderStyle = bsSingle then
{$IFDEF WIN32}
if NewStyleControls and Ctl3D then ExStyle := ExStyle or WS_EX_CLIENTEDGE
else Style := Style or WS_BORDER;
{$ELSE}
Style := Style or WS_BORDER;
{$ENDIF}
end;
end;
procedure TRxDBLookupList.CreateWnd;
begin
inherited CreateWnd;
UpdateScrollBar;
end;
procedure TRxDBLookupList.Loaded;
begin
inherited Loaded;
Height := Height;
end;
function TRxDBLookupList.GetKeyIndex: Integer;
var
FieldValue: string;
begin
if not ValueIsEmpty(FValue) then
for Result := 0 to FRecordCount - 1 do begin
FLookupLink.ActiveRecord := Result;
FieldValue := FKeyField.AsString;
FLookupLink.ActiveRecord := FRecordIndex;
if FieldValue = FValue then Exit;
end;
Result := -1;
end;
procedure TRxDBLookupList.KeyDown(var Key: Word; Shift: TShiftState);
var
Delta, KeyIndex, EmptyRow: Integer;
begin
inherited KeyDown(Key, Shift);
FSelectEmpty := False;
EmptyRow := Ord(EmptyRowVisible);
if CanModify then begin
Delta := 0;
case Key of
VK_UP, VK_LEFT: Delta := -1;
VK_DOWN, VK_RIGHT: Delta := 1;
VK_PRIOR: Delta := 1 - (FRowCount - EmptyRow);
VK_NEXT: Delta := (FRowCount - EmptyRow) - 1;
VK_HOME: Delta := -Maxint;
VK_END: Delta := Maxint;
end;
if Delta <> 0 then begin
if ValueIsEmpty(Value) and (EmptyRow > 0) and (Delta < 0) then
FSelectEmpty := True;
FSearchText := '';
if Delta = -Maxint then FLookupLink.DataSet.First
else if Delta = Maxint then FLookupLink.DataSet.Last
else begin
KeyIndex := GetKeyIndex;
if KeyIndex >= 0 then begin
FLookupLink.DataSet.MoveBy(KeyIndex - FRecordIndex);
end
else begin
KeyValueChanged;
Delta := 0;
end;
FLookupLink.DataSet.MoveBy(Delta);
if FLookupLink.DataSet.BOF and (Delta < 0) and (EmptyRow > 0) then
FSelectEmpty := True;
end;
SelectCurrent;
end;
end;
end;
procedure TRxDBLookupList.KeyPress(var Key: Char);
begin
inherited KeyPress(Key);
ProcessSearchKey(Key);
end;
procedure TRxDBLookupList.KeyValueChanged;
begin
if FListActive and not FLockPosition then
if not LocateKey then FLookupLink.DataSet.First;
end;
procedure TRxDBLookupList.DisplayValueChanged;
begin
if FListActive and not FLockPosition then
if not LocateDisplay then FLookupLink.DataSet.First;
end;
procedure TRxDBLookupList.ListLinkActiveChanged;
begin
try
inherited ListLinkActiveChanged;
finally
if FListActive and not FLockPosition then begin
if Assigned(FMasterField) then UpdateKeyValue
else KeyValueChanged;
end
else ListDataChanged;
end;
end;
procedure TRxDBLookupList.ListDataChanged;
begin
if FListActive then begin
FRecordIndex := FLookupLink.ActiveRecord;
FRecordCount := FLookupLink.RecordCount;
FKeySelected := not ValueIsEmpty(FValue) or not FLookupLink.DataSet.BOF;
end
else begin
FRecordIndex := 0;
FRecordCount := 0;
FKeySelected := False;
end;
if HandleAllocated then begin
UpdateScrollBar;
Invalidate;
end;
end;
procedure TRxDBLookupList.ListLinkDataChanged;
begin
ListDataChanged;
end;
procedure TRxDBLookupList.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
if Button = mbLeft then begin
FSearchText := '';
if not FPopup then begin
if CanFocus then SetFocus;
if not FFocused then Exit;
end;
if CanModify then
if ssDouble in Shift then begin
if FRecordIndex = Y div GetTextHeight then DblClick;
end
else begin
MouseCapture := True;
FTracking := True;
SelectItemAt(X, Y);
end;
end;
inherited MouseDown(Button, Shift, X, Y);
end;
procedure TRxDBLookupList.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
if FTracking then begin
SelectItemAt(X, Y);
FMousePos := Y;
TimerScroll;
end;
inherited MouseMove(Shift, X, Y);
end;
procedure TRxDBLookupList.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
if FTracking then begin
StopTracking;
SelectItemAt(X, Y);
end;
inherited MouseUp(Button, Shift, X, Y);
end;
procedure TRxDBLookupList.DrawItemText(Canvas: TCanvas; Rect: TRect;
Selected, IsEmpty: Boolean);
var
J, W, X, ATop, TextWidth, LastFieldIndex: Integer;
S: string;
Field: TField;
R: TRect;
AAlignment: TAlignment;
begin
TextWidth := Canvas.TextWidth('M');
LastFieldIndex := FListFields.Count - 1;
R := Rect;
R.Right := R.Left;
S := '';
ATop := (R.Bottom + R.Top - Canvas.TextHeight('Xy')) div 2;
for J := 0 to LastFieldIndex do begin
Field := FListFields[J];
if FListStyle = lsFixed then begin
if J < LastFieldIndex then W := Field.DisplayWidth * TextWidth + 4
else W := ClientWidth - R.Right;
if IsEmpty then begin
if J = 0 then begin
S := DisplayEmpty;
end
else S := '';
end
else S := Field.DisplayText;
X := 2;
AAlignment := Field.Alignment;
{$IFDEF RX_D4}
if UseRightToLeftAlignment then ChangeBiDiModeAlignment(AAlignment);
{$ENDIF}
case AAlignment of
taRightJustify: X := W - Canvas.TextWidth(S) - 3;
taCenter: X := (W - Canvas.TextWidth(S)) div 2;
end;
R.Left := R.Right;
R.Right := R.Right + W;
{$IFDEF RX_D4}
if SysLocale.MiddleEast and UseRightToLeftReading then
Canvas.TextFlags := Canvas.TextFlags or ETO_RTLREADING
else
Canvas.TextFlags := Canvas.TextFlags and not ETO_RTLREADING;
{$ENDIF}
Canvas.TextRect(R, R.Left + X, ATop, S);
if J < LastFieldIndex then begin
Canvas.MoveTo(R.Right, R.Top);
Canvas.LineTo(R.Right, R.Bottom);
Inc(R.Right);
if R.Right >= ClientWidth then Break;
end;
end
else {if FListStyle = lsDelimited then} if not IsEmpty then begin
S := S + Field.DisplayText;
if J < LastFieldIndex then S := S + FFieldsDelim + ' ';
end;
end;
if (FListStyle = lsDelimited) then begin
if IsEmpty then
S := DisplayEmpty;
R.Left := Rect.Left;
R.Right := Rect.Right;
{$IFDEF RX_D4}
if SysLocale.MiddleEast and UseRightToLeftReading then
Canvas.TextFlags := Canvas.TextFlags or ETO_RTLREADING
else
Canvas.TextFlags := Canvas.TextFlags and not ETO_RTLREADING;
{$ENDIF}
Canvas.TextRect(R, R.Left + 2, ATop, S);
end;
end;
procedure TRxDBLookupList.Paint;
var
I, J, TextHeight, TextMargin: Integer;
Image: TGraphic;
Bmp: TBitmap;
R, ImageRect: TRect;
Selected: Boolean;
begin
Bmp := TBitmap.Create;
try
Canvas.Font := Font;
TextHeight := GetTextHeight;
if ColorToRGB(Color) <> ColorToRGB(clBtnFace) then
Canvas.Pen.Color := clBtnFace
else Canvas.Pen.Color := clBtnShadow;
for I := 0 to FRowCount - 1 do begin
J := I - Ord(EmptyRowVisible);
Canvas.Font.Color := Font.Color;
Canvas.Brush.Color := Color;
Selected := not FKeySelected and (I = 0) and not EmptyRowVisible;
R.Top := I * TextHeight;
R.Bottom := R.Top + TextHeight;
if I < FRecordCount + Ord(EmptyRowVisible) then begin
if (I = 0) and (J = -1) then begin
if ValueIsEmpty(FValue) then begin
Canvas.Font.Color := clHighlightText;
Canvas.Brush.Color := clHighlight;
Selected := True;
end
else Canvas.Brush.Color := EmptyItemColor;
R.Left := 0; R.Right := ClientWidth;
Image := GetPicture(False, True, TextMargin);
if TextMargin > 0 then begin
with Bmp do begin
Canvas.Font := Self.Canvas.Font;
Canvas.Brush := Self.Canvas.Brush;
Canvas.Pen := Self.Canvas.Pen;
Width := WidthOf(R);
Height := HeightOf(R);
end;
ImageRect := Bounds(0, 0, TextMargin, HeightOf(R));
Bmp.Canvas.FillRect(ImageRect);
if Image <> nil then DrawPicture(Bmp.Canvas, ImageRect, Image);
DrawItemText(Bmp.Canvas, Bounds(TextMargin, 0, WidthOf(R) - TextMargin,
HeightOf(R)), Selected, True);
Canvas.Draw(R.Left, R.Top, Bmp);
end
else DrawItemText(Canvas, R, Selected, True);
end
else begin
FLookupLink.ActiveRecord := J;
if not ValueIsEmpty(FValue) and (FKeyField.AsString = FValue) then
begin
Canvas.Font.Color := clHighlightText;
Canvas.Brush.Color := clHighlight;
Selected := True;
end;
R.Left := 0; R.Right := ClientWidth;
Image := GetPicture(False, False, TextMargin);
if TextMargin > 0 then begin
with Bmp do begin
Canvas.Font := Self.Canvas.Font;
Canvas.Brush := Self.Canvas.Brush;
Canvas.Pen := Self.Canvas.Pen;
Width := WidthOf(R);
Height := HeightOf(R);
end;
ImageRect := Bounds(0, 0, TextMargin, HeightOf(R));
Bmp.Canvas.FillRect(ImageRect);
if Image <> nil then DrawPicture(Bmp.Canvas, ImageRect, Image);
DrawItemText(Bmp.Canvas, Bounds(TextMargin, 0, WidthOf(R) - TextMargin,
HeightOf(R)), Selected, False);
Canvas.Draw(R.Left, R.Top, Bmp);
end
else DrawItemText(Canvas, R, Selected, False);
end;
end;
R.Left := 0;
R.Right := ClientWidth;
if J >= FRecordCount then Canvas.FillRect(R);
if Selected and (FFocused or FPopup) then Canvas.DrawFocusRect(R);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -