📄 rxlookup.pas
字号:
finally
Bmp.Free;
end;
if FRecordCount <> 0 then FLookupLink.ActiveRecord := FRecordIndex;
end;
procedure TRxDBLookupList.SelectCurrent;
begin
FLockPosition := True;
try
if FSelectEmpty then begin
ResetField;
end
else SelectKeyValue(FKeyField.AsString);
finally
FSelectEmpty := False;
FLockPosition := False;
end;
end;
procedure TRxDBLookupList.SelectItemAt(X, Y: Integer);
var
Delta: Integer;
begin
if Y < 0 then Y := 0;
if Y >= ClientHeight then Y := ClientHeight - 1;
Delta := Y div GetTextHeight;
if (Delta = 0) and EmptyRowVisible then begin
FSelectEmpty := True;
end
else begin
Delta := Delta - FRecordIndex;
if EmptyRowVisible then Dec(Delta);
FLookupLink.DataSet.MoveBy(Delta);
end;
SelectCurrent;
end;
procedure TRxDBLookupList.SetBorderStyle(Value: TBorderStyle);
begin
if FBorderStyle <> Value then begin
FBorderStyle := Value;
RecreateWnd;
if not (csReading in ComponentState) then begin
Height := Height;
RowCount := RowCount;
end;
end;
end;
procedure TRxDBLookupList.UpdateDisplayEmpty(const Value: string);
begin
UpdateBufferCount(RowCount - Ord(Value <> EmptyStr));
end;
procedure TRxDBLookupList.UpdateBufferCount(Rows: Integer);
begin
if FLookupLink.BufferCount <> Rows then begin
FLookupLink.BufferCount := Rows;
ListLinkDataChanged;
end;
end;
procedure TRxDBLookupList.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
var
BorderSize, TextHeight, Rows: Integer;
begin
BorderSize := GetBorderSize;
TextHeight := GetTextHeight;
Rows := (AHeight - BorderSize) div TextHeight;
if Rows < 1 then Rows := 1;
FRowCount := Rows;
UpdateBufferCount(Rows - Ord(EmptyRowVisible));
if not (csReading in ComponentState) then
AHeight := Rows * TextHeight + BorderSize;
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;
procedure TRxDBLookupList.SetRowCount(Value: Integer);
begin
if Value < 1 then Value := 1;
if Value > 50 then Value := 50;
Height := Value * GetTextHeight + GetBorderSize;
end;
procedure TRxDBLookupList.StopTimer;
begin
if FTimerActive then begin
KillTimer(Handle, 1);
FTimerActive := False;
end;
end;
procedure TRxDBLookupList.StopTracking;
begin
if FTracking then begin
StopTimer;
FTracking := False;
MouseCapture := False;
end;
end;
procedure TRxDBLookupList.TimerScroll;
var
Delta, Distance, Interval: Integer;
begin
Delta := 0;
Distance := 0;
if FMousePos < 0 then begin
Delta := -1;
Distance := -FMousePos;
end;
if FMousePos >= ClientHeight then begin
Delta := 1;
Distance := FMousePos - ClientHeight + 1;
end;
if Delta = 0 then StopTimer
else begin
FLookupLink.DataSet.MoveBy(Delta);
SelectCurrent;
Interval := 200 - Distance * 15;
if Interval < 0 then Interval := 0;
SetTimer(Handle, 1, Interval, nil);
FTimerActive := True;
end;
end;
procedure TRxDBLookupList.UpdateScrollBar;
(*
{$IFDEF RX_D3}
var
SIOld, SINew: TScrollInfo;
begin
if FLookuplink.Active and HandleAllocated then begin
with FLookuplink.DataSet do begin
SIOld.cbSize := sizeof(SIOld);
SIOld.fMask := SIF_ALL;
GetScrollInfo(Self.Handle, SB_VERT, SIOld);
SINew := SIOld;
if IsSequenced then begin
SINew.nMin := 1;
SINew.nPage := Self.FRowCount - Ord(EmptyRowVisible);
SINew.nMax := RecordCount + SINew.nPage - 1;
if State in [dsInactive, dsBrowse, dsEdit] then
SINew.nPos := RecNo;
end
else begin
SINew.nMin := 0;
SINew.nPage := 0;
if Self.FRecordCount = (FRowCount - Ord(EmptyRowVisible)) then begin
SINew.nMax := 4;
if BOF then SINew.nPos := 0
else if EOF then SINew.nPos := 4
else SINew.nPos := 2;
end
else begin
SINew.nMax := 0;
SINew.nPos := 0;
end;
end;
if (SINew.nMin <> SIOld.nMin) or (SINew.nMax <> SIOld.nMax) or
(SINew.nPage <> SIOld.nPage) or (SINew.nPos <> SIOld.nPos) then
SetScrollInfo(Self.Handle, SB_VERT, SINew, True);
end;
end
else begin
SetScrollRange(Handle, SB_VERT, 0, 0, False);
SetScrollPos(Handle, SB_VERT, 0, True);
end;
end;
{$ELSE}
*)
var
Pos, Max: Integer;
CurPos, MaxPos: Integer;
begin
if FLookupLink.Active then begin
Pos := 0;
Max := 0;
if FRecordCount = (FRowCount - Ord(EmptyRowVisible)) then begin
Max := 4;
if not FLookupLink.DataSet.BOF then
if not FLookupLink.DataSet.EOF then Pos := 2 else Pos := 4;
end;
GetScrollRange(Handle, SB_VERT, CurPos, MaxPos);
if MaxPos = 0 then MaxPos := FRecordCount;
CurPos := GetScrollPos(Handle, SB_VERT);
if Max <> MaxPos then SetScrollRange(Handle, SB_VERT, 0, Max, False);
if CurPos <> Pos then SetScrollPos(Handle, SB_VERT, Pos, True);
end
else begin
SetScrollRange(Handle, SB_VERT, 0, 0, False);
SetScrollPos(Handle, SB_VERT, 0, True);
end;
end;
procedure TRxDBLookupList.CMCtl3DChanged(var Message: TMessage);
begin
{$IFDEF WIN32}
if NewStyleControls and (FBorderStyle = bsSingle) then begin
RecreateWnd;
if not (csReading in ComponentState) then RowCount := RowCount;
end;
inherited;
{$ELSE}
inherited;
Invalidate;
if not (csReading in ComponentState) then RowCount := RowCount;
{$ENDIF}
end;
procedure TRxDBLookupList.CMFontChanged(var Message: TMessage);
begin
inherited;
if not (csReading in ComponentState) then Height := Height;
end;
procedure TRxDBLookupList.WMCancelMode(var Message: TMessage);
begin
StopTracking;
inherited;
end;
procedure TRxDBLookupList.WMTimer(var Message: TMessage);
begin
TimerScroll;
end;
procedure TRxDBLookupList.WMNCHitTest(var Msg: TWMNCHitTest);
begin
if csDesigning in ComponentState then begin
if FLookupLink.Active then DefaultHandler(Msg)
else inherited;
end
else inherited;
end;
{$IFDEF RX_D4}
function TRxDBLookupList.DoMouseWheelDown(Shift: TShiftState;
MousePos: TPoint): Boolean;
begin
Result := inherited DoMouseWheelDown(Shift, MousePos);
if not Result then begin
with FLookupLink.DataSet do
Result := MoveBy(FRecordCount - FRecordIndex) <> 0;
end;
end;
function TRxDBLookupList.DoMouseWheelUp(Shift: TShiftState;
MousePos: TPoint): Boolean;
begin
Result := inherited DoMouseWheelUp(Shift, MousePos);
if not Result then begin
with FLookupLink.DataSet do
Result := MoveBy(-FRecordIndex - 1) <> 0;
end;
end;
{$ENDIF RX_D4}
procedure TRxDBLookupList.WMVScroll(var Message: TWMVScroll);
begin
FSearchText := '';
with Message, FLookupLink.DataSet do
case ScrollCode of
SB_LINEUP: MoveBy(-FRecordIndex - 1);
SB_LINEDOWN: MoveBy(FRecordCount - FRecordIndex);
SB_PAGEUP: MoveBy(-FRecordIndex - FRecordCount + 1);
SB_PAGEDOWN: MoveBy(FRecordCount - FRecordIndex + FRecordCount - 2);
SB_THUMBPOSITION:
begin
case Pos of
0: First;
1: MoveBy(-FRecordIndex - FRecordCount + 1);
2: Exit;
3: MoveBy(FRecordCount - FRecordIndex + FRecordCount - 2);
4: Last;
end;
end;
SB_BOTTOM: Last;
SB_TOP: First;
end;
end;
{ TRxPopupDataList }
constructor TRxPopupDataList.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if AOwner is TRxLookupControl then FCombo := TRxLookupControl(AOwner);
{$IFDEF WIN32}
ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable];
{$ELSE}
ControlStyle := [csOpaque];
{$ENDIF}
FPopup := True;
TabStop := False;
ParentCtl3D := False;
Ctl3D := False;
end;
procedure TRxPopupDataList.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do begin
Style := WS_POPUP or WS_BORDER;
{$IFDEF WIN32}
ExStyle := WS_EX_TOOLWINDOW;
{$ENDIF}
{$IFDEF RX_D4}
AddBiDiModeExStyle(ExStyle);
{$ENDIF}
WindowClass.Style := CS_SAVEBITS;
end;
end;
{$IFNDEF WIN32}
procedure TRxPopupDataList.CreateWnd;
begin
inherited CreateWnd;
if (csDesigning in ComponentState) then SetParent(nil);
end;
{$ENDIF}
procedure TRxPopupDataList.WMMouseActivate(var Message: TMessage);
begin
Message.Result := MA_NOACTIVATE;
end;
procedure TRxPopupDataList.Click;
begin
inherited Click;
if Assigned(FCombo) and TRxDBLookupCombo(FCombo).FListVisible then
TRxDBLookupCombo(FCombo).InvalidateText;
end;
procedure TRxPopupDataList.KeyPress(var Key: Char);
begin
inherited KeyPress(Key);
if Assigned(FCombo) and TRxDBLookupCombo(FCombo).FListVisible then
TRxDBLookupCombo(FCombo).InvalidateText;
end;
{ TRxDBLookupCombo }
constructor TRxDBLookupCombo.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{$IFDEF WIN32}
ControlStyle := ControlStyle + [csReplicatable] - [csSetCaption];
{$ELSE}
ControlStyle := [csFramed, csOpaque];
{$ENDIF}
Width := 145;
Height := 0;
FDataList := TRxPopupDataList.Create(Self);
FDataList.Visible := False;
FDataList.Parent := Self;
FDataList.OnMouseUp := ListMouseUp;
FButtonWidth := GetSystemMetrics(SM_CXVSCROLL);
FDropDownCount := 8;
FDisplayValues := TStringList.Create;
FSelImage := TPicture.Create;
{$IFNDEF WIN32}
FBtnGlyph := TBitmap.Create;
{ Load ComboBox button glyph }
FBtnGlyph.Handle := LoadBitmap(0, PChar(32738));
FBtnDisabled := CreateDisabledBitmap(FBtnGlyph, clBlack);
{$ENDIF}
Height := {GetMinHeight}21;
FIgnoreCase := True;
FEscapeClear := True;
end;
destructor TRxDBLookupCombo.Destroy;
begin
{$IFNDEF WIN32}
FBtnDisabled.Free;
FBtnGlyph.Free;
{$ENDIF}
FSelImage.Free;
FSelImage := nil;
FDisplayValues.Free;
FDisplayValues := nil;
inherited Destroy;
end;
procedure TRxDBLookupCombo.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
{$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;
procedure TRxDBLookupCombo.CloseUp(Accept: Boolean);
var
ListValue: string;
begin
if FListVisible then begin
if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
ListValue := FDataList.Value;
SetWindowPos(FDataList.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
FListVisible := False;
FDataList.LookupSource := nil;
Invalidate;
FSearchText := '';
FDataList.FSearchText := '';
if Accept and CanModify and (Value <> ListValue) then
SelectKeyValue(ListValue);
if CanFocus then SetFocus;
if Assigned(FOnCloseUp) then FOnCloseUp(Self);
end;
end;
procedure TRxDBLookupCombo.DropDown;
var
P: TPoint;
I, Y: Integer;
S: string;
begin
if not FListVisible and {FListActive} CanModify then begin
if Assigned(FOnDropDown) then FOnDropDown(Self);
FDataList.Color := Color;
FDataList.Font := Font;
FDataList.ItemHeight := ItemHeight;
FDataList.ReadOnly := not CanModify;
FDataList.EmptyValue := EmptyValue;
FDataList.DisplayEmpty := DisplayEmpty;
FDataList.EmptyItemColor := EmptyItemColor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -